欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

uniapp 三级地区选择组件 selectAddress pick-xxx的使用

程序员文章站 2024-02-02 12:00:40
...

三级地区选择

uniapp 三级地区选择组件 selectAddress pick-xxx的使用
功能要求如下:

  1. 点击 可以弹出选择组件,选择地区后,会显示在界面上
  2. 接收到地区code后,可以根据地区code查找到对应的地区名称,进行展示。

此功能实现时,利用了一个封装好的组件 selectAddress ,后面会放出代码。

界面部分

<view class="row b-b">
	<text class="tit">地址</text>
	// disableFlag: 是否禁用   defaultRegion:默认的地区  @getRegion 选择地区的函数
	<pick-regions :disableFlag="disableFlag" :defaultRegion="defaultRegion" @getRegion="handleGetRegion" class="input">
	       <text v-if='regionName'>{{regionName}}</text>
		   <text style="color: #999;" v-else>//</text>
	</pick-regions>
	<text style="color: #999;" class="icon iconfont icon-you-copy"></text>
</view>

script数据部分

// 引入地区列表json文件
const CHINA_REGIONS = require('@/components/regions.json')
data(){
	return{
		defaultRegion:['浙江省','杭州市','拱墅区'],
		defaultRegionCode:'130102',
		disableFlag:false,
		region:[]
	}
},
computed:{
	regionName(){
		let addr = ""
		this.region.forEach(item=>{
			addr += `${item}  `;
		})
		return addr;
	}
},
methods:{
	 // 获取选择的地区
	handleGetRegion(region){
		this.region = [];
		region.forEach((item)=>{
			this.region.push(item.name);
		})
		console.log(region);
		// 以下是地区code的存储
		this.userInfo.regionId = region[region.length - 1].code;
	},
	// 根据地区code获取地区名称
	getAddr(row) {
      let code = row;
	  this.region = [];
      if (code) {
        let provinceCode = code.slice(0, 2);
        let cityCode = code.slice(2, 4);
        let areaCode = code.slice(4, 6);
        let addr = "";
        CHINA_REGIONS.forEach(item => {
          if (item.code.slice(0, 2) === provinceCode) {
            addr += item.name;
			this.region.push(item.name);
            item.childs.forEach(item2 => {
              if (item2.code.slice(2, 4) === cityCode) {
                addr += item2.name;
				this.region.push(item2.name);
                item2.childs.forEach(item3 => {
                  if (item3.code.slice(4, 6) === areaCode) {
                    addr += item3.name;
					this.region.push(item3.name);
                  }
                });
              }
            });
			this.defaultRegion = this.region;
          }
        });
      }
    }
}

selectAddress组件

<template>
    <picker mode="multiSelector" 
            :value="multiIndex" 
            :range="multiArray" 
            @change="handleValueChange"
            @columnchange="handleColumnChange" :disabled="disabledFlag">
        <slot></slot>
    </picker>
</template>

<script>
    const CHINA_REGIONS = require('./regions.json')
	export default {
        props:{
            defaultRegions:{
                type:Array,
                default(){
                    return []
                }
            },
			disabledFlag:{
				type:Boolean,
				default:false
			},
            defaultRegion:[String,Array]
        },
		data() {
			return {
                cityArr:CHINA_REGIONS[0].childs,
                districtArr:CHINA_REGIONS[0].childs[0].childs,
                multiIndex: [0,0,0],
                isInitMultiArray:true,
			}
		},
        watch:{
            defaultRegion:{
                handler(region,oldRegion){
                    if(Array.isArray(region)){
                        // 避免传的是字面量的时候重复触发
                        oldRegion = oldRegion || []
                        if(region.join('')!==oldRegion.join('')){
                            this.handleDefaultRegion(region)
                        }
                    }else if(region&&region.length == 6){
                        this.handleDefaultRegion(region)
                    }else{
                        console.warn('defaultRegion非有效格式')
                    }
                },
                immediate:true,
            }
        },
        computed:{
            multiArray(){
                return this.pickedArr.map(arr=>arr.map(item=>item.name))
            },
            pickedArr(){
                // 进行初始化
                if(this.isInitMultiArray){
                    return [
                        CHINA_REGIONS,
                        CHINA_REGIONS[0].childs,
                        CHINA_REGIONS[0].childs[0].childs
                    ]
                }
                return [CHINA_REGIONS,this.cityArr,this.districtArr];
            }
        },
		methods: {
            handleColumnChange(e){
                this.isInitMultiArray = false;
                const that = this;
                let col = e.detail.column;
                let row = e.detail.value;
                that.multiIndex[col] = row;
                try{
                    switch(col){
                        case 0:
                            if(CHINA_REGIONS[that.multiIndex[0]].childs.length==0){
                                that.cityArr = that.districtArr = [CHINA_REGIONS[that.multiIndex[0]]]
                                break;
                            }
                            that.cityArr = CHINA_REGIONS[that.multiIndex[0]].childs
                            that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[that.multiIndex[1]].childs
                            break;
                        case 1:
                            that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[that.multiIndex[1]].childs
                            break;
                        case 2:
                            break;
                    }
                }catch(e){
                    // console.log(e);
                    that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[0].childs
                }
                
            },
            handleValueChange(e){
                // 结构赋值
                let [index0,index1,index2] = e.detail.value;
                let [arr0,arr1,arr2] = this.pickedArr;
                let address = [arr0[index0],arr1[index1],arr2[index2]];
                // console.log(address);
                this.$emit('getRegion',address)
            },
            handleDefaultRegion(region){
                const isCode = !Array.isArray(region)
                this.isInitMultiArray = false;
                let children = CHINA_REGIONS
                for(let i=0;i<3;i++){
                    for(let j=0;j<children.length;j++){
                       let condition = isCode?children[j].code==region.slice(0,(i+1)*2):children[j].name.includes(region[i]);
                       if(condition){
                           // 匹配成功进行赋值
                           children = children[j].childs;
                           if(i==0){
                               this.cityArr = children
                           }else if(i==1){
                               this.districtArr = children
                           }
                           this.$set(this.multiIndex,i,j)
                           break;
                       }else{
                           // 首次匹配失败就用默认的初始化
                           if(i==0 && j==(children.length-1)){
                               this.isInitMultiArray = true;
                           }
                       }
                    }
                }
            }
		}
	}
</script>