Files
steel_prices_service/Sale/PICKER_FIX.md
2026-01-06 18:00:43 +08:00

6.6 KiB

TDesign Picker 修复完成

📅 修复时间

2026-01-06

问题原因

之前使用了错误的 TDesign Picker 用法:

  1. 选项数据使用字符串数组: ['昆明', '玉溪', ...]
  2. 使用 bind:confirmbind:cancel 事件
  3. 没有使用 <t-picker-item> 子组件

正确用法

根据 TDesign 官方文档,Picker 的正确使用方式:

1. 数据格式

选项必须是对象数组:

regions: [
  { label: '昆明', value: '昆明' },
  { label: '玉溪', value: '玉溪' },
  { label: '楚雄', value: '楚雄' }
]

2. 组件结构

使用 <t-picker-item> 子组件:

<t-picker
  visible="{{regionPickerVisible}}"
  value="{{regionPickerValue}}"
  data-key="region"
  title="选择地区"
  cancelBtn="取消"
  confirmBtn="确认"
  usingCustomNavbar
  bindchange="onPickerChange"
  bindcancel="onPickerCancel">
  <t-picker-item options="{{regions}}"></t-picker-item>
</t-picker>

3. 事件处理

使用 bindchange 而非 bind:confirm:

onPickerChange(e) {
  const { key } = e.currentTarget.dataset
  const { value } = e.detail

  // value 是数组,取第一个元素的值
  const selectedValue = value[0]

  if (key === 'region') {
    const region = this.data.regions.find(item => item.value === selectedValue)
    this.setData({
      regionPickerVisible: false,
      regionPickerValue: value,
      selectedRegion: selectedValue,
      regionText: region ? region.label : '请选择地区'
    })
  }
}

🔧 修复内容

1. 数据结构更新 (pages/index/index.js)

修改前:

data: {
  regions: ['昆明', '玉溪', '楚雄', ...],
  selectedRegionIndex: -1,
  regionText: '请选择地区'
}

修改后:

data: {
  regions: [
    { label: '昆明', value: '昆明' },
    { label: '玉溪', value: '玉溪' },
    { label: '楚雄', value: '楚雄' }
  ],
  selectedRegion: '',
  regionText: '请选择地区',
  regionPickerValue: []
}

2. WXML 组件更新 (pages/index/index.wxml)

修改前:

<t-cell
  title="地区"
  note="{{selectedRegionIndex === -1 ? '请选择地区' : regions[selectedRegionIndex]}}"
  bindtap="showRegionPicker" />

修改后:

<t-cell
  title="地区"
  note="{{regionText}}"
  arrow
  hover
  bindtap="showRegionPicker"
  required />

3. Picker 组件更新 (pages/index/index.wxml)

修改前:

<t-picker
  visible="{{regionPickerVisible}}"
  value="{{selectedRegionIndex}}"
  range="{{regions}}"
  bind:confirm="onPickerConfirm"
  bind:cancel="onPickerCancel" />

修改后:

<t-picker
  visible="{{regionPickerVisible}}"
  value="{{regionPickerValue}}"
  data-key="region"
  title="选择地区"
  cancelBtn="取消"
  confirmBtn="确认"
  usingCustomNavbar
  bindchange="onPickerChange"
  bindcancel="onPickerCancel">
  <t-picker-item options="{{regions}}"></t-picker-item>
</t-picker>

4. 事件处理更新 (pages/index/index.js)

修改前:

onPickerConfirm(e) {
  const { value } = e.detail
  const key = e.currentTarget.dataset.key
  const selectedIndex = value[0]

  this.setData({
    [key]: selectedIndex
  })
}

修改后:

onPickerChange(e) {
  const { key } = e.currentTarget.dataset
  const { value } = e.detail

  if (key === 'region') {
    const region = this.data.regions.find(item => item.value === value[0])
    this.setData({
      regionPickerVisible: false,
      regionPickerValue: value,
      selectedRegion: value[0] || '',
      regionText: region ? region.label : '请选择地区'
    })
  }
}

5. 组件注册更新 (app.json)

添加 t-picker-item 组件:

"usingComponents": {
  "t-picker": "tdesign-miniprogram/picker/picker",
  "t-picker-item": "tdesign-miniprogram/picker-item/picker-item",
  ...
}

📊 数据流对比

旧方案 (错误)

用户点击 → 打开 Picker → 选择索引 → 存储索引 → 通过索引获取值

问题:

  • 需要维护索引值
  • 需要通过索引查找数组
  • 不符合 TDesign 设计规范

新方案 (正确)

用户点击 → 打开 Picker → 选择值 → 直接存储值 → 显示标签

优势:

  • 直接存储实际值,无需索引转换
  • 对象数组包含 label 和 value,更灵活
  • 符合 TDesign 官方规范
  • 代码更简洁清晰

🎯 关键点总结

1. 数据格式

  • 选项必须是 [{ label, value }] 格式
  • value 是实际值,label 是显示文本

2. 组件使用

  • 必须使用 <t-picker-item> 子组件
  • 通过 options 属性传递选项数据
  • 使用 data-key 标识不同的 Picker

3. 事件处理

  • 使用 bindchange 而非 bind:confirm
  • e.detail.value 返回值数组
  • 关闭 Picker 在事件处理中完成

4. 显示文本

  • 单独维护显示文本 (如 regionText)
  • 从对象数组中查找对应 label 显示

📝 完整示例

数据定义:

data: {
  regions: [
    { label: '昆明', value: '昆明' },
    { label: '玉溪', value: '玉溪' }
  ],
  regionText: '请选择地区',
  regionPickerValue: [],
  regionPickerVisible: false
}

WXML:

<t-cell note="{{regionText}}" arrow bindtap="showRegionPicker" />

<t-picker
  visible="{{regionPickerVisible}}"
  value="{{regionPickerValue}}"
  data-key="region"
  bindchange="onPickerChange">
  <t-picker-item options="{{regions}}"></t-picker-item>
</t-picker>

JS:

showRegionPicker() {
  this.setData({ regionPickerVisible: true })
},

onPickerChange(e) {
  const { value } = e.detail
  const region = this.data.regions.find(item => item.value === value[0])

  this.setData({
    regionPickerVisible: false,
    regionPickerValue: value,
    regionText: region.label
  })
}

修复验证

在微信开发者工具中测试:

  1. 点击"地区"单元格,弹出选择器
  2. 选择器正确显示地区选项
  3. 选择后,单元格显示正确的地区名称
  4. 点击"查询价格",使用正确的地区值
  5. 材质和品名选择器同样正常工作

🎉 总结

修复完成!现在 Picker 组件使用的是 TDesign 官方推荐的标准用法:

  • 数据格式正确 (对象数组)
  • 组件结构正确 (使用 t-picker-item)
  • 事件处理正确 (使用 bindchange)
  • 状态管理正确 (直接存储值而非索引)

所有下拉选择现在应该可以正常工作了!


修复完成时间: 2026-01-06 状态: 已完成,请测试验证