Files
2026-05-25 14:18:28 +08:00

120 lines
3.5 KiB
TypeScript

import { WORDS } from '../../core/data/words';
Component({
options: {},
/**
* 组件的属性列表
*/
properties: {
show: {
type: Boolean,
value: false,
},
cardList: {
type: Array,
value: [],
},
currentTab: {
type: Number,
value: 0,
},
selectedWords: {
type: Array,
value: [],
},
max: {
type: Number,
value: 6,
},
},
/**
* 组件的初始数据
*/
data: {
wordList: WORDS,
},
lifetimes: {
ready() {
// 初始化同步一次 selectedWords,避免首次传入时未触发 observers 的情况
const list = (this.data as any).cardList || [];
if (Array.isArray(list) && list.length > 0) {
const selectedWords = list.map((item: any) => item.word);
this.setData({ selectedWords });
}
},
},
observers: {
cardList(newVal: CardList) {
if (!Array.isArray(newVal)) return;
// 练字贴等页面只传 selectedWords、cardList 恒为 [],勿用空列表覆盖已选字
if (newVal.length === 0) {
const fromProp = this.properties.selectedWords as string[];
if (Array.isArray(fromProp) && fromProp.length > 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] : [],
});
},
},
/**
* 组件的方法列表
*/
methods: {
onClose() {
this.triggerEvent('onClose');
},
onClear() {
this.setData({
selectedWords: [],
});
},
onChange() {
this.triggerEvent('onChange', {
selectedWords: this.data.selectedWords,
});
},
onTabChange(e: WechatMiniprogram.CustomEvent) {
const index =
typeof e.detail === 'object' ? e.detail.index : e.detail;
this.setData({ currentTab: index });
},
onWordClick(e: WechatMiniprogram.TouchEvent) {
const { word } = e.currentTarget.dataset;
const { selectedWords, max } = this.data;
let newSelectedWords = selectedWords as string[];
// 如果是已选中的文字,直接取消选中
if (newSelectedWords.includes(word)) {
newSelectedWords = newSelectedWords.filter(
(item) => item !== word,
);
} else {
// 如果是未选中的文字,先判断是否已选满6个
if (newSelectedWords.length >= max) {
wx.showToast({
title: `最多选择 ${max} 个字`,
icon: 'none',
});
return;
}
newSelectedWords = [...newSelectedWords, word];
}
this.setData({
selectedWords: newSelectedWords,
});
},
},
});