最近搜索

小程序 下拉 选择 picker 一级 二级效果

浏览:77
管理员 2026-07-03 20:41

分类1变动 分类2也随着变动



只使用一个picker 

image.png image.png


Page({
  data: {
    // 多列选择器数据
    multiArray: [[], []],
    multiIndex: [0, 0],

    // 当前选中的对象
    selectedLevel1: null,
    selectedLevel2: null,

    // 显示文字
    displayText: '',

    // 是否可提交
    canSubmit: false
  },

  onLoad() {
    // 初始加载一级列表
    const level1List = this.getLevel1List()
    const level2List = this.getLevel2ByLevel1(level1List[0].id)

    this.setData({
      'multiArray[0]': level1List,
      'multiArray[1]': level2List,
      multiIndex: [0, 0],
      selectedLevel1: level1List[0],
      selectedLevel2: level2List[0],
      displayText: level1List[0].name + ' - ' + level2List[0].name,
      canSubmit: true
    })
  },

  // 列变化(一级变 → 更新二级)
  onColumnChange(e) {
    const { column, value } = e.detail

    if (column === 0) {
      // 一级列变了,二级跟着变
      const level1 = this.data.multiArray[0][value]
      const level2List = this.getLevel2ByLevel1(level1.id)

      this.setData({
        'multiArray[1]': level2List,
        multiIndex: [value, 0],
        selectedLevel1: level1,
        selectedLevel2: level2List[0],
        displayText: level1.name + ' - ' + level2List[0].name
      })
    }
    // column === 1 时不处理,保持 multiIndex 同步即可
  },

  // 确认选择
  onConfirm(e) {
    const [l1Idx, l2Idx] = e.detail.value
    const level1 = this.data.multiArray[0][l1Idx]
    const level2 = this.data.multiArray[1][l2Idx]

    this.setData({
      multiIndex: e.detail.value,
      selectedLevel1: level1,
      selectedLevel2: level2,
      displayText: level1.name + ' - ' + level2.name,
      canSubmit: true
    })
  },

  // 一级列表
  getLevel1List() {
    return [
      { id: 1, name: '数码电子' },
      { id: 2, name: '服装鞋包' },
      { id: 3, name: '食品生鲜' },
      { id: 4, name: '家居用品' }
    ]
  },

  // 二级列表
  getLevel2ByLevel1(l1Id) {
    const map = {
      1: [
        { id: 101, name: '手机' },
        { id: 102, name: '电脑' },
        { id: 103, name: '平板' },
        { id: 104, name: '耳机' },
        { id: 105, name: '充电器' }
      ],
      2: [
        { id: 201, name: '男装' },
        { id: 202, name: '女装' },
        { id: 203, name: '童装' },
        { id: 204, name: '运动鞋' },
        { id: 205, name: '背包' }
      ],
      3: [
        { id: 301, name: '水果' },
        { id: 302, name: '蔬菜' },
        { id: 303, name: '肉类' },
        { id: 304, name: '海鲜' },
        { id: 305, name: '零食' }
      ],
      4: [
        { id: 401, name: '厨具' },
        { id: 402, name: '床品' },
        { id: 403, name: '清洁用品' },
        { id: 404, name: '收纳' },
        { id: 405, name: '家电' }
      ]
    }
    return map[l1Id] || []
  },

  // 提交
  onSubmit() {
    const { selectedLevel1, selectedLevel2 } = this.data
    if (!selectedLevel1 || !selectedLevel2) return

    wx.showToast({ title: '已选择', icon: 'success' })
    console.log('选择结果:', { level1: selectedLevel1, level2: selectedLevel2 })
    // TODO: 调用接口
  }
})


<view class="container">

<!-- 标题 -->
<view class="page-title">分类选择</view>

<!-- 单个联动选择器 -->
<view class="field-card">
  <view class="field-label">选择分类</view>
  <picker
    mode="multiSelector"
    bindcolumnchange="onColumnChange"
    bindchange="onConfirm"
    value="{{multiIndex}}"
    range="{{multiArray}}"
    range-key="name"
  >
    <view class="picker-box">
      <text class="picker-value {{!multiIndex[0] && !multiIndex[1] ? 'placeholder' : ''}}">
        {{displayText || '请选择一级和二级分类'}}
      </text>
      <text class="picker-arrow">›</text>
    </view>
  </picker>
</view>

<!-- 提示文字 -->
<view class="hint-text">请先选择一级分类,再选择二级分类</view>

<!-- 已选结果 -->
<view class="result-card" wx:if="{{selectedLevel1 || selectedLevel2}}">
  <view class="result-title">已选分类</view>
  <view class="result-tags">
    <view class="result-tag tag-l1" wx:if="{{selectedLevel1}}">
      <text>{{selectedLevel1.name}}</text>
    </view>
    <text class="result-arrow" wx:if="{{selectedLevel1 && selectedLevel2}}">›</text>
    <view class="result-tag tag-l2" wx:if="{{selectedLevel2}}">
      <text>{{selectedLevel2.name}}</text>
    </view>
  </view>
  <view class="result-id" wx:if="{{selectedLevel2}}">
    最终分类ID:{{selectedLevel2.id}}
  </view>
</view>

<!-- 提交按钮 -->
<button
  class="submit-btn {{canSubmit ? 'active' : ''}}"
  bindtap="onSubmit"
  disabled="{{!canSubmit}}"
>确认选择</button>

</view>


page {
  background: #f5f7fa;
}

.container {
  padding: 32rpx 24rpx;
  min-height: 100vh;
}

/* 标题 */
.page-title {
  font-size: 36rpx;
  font-weight: 700;
  color: #1a1a1a;
  margin-bottom: 32rpx;
  padding-left: 8rpx;
}

/* 字段卡片 */
.field-card {
  background: #fff;
  border-radius: 16rpx;
  padding: 28rpx 28rpx;
  margin-bottom: 24rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}

.field-label {
  font-size: 26rpx;
  color: #999;
  margin-bottom: 16rpx;
}

.picker-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 24rpx;
  background: #f9fafb;
  border-radius: 12rpx;
  border: 2rpx solid transparent;
  transition: border-color 0.2s;
}

.picker-box:active {
  border-color: #07c160;
}

.picker-box.disabled {
  opacity: 0.4;
}

.picker-value {
  font-size: 30rpx;
  color: #1a1a1a;
}

.picker-value.placeholder {
  color: #bbb;
}

.picker-arrow {
  font-size: 32rpx;
  color: #ccc;
  transform: rotate(90deg);
}

.picker-arrow.disabled {
  color: #ddd;
}

/* 已选结果 */
.result-card {
  background: #fff;
  border-radius: 16rpx;
  padding: 28rpx;
  margin-top: 8rpx;
  margin-bottom: 40rpx;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
  border-left: 6rpx solid #07c160;
}

.result-title {
  font-size: 24rpx;
  color: #999;
  margin-bottom: 16rpx;
}

.result-tags {
  display: flex;
  align-items: center;
  gap: 12rpx;
  flex-wrap: wrap;
}

.result-tag {
  padding: 10rpx 20rpx;
  border-radius: 24rpx;
  font-size: 28rpx;
  font-weight: 500;
}

.tag-l1 {
  background: #e8f5e9;
  color: #2e7d32;
}

.tag-l2 {
  background: #e3f2fd;
  color: #1565c0;
}

.result-arrow {
  font-size: 28rpx;
  color: #bbb;
}

.result-id {
  font-size: 22rpx;
  color: #bbb;
  margin-top: 14rpx;
  padding-top: 14rpx;
  border-top: 1rpx dashed #eee;
}

/* 提交按钮 */
.submit-btn {
  width: 100%;
  height: 96rpx;
  line-height: 96rpx;
  border-radius: 48rpx;
  font-size: 32rpx;
  font-weight: 600;
  color: #fff;
  background: #d8d8d8;
  border: none;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.submit-btn.active {
  background: linear-gradient(135deg, #07c160 0%, #06ad56 100%);
  box-shadow: 0 4rpx 20rpx rgba(7, 193, 96, 0.35);
}

.submit-btn.active:active {
  transform: scale(0.98);
  opacity: 0.9;
}


联系站长

站长微信:xiaomao0055

站长QQ:14496453