uniapp 二级联动选择器

代码部分

<template>
  <view class="container">
    <picker 
      mode="multiSelector" 
      @change="handlePickerChange" 
      @columnchange="handlePickerColumnChange"
      :value="multiIndex" 
      :range="multiArray" 
      range-key="name"
      class="region-picker"
    >
      <view class="picker-display">
        <text class="selected-text">{{ selectedProvince }} - {{ selectedCity }}</text>
        <text class="picker-arrow">▼</text>
      </view>
    </picker>
    
    <view v-if="regionId" class="selected-info">
      当前选中地区ID: {{ regionId }}
    </view>
  </view>
</template>

<script>
// 模拟数据提取到外部常量
const MOCK_REGION_DATA = {
  retdata: [
    {
      areacode: 340000,
      city_name: "安徽",
      pinyin: "anhui",
      abb_province: "皖",
      city_list: [
        { areacode: 340800, city_name: "安庆", pinyin: "anqing", abb_province: "H" },
        { areacode: 340300, city_name: "蚌埠", pinyin: "bangbu", abb_province: "C" },
        { areacode: 340100, city_name: "合肥", pinyin: "hefei", abb_province: "A" }
      ]
    },
    {
      areacode: 320000,
      city_name: "江苏",
      pinyin: "jiangsu",
      abb_province: "苏",
      city_list: [
        { areacode: 320100, city_name: "南京", pinyin: "nanjing", abb_province: "A" },
        { areacode: 320200, city_name: "无锡", pinyin: "wuxi", abb_province: "B" },
        { areacode: 320300, city_name: "徐州", pinyin: "xuzhou", abb_province: "C" }
      ]
    },
    {
      areacode: 330000,
      city_name: "浙江",
      pinyin: "zhejiang",
      abb_province: "浙",
      city_list: [
        { areacode: 330100, city_name: "杭州", pinyin: "hangzhou", abb_province: "A" },
        { areacode: 330200, city_name: "宁波", pinyin: "ningbo", abb_province: "B" },
        { areacode: 330300, city_name: "温州", pinyin: "wenzhou", abb_province: "C" }
      ]
    }
  ]
};

export default {
  data() {
    return {
      provinces: [],
      cities: [],
      multiArray: [],
      multiIndex: [0, 0],
      selectedProvince: '',
      selectedCity: '',
      regionId: ''
    };
  },

  onLoad() {
    uni.setNavigationBarTitle({
      title: '智能工具箱'
    });
    this.initRegionData();
  },

  methods: {
    // 初始化地区数据
    initRegionData() {
      this.processRegionData(MOCK_REGION_DATA.retdata);
    },

    // 处理地区数据
    processRegionData(data) {
      if (!data || !Array.isArray(data)) {
        console.error('Invalid region data');
        return;
      }

      const provinces = [];
      const cities = [];

      data.forEach(province => {
        // 省份数据
        provinces.push({
          id: province.areacode,
          name: province.city_name,
          pinyin: province.pinyin,
          abb: province.abb_province
        });

        // 城市数据
        const cityList = province.city_list.map(city => ({
          id: city.areacode,
          name: city.city_name,
          pinyin: city.pinyin,
          abb: city.abb_province
        }));
        
        cities.push(cityList);
      });

      // 批量更新数据
      Object.assign(this, {
        provinces,
        cities,
        multiArray: [provinces, cities[0]],
        selectedProvince: provinces[0]?.name || '',
        selectedCity: cities[0]?.[0]?.name || '',
        regionId: cities[0]?.[0]?.id || ''
      });
    },

    // 列改变事件处理
    handlePickerColumnChange(e) {
      const { column, value } = e.detail;
      
      // 省份列变化
      if (column === 0) {
        this.updateCityColumn(value);
      } else {
        // 城市列变化
        this.multiIndex = [this.multiIndex[0], value];
        this.updateSelectedCity(value);
      }
    },

    // 更新城市列
    updateCityColumn(provinceIndex) {
      if (!this.cities[provinceIndex]) return;
      
      this.multiArray = [this.provinces, this.cities[provinceIndex]];
      this.multiIndex = [provinceIndex, 0];
      
      // 更新显示文本
      this.selectedProvince = this.provinces[provinceIndex]?.name || '';
      this.selectedCity = this.cities[provinceIndex]?.[0]?.name || '';
      this.regionId = this.cities[provinceIndex]?.[0]?.id || '';
    },

    // 更新选中城市
    updateSelectedCity(cityIndex) {
      const provinceIndex = this.multiIndex[0];
      const city = this.cities[provinceIndex]?.[cityIndex];
      
      if (city) {
        this.selectedCity = city.name;
        this.regionId = city.id;
      }
    },

    // 选择器确认事件
    handlePickerChange(e) {
      const [provinceIndex, cityIndex] = e.detail.value;
      const province = this.provinces[provinceIndex];
      const city = this.cities[provinceIndex]?.[cityIndex];
      
      if (province && city) {
        Object.assign(this, {
          selectedProvince: province.name,
          selectedCity: city.name,
          regionId: city.id,
          multiIndex: [provinceIndex, cityIndex]
        });
        
        console.log('选中地区:', province.name, city.name, 'ID:', city.id);
        
        // 可以在这里触发其他业务逻辑
        this.onRegionSelected(province, city);
      }
    },

    // 地区选择完成回调(可扩展)
    onRegionSelected(province, city) {
      // 这里可以添加选择完成后的业务逻辑
      // 例如:保存到本地存储、触发父组件事件等
      uni.$emit('regionSelected', { province, city });
    }
  }
};
</script>

<style scoped>
.container {
  padding: 30rpx;
}

.region-picker {
  margin: 20rpx 0;
}

.picker-display {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24rpx 30rpx;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 12rpx;
  font-size: 28rpx;
}

.selected-text {
  color: #333;
  font-weight: 500;
}

.picker-arrow {
  color: #6c757d;
  font-size: 24rpx;
}

.selected-info {
  margin-top: 20rpx;
  padding: 20rpx;
  background: #e7f3ff;
  border-radius: 8rpx;
  color: #007aff;
  font-size: 26rpx;
  text-align: center;
}

/* 添加点击效果 */
.picker-display:active {
  background: #e9ecef;
}
</style>

UniApp 中实现下拉框选择器二级联动,可按以下步骤操作: ### 1. 准备数据 首先要准备好两级联动的数据,一般是一个包含父级选项和对应子级选项的对象。 ```javascript export default { data() { return { // 一级选项 parentOptions: [ { id: 1, name: '水果' }, { id: 2, name: '蔬菜' } ], // 二级选项,每个父级选项对应一组子级选项 childOptionsMap: { 1: [ { id: 11, name: '苹果' }, { id: 12, name: '香蕉' } ], 2: [ { id: 21, name: '白菜' }, { id: 22, name: '萝卜' } ] }, // 当前选中的一级选项 selectedParent: null, // 当前选中的二级选项 selectedChild: null, // 当前显示的二级选项列表 currentChildOptions: [] }; } }; ``` ### 2. 编写页面结构 使用 `picker` 组件来创建下拉框选择器。 ```vue <template> <view> <!-- 一级选择器 --> <picker @change="onParentChange" :value="selectedParent" mode="selector" :range="parentOptions.map(item => item.name)"> <view>当前选择的一级选项:{{ selectedParent!== null? parentOptions[selectedParent].name : '请选择' }}</view> </picker> <!-- 二级选择器 --> <picker @change="onChildChange" :value="selectedChild" mode="selector" :range="currentChildOptions.map(item => item.name)" :disabled="currentChildOptions.length === 0"> <view>当前选择的二级选项:{{ selectedChild!== null? currentChildOptions[selectedChild].name : '请先选择一级选项' }}</view> </picker> </view> </template> ``` ### 3. 实现联动逻辑 在 `methods` 中编写处理选择变化的方法。 ```vue <script> export default { data() { // 数据部分同上 }, methods: { // 一级选项选择变化时的处理方法 onParentChange(e) { // 获取选中的一级选项索引 this.selectedParent = e.detail.value; // 根据选中的一级选项 ID 获取对应的二级选项列表 const parentId = this.parentOptions[this.selectedParent].id; this.currentChildOptions = this.childOptionsMap[parentId] || []; // 重置二级选项的选择 this.selectedChild = null; }, // 二级选项选择变化时的处理方法 onChildChange(e) { // 获取选中的二级选项索引 this.selectedChild = e.detail.value; } } }; </script> ``` ### 代码解释 - **数据部分**:`parentOptions` 存储一级选项,`childOptionsMap` 存储每个一级选项对应的二级选项。`selectedParent` 和 `selectedChild` 分别记录当前选中的一级和二级选项的索引,`currentChildOptions` 存储当前显示的二级选项列表。 - **页面结构**:使用 `picker` 组件创建两个下拉框选择器,分别对应一级和二级选项。`@change` 事件监听选择变化,`mode="selector"` 表示选择器模式,`range` 是显示的选项列表。 - **联动逻辑**:当一级选项选择变化时,根据选中的一级选项 ID 更新 `currentChildOptions`,并重置二级选项的选择;当二级选项选择变化时,更新 `selectedChild`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值