/** 成员数据项 */ interface SelectMemberItem { /** 唯一标识 */ id: string /** 姓名 */ name: string /** 性别 */ gender: '男' | '女' /** 年龄 */ age: number /** 身高(cm) */ height: number /** 头像 URL,无则显示彩色占位圆 */ avatar?: string /** 是否已选中 */ selected?: boolean } /** * 选择已有成员抽屉组件 * Properties: show(控制显示), members(成员列表) * Events: close(关闭), select(选中成员,携带 SelectMemberItem) */ Component({ properties: { /** 是否显示抽屉 */ show: { type: Boolean, value: false }, /** 成员列表 */ members: { type: Array, value: [] as SelectMemberItem[] } }, data: { /** 控制 wx:if,DOM 是否存在 */ innerShow: false, /** 控制 --visible 类,触发 CSS transition */ animVisible: false }, observers: { /** * 监听外部 show 变化,错开两帧: * 打开:先插入 DOM,下一帧加动画类 * 关闭:先移除动画类,等 transition 结束再移除 DOM */ show(val: boolean) { if (val) { this.setData({ innerShow: true }) // 延迟一帧,让 DOM 先以初始状态渲染,再触发 transition setTimeout(() => { this.setData({ animVisible: true }) }, 20) } else { this.setData({ animVisible: false }) // 等 CSS transition 结束(0.3s)再移除 DOM setTimeout(() => { this.setData({ innerShow: false }) }, 300) } } }, methods: { /** 点击遮罩关闭 */ onTapMask() { this.triggerEvent('close') }, /** 点击关闭按钮 */ onTapClose() { this.triggerEvent('close') }, /** * 点击成员行,触发 select 事件 * @param e 携带 data-member 的点击事件 */ onTapMember(e: WechatMiniprogram.TouchEvent) { const member = e.currentTarget.dataset.member as SelectMemberItem this.triggerEvent('select', member) } } })