From 4379358a4194e97c6016af81814a9fda7a3a78d3 Mon Sep 17 00:00:00 2001 From: R524809 Date: Mon, 25 May 2026 14:18:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B1=89=E5=AD=97=E9=A1=B5=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E5=92=8C=E9=80=89=E6=8B=A9=E4=BD=93=E9=AA=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handwritingSheet/handwritingSheet.ts | 130 +++++------------- .../handwritingSheet/handwritingSheet.wxml | 2 +- .../components3.0/word-picker/word-picker.ts | 14 ++ 3 files changed, 48 insertions(+), 98 deletions(-) diff --git a/miniprogram/chinesePages/handwritingSheet/handwritingSheet.ts b/miniprogram/chinesePages/handwritingSheet/handwritingSheet.ts index 6d8ca8d..1d6d814 100644 --- a/miniprogram/chinesePages/handwritingSheet/handwritingSheet.ts +++ b/miniprogram/chinesePages/handwritingSheet/handwritingSheet.ts @@ -70,9 +70,8 @@ createPage( currentMode: HANDWRITING_SHEET_WORKSHEET_ID as HandwritingSheetMode, modeOptions: HANDWRITING_SHEET_MODE_OPTIONS, hasContent: false, + /** 练习字表(唯一数据源);inputValue 与弹窗均为其编辑入口 */ words: [] as string[], - inputWords: [] as string[], - selectedWords: [] as string[], inputValue: '', showSelectWordPopup: false, pickerCurrentTab: 0, @@ -256,34 +255,35 @@ createPage( : CUSTOM_MAX_WORDS; }, + /** 以 words 为准,同步输入框镜像并刷新预览 */ + applyWords(nextWords: string[], options?: { closePicker?: boolean }) { + const inputValue = nextWords.join(''); + const patch: Record = { + words: nextWords, + inputValue, + }; + if (options?.closePicker) { + patch.showSelectWordPopup = false; + } + + this.setData(patch, () => + this.renderPracticeContent().catch(console.error), + ); + }, + syncWordsFromInput(value: string, showLimitToast: boolean) { const max = this.getMaxWordsForMode(); - const selectedWords = this.data.selectedWords as string[]; - const maxInputCount = Math.max(0, max - selectedWords.length); - const nextInputWords = this.splitToSingleChars(value).slice( - 0, - maxInputCount, - ); - const nextWords = [...nextInputWords, ...selectedWords]; + const parsed = this.splitToSingleChars(value); + const nextWords = parsed.slice(0, max); - if ( - showLimitToast && - nextInputWords.length < this.splitToSingleChars(value).length - ) { + if (showLimitToast && parsed.length > max) { wx.showToast({ - title: `最多输入 ${maxInputCount} 个字`, + title: `最多输入 ${max} 个字`, icon: 'none', }); } - this.setData( - { - inputValue: nextInputWords.join(''), - inputWords: nextInputWords, - words: nextWords, - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords(nextWords); }, openSelectWordPopup() { @@ -304,10 +304,9 @@ createPage( onChangeWord(e: WechatMiniprogram.CustomEvent) { const max = this.getMaxWordsForMode(); - const nextSelectedWords = e.detail.selectedWords as string[]; - const inputWords = this.data.inputWords as string[]; + const nextWords = e.detail.selectedWords as string[]; - if (inputWords.length + nextSelectedWords.length > max) { + if (nextWords.length > max) { wx.showToast({ title: `最多只能添加 ${max} 个字`, icon: 'none', @@ -315,61 +314,22 @@ createPage( return; } - this.setData( - { - selectedWords: nextSelectedWords, - words: [...inputWords, ...nextSelectedWords], - showSelectWordPopup: false, - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords(nextWords, { closePicker: true }); }, deleteWordChip(e: WechatMiniprogram.TouchEvent) { const index = Number(e.currentTarget.dataset.index); if (Number.isNaN(index)) return; - const inputWords = [...(this.data.inputWords as string[])]; - const selectedWords = [...(this.data.selectedWords as string[])]; + const words = [...(this.data.words as string[])]; + if (index < 0 || index >= words.length) return; - if (index < inputWords.length) { - inputWords.splice(index, 1); - this.setData( - { - inputWords, - inputValue: inputWords.join(''), - words: [...inputWords, ...selectedWords], - }, - () => this.renderPracticeContent().catch(console.error), - ); - return; - } - - const selectedIndex = index - inputWords.length; - if (selectedIndex < 0 || selectedIndex >= selectedWords.length) - return; - - selectedWords.splice(selectedIndex, 1); - this.setData( - { - selectedWords, - words: [...inputWords, ...selectedWords], - }, - () => this.renderPracticeContent().catch(console.error), - ); + words.splice(index, 1); + this.applyWords(words); }, clearWords() { - this.setData( - { - words: [], - inputWords: [], - selectedWords: [], - inputValue: '', - showSelectWordPopup: false, - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords([], { closePicker: true }); }, initDefaultWords() { @@ -383,15 +343,7 @@ createPage( return; } - this.setData( - { - words: defaults, - inputWords: defaults, - selectedWords: [], - inputValue: defaults.join(''), - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords(defaults); return; } @@ -404,15 +356,7 @@ createPage( return; } - this.setData( - { - words: defaults, - inputWords: defaults, - selectedWords: [], - inputValue: defaults.join(''), - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords(defaults); }, refreshWords() { @@ -439,15 +383,7 @@ createPage( return; } - this.setData( - { - words: supported, - inputWords: supported, - selectedWords: [], - inputValue: supported.join(''), - }, - () => this.renderPracticeContent().catch(console.error), - ); + this.applyWords(supported); }, splitToSingleChars(text: string): string[] { diff --git a/miniprogram/chinesePages/handwritingSheet/handwritingSheet.wxml b/miniprogram/chinesePages/handwritingSheet/handwritingSheet.wxml index 5a5fd76..383c41b 100644 --- a/miniprogram/chinesePages/handwritingSheet/handwritingSheet.wxml +++ b/miniprogram/chinesePages/handwritingSheet/handwritingSheet.wxml @@ -148,7 +148,7 @@ 0) return; + } const selectedWords = newVal.map((item) => item.word); this.setData({ selectedWords }); }, + /** 仅在弹窗打开时从父组件同步一次,避免监听 selectedWords 与 setData 形成死循环 */ + show(show: boolean) { + if (!show) return; + const incoming = this.properties.selectedWords as string[]; + this.setData({ + selectedWords: Array.isArray(incoming) ? [...incoming] : [], + }); + }, }, /** * 组件的方法列表