微信小程序,动态设置三级联动, 省市区街道

在这里插入图片描述

1.第一步   传parentId=0   查询省份
2.第二步   选择省份,传pathId=选择省份的pathId, 不传parentId,会查询出   市/县数据
3.第三步   根据选择县的parentId 查询街道数据,传parentId=选择的县id
4.选择结果回显   显示所选择的 path 以/分割   取最后一级
  <van-dropdown-menu active-color="#409eff" custom-class="filter-menus">
    <van-dropdown-item id="areaAll" title="{{areaName}}">
      <view class="areaBox" style="height:288rpx; overflow:auto;">
        <van-cell class="van-dropdown-item__option dropdown-time {{item.id === parentId ? 'time-active' : ''}}" wx:for="{{areaAllList}}" wx:key="index" data-item="{{item}}" bindtap="areaClick">
          <view class="van-cell">
            <view class="van-dropdown-item__title">{{item.name}}</view>
          </view>
        </van-cell>
      </view>
      <view>
        <van-picker show-toolbar columns='{{columns}}' value-key='name' bind:change='chgArea' bind:confirm='confirmArea' bind:cancel='areaClose' />
      </view>
    </van-dropdown-item>
 </van-dropdown-menu>
Page({
  data: {
      //行政区域
    areaAllList: [],
    columns: [
      // {
      //   values: '', // one,                    //可以是数组,或者对象数组
      //   className: 'column1' //选择器的第一列
      // },
      // {
      //   values: '', // two[one[0].name],       //默认选中two对象中的第一项
      //   className: 'column2', //选择器的第二列
      // },
      // {
      //   values: '', // three[two[one[0].name][0].name],  //默认选中three对象中的第一项
      //   className: 'column3', //选择器的第三列
      // }
    ],
    one: [],
    two: [],
    areaName:'区域选择'
  }
  })
  onLoad(options) {
    //行政区划   areaAllList
    this.getParent() //
},
method:{
  areaClick(e) {
  //点击省, 请求市级的数据
    const item = e.currentTarget.dataset.item
    this.setData({
      parentId: item.id
    })
    this.initPath(item.pathId)
  },
  getParent() {
  //获取顶部的省级
    fetch.apply.getAreaAll({
      parentId: 0
    }, res => {
      if (res.flag == 0) {
        this.setData({
          areaAllList: res.object
        })
      }
    })
  },
  initPath(pathId) {
  // 1写入 选择器第一级 数据 ;  2将二级数据, 做成 columns 的格式,并写入
    fetch.apply.getAreaAll({
      pathId: pathId
    }, res => {
      if (res.flag == 0 && res.object.length > 0) {
        var v1 = []
        res.object.forEach((e, i) => {
          v1[e.name] = e.childs
        });
        this.setData({
          one: res.object,
          two: v1,
        })
        this.setData({
          columns: [{
              values: this.data.one, //可以是数组,或者对象数组
              className: 'column1', //选择器的第一列
            },
            {
              values: this.data.two[this.data.one[0].name], //默认选中two对象中的第一项
              className: 'column2', //选择器的第二列
              defaultIndex: 0
            },
            {
              values: '', // this.data.three[this.data.two[this.data.one[0].name][0].name], //默认选中three对象中的第一项
              className: 'column3', //选择器的第三列
            }
          ],
        })
      } else {
        this.setData({
          one: '',
          two: '',
          columns: []
        })
      }
    })
  },
  confirmArea(event) {
    let value = event.detail.value
    if (!value[0]) {
      this.setData({
        areaPathId: '',
        top_num: 0
      })
    }
    if (!value[0]) {
      this.setData({
        areaPathId: ''
      })
      this.setData({
        list: []
      })
    } else if (!value[1]) {
      this.setData({
        areaPathId: ''
      })
      this.setData({
        list: []
      })
    } else if (!value[2]) {
      var areaPath = value[1].path;
      var areaName = ''
      if (areaPath.indexOf('/') > 0) {
        areaName = this.getAreaname(areaPath)
      } else {
        areaName = areaPath
      }
      this.setData({
        areaName: areaName,
        areaPathId: value[1].pathId
      })
      this.setData({
        list: []
      })
    } else {
      var areaPath = value[2].path;
      var areaName;
      if (areaPath.indexOf('/') > 0) {
        areaName = this.getAreaname(areaPath)
      }
      this.setData({
        areaName: areaName,
        areaPathId: value[2].pathId
      })
      this.setData({
        list: []
      })
    }

    this.getList()
    this.areaClose()
  },
 getAreaname(areaPath) {
    var areaName
    var arr = areaPath.split("/");
    console.log('dfdfdf', arr[arr.length - 1])
    areaName = arr[arr.length - 1]
    return areaName
  },
  chgArea(event) {
  // 滚动选择器, 通过第二级,获取最后一级, 街道数据
    let picker = event.detail.picker
    let value = event.detail.value
    let index = event.detail.index

    //在change 第一列的时候,动态更改第二列的数据
    //setColumnValues是vant自带的实例方法
    //第一个参数是列数,从0开始;第二个参数是第二列应该显示的数据
    picker.setColumnValues(1, this.data.two[value[0].name])

    //此处vant-picker有一个bug,当只滑动第一级时,返回的value数据是错误的,需要我们自己根据第二 级计算,去获取第三级数据
    if (index == 0) {
      //切换 市, 街道清空
       picker.setColumnValues(2, '')
    } else if (index == 1) {
      var v2 = {}
      fetch.apply.getAreaAll({
        parentId: value[index].id
      }, res => {
        if (res.flag == 0) {
          v2[value[index].name] = res.object
          this.setData({
            three: v2
          })
          picker.setColumnValues(2, this.data.three[value[1].name])
        }
      })
    } else {
      picker.setColumnValues(2, this.data.three[value[1].name])
    }
  },
  areaClose() {
    this.selectComponent('#areaAll').toggle()
  },
}

技术要点

1 按照固定格式, 设置columns 的数据
2 picker.setColumnValues() 方法,获取数据

columns 的数据 格式

var one = [
  { id: 111, 'name': '杭州' },
  { id: 222, 'name': '宁波' },
]
var two = {
  '杭州': [
    { id: 11100, 'name': '国杭州' },
    { id: 22201, 'name': '国宁波' },
  ],
  '宁波': [
    { id: 11102, 'name': '中杭州' },
    { id: 22203, 'name': '中宁波' },
    { id: 33304, 'name': '中温州' },
  ]
}
var three = {
  '国杭州': [
    { id: 1110000, 'name': 'aaa' },
    { id: 2220101, 'name': 'bbb' },
  ],
  '国宁波': [
    { id: 1110102, 'name': 'ccc' },
    { id: 2220103, 'name': 'ddd' },
    { id: 3330104, 'name': 'eee' },
  ],
  '中杭州': [
    { id: 1110205, 'name': 'fff' },
    { id: 2220206, 'name': 'ggg' },
    { id: 3330207, 'name': 'hhh' },
  ],
  '中宁波': [
    { id: 1110308, 'name': 'www' },
    { id: 2220309, 'name': 'ttt' },
    { id: 3330310, 'name': 'yyy' },
  ],
  '中温州': [
    { id: 1110411, 'name': 'jjj' },
    { id: 2220412, 'name': 'kkk' },
    { id: 3330413, 'name': 'ppp' },
  ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值