react+taro 地区选择器和多列选择器实现省市区的三级联动

1.使用自带的地区选择器实现省市区的三级联动

微信小程序地址https://developers.weixin.qq.com/miniprogram/dev/component/picker.html
taro地址
https://taro-docs.jd.com/taro/docs/components/forms/picker/

主要代码
{/* 就业地区 */}
  {/* 
          
               *
                  地区意向:
                     
                                                   
                           
                           
                          
                
          */}

// 省市区三级联动改变时的值
        bindRegionChange =  e => {
            // console.log('picker发送选择改变,携带值为', e.detail.value)
            // console.log('picker发送选择改变,携带值为', e.detail.code)
            if(e.detail.code.length == 2){
                e.detail.code.push(e.detail.code[1])
            }
            this.setState({
              region: e.detail.value,
              province_id:e.detail.code[0],
              city_id:e.detail.code[1],
              district_id:e.detail.code[2],
            })
          }
{/* 就业地区 */}

1.指定选择器类型: mode = region 省市区选择器
2.region数据格式 显示的数据,为一个数组 => region: ['北京市', '北京市', '东城区'],
3.customItem:可为每一列的顶部添加一个自定义的项 我需要的数据就是在每一个区加上 全某某市 的数据,可惜这个数据是微信官方的数据,然后这样的话在省市区的头部全都加上了一列自定义数据,而我只需要在 上加,和我需要的有一点区别

2.使用多列选择器实现省市区的联动,写的很杂,因为第一次写,写的非常垃圾

实现的效果
主要代码
 {/* 就业地区 */}
          
                
                     *
                           地区意向:
                                
                                                                                   
                                    
                                    {areaName}
                               
                      
              

1.指定选择器类型 mode='multiSelector'

2.range:为多列选择器的数据,二维数组,格式
省市区三列,三个数组
3.value:表示选择了 range 中的第几个(下标从 0 开始)

4.onChange:当 value 改变时触发 change 事件,event.detail = {value};onColumnChange:列改变时触发

主要的代码就是下面这个

            areaValue:[0,0,0], // 在selector里面的下标
            selector: [], // 省市区的数组数据 里面是省市区的三个数组
 // 初始化地区数据
        initArea = () => {
            let { regionData, selector, areaValue,provinceArr,cityArr,districtArr,areaName} = this.state
            let province = []
            let city = []
            let district =[]
            regionData.forEach(item => {
                province.push(item.label)
            })
            selector.push(province)
            regionData[0].children.forEach(item => {
                city.push(item.label)
                item.children.forEach(child => {
                    district.push(child.label)
                })
            })
            selector.push(city)
            selector.push(district)
            let name = `${selector[0][0]},${selector[1][0]},${selector[2][0]}`
            this.setState({
                selector,
                provinceArr: province,
                cityArr: city,
                districtArr: district,
                areaName:'请选择你的就业地区 >'
            })
        }
 //   列改变
        onColumnChange = e => {
          let { regionData, selector,provinceArr,cityArr,districtArr,areaValue,provinceIndex,cityIndex,districtIndex,rangeKey } = this.state
          let column = e.detail.column
          let index = e.detail.value
        //   this.initArea()
         //修改的列为 0 ,值为 1,第一列索引为 1 的值改变了,索引从0开始
          console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
          if(column == 0 ){
                let arr = []
                let arrchild = []
                let provinceIndex = index // 保存一下省份index
                let cityList = regionData[index].children  // 城市名字
                cityList.forEach(city => {
                    arr.push(city.label)
                })
                
                cityList[0].children.forEach(district => {
                    arrchild.push(district.label)
                })
                this.setState({
                    cityArr:arr,
                    provinceIndex,
                    selector:[provinceArr,arr,arrchild],
                    areaValue:[provinceIndex,0,0],
                })
                // console.log(`省份移动${areaValue}`)
          }else if(column == 1){
                let cityIndex = index
                let districtArr = []
                // let cityName = cityArr[index]  // 拿到当前选择的 城市名字
                let arr = []
                // let provIndex = provinceIndex == '' ? areaValue[0] : provinceIndex
                regionData[areaValue[0]].children.forEach(item =>{ // 这一步是为了回显的时候,如果用户没有移动省份,直接移动市的时候,依然能够得到正确的数据,因为 areaValue[0] 数据是省的下标, regionData[areaValue[0]].children就是 原始数据里对应的省份下的市的数据
                    arr.push(item.label)
                })
                let cityName = arr[index]
                regionData[areaValue[0]].children.forEach(city => {
                    if(city.label == cityName){
                        city.children.forEach(district => {
                            districtArr.push(district.label)
                        })
                    }
                })
                // console.log(districtArr)
                this.setState({
                    cityIndex,
                    districtArr,
                    selector:[provinceArr,arr,districtArr],
                    areaValue:[areaValue[0],index,0],
                })
                // console.log(`市移动${areaValue}`)
          }else{
                let districtIndex = index
                provinceIndex = areaValue[0] == '' ? 0 : areaValue[0]
                cityIndex = areaValue[1] == '' ? 0 : cityIndex
                this.setState({
                    areaValue:[provinceIndex,cityIndex,index],
                })
                // console.log(`区移动${areaValue}`)
          }
        }
        // 确定后的数据 onChange  [8, 0, 0] 对应选择数据的下标
        onChange = e => {
            let { selector,areaValue, areaName,province_id,city_id,district_id } = this.state
            const [pro,cty,dis] = e.detail.value // 结构数组中的数据
            let proName = selector[0][pro]
            let ctyName = selector[1][cty]
            let disName = selector[2][dis]
            console.log('onChange', e.detail.value)
            let proCode =  this.searchProCode(proName)
            let ctyCode =  this.searchCtyCode(ctyName)
            let disCode =  this.searchDisCode(disName)
            let name = `${proName},${ctyName},${disName}`
            this.setState({
                areaName:name,
                province_id:proCode,
                city_id:ctyCode,
                district_id:disCode
            })
        }  

主要实现思路:1. 每一列改变的时候可以得到这一列改变的列数和这一列改变的索引,判断是第几列改变,拿到这一列改变的索引区原数据中得到省份下的市,再拿到区
2.第一列数据是固定的省份数组,通过索引去原数据中找到对应省份下 改变的市,然后再通过市去得到区
3第一列 省改变,得到市,第二列改变得到区,保存一下这个改变的index,通过 index 去 range 里面通过索引得到展示的数据,

你可能感兴趣的:(react+taro 地区选择器和多列选择器实现省市区的三级联动)