vue+antdv省市区联动组件封装

省市区联动作为基础组件在各项目中都有使用,抽空封装一下。省市区JSON文件保存在本地,组件下级数据根据上级数据联动,支持删除叶子层级数据。效果图如下:

在这里插入图片描述

<template>
  <div class="regionselect-container">
    <a-form-model
      layout="inline"
      :model="form"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    > 
      <a-form-model-item>
        <a-select
          size="large"
          :allowClear="!form.municipalityId && !form.districtId"
          placeholder="全部省份"
          v-model="form.provinceId"
          @change="(value) => handleChange(value,1)"
        >
          <a-select-option v-for="item in provinceList" :value="item.id" :key="item.id">
            {{item.name}}
          </a-select-option >
        </a-select>
      </a-form-model-item>
      <a-form-model-item v-if="level!==1">
        <a-select 
          size="large"
          :allowClear="!form.districtId"
          placeholder="全部城市"
          notFoundContent="暂无数据"
          v-model="form.municipalityId"
          @change="(value) => handleChange(value,2)"
        >
          <a-select-option v-for="item in municipalityList" :value="item.id" :key="item.id">
            {{item.name}}
          </a-select-option>
        </a-select>
      </a-form-model-item>
      <a-form-model-item v-if="level==3">
        <a-select 
          size="large"
          allowClear
          placeholder="全部地区"
          notFoundContent="暂无数据"
          v-model="form.districtId"
          @change="(value) => handleChange(value,3)"
        >
          <a-select-option v-for="item in districtList" :value="item.id" :key="item.id">
            {{item.name}}
          </a-select-option>
        </a-select>
      </a-form-model-item>
  </a-form-model>
  </div>
</template>

<script>
import region from '@/assets/region.json'
export default {
  name: 'RegionSelect',
  props:{
    level:{
      type: Number,
      default: 3 //1:省 2:省市 3:省市区
    },
    regionData:{
      type: Object,
      default:()=>{
        return{
          provinceId: '',
          municipalityId: '',
          districtId: ''
        }
      }
    }
  },
  data(){
    return {
      region,
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      form:{
        provinceId: '',
        municipalityId: '',
        districtId: ''
      },
    }
  },
  watch:{
    regionData:{
      handler: function(){
        const { provinceId, municipalityId, districtId } = this.regionData
        this.form.provinceId = provinceId == '' ? undefined : Number(provinceId)
        this.form.municipalityId = municipalityId == '' ? undefined : Number(municipalityId)
        this.form.districtId = districtId == '' ? undefined : Number(districtId)
      },
      deep: true,
      immediate: true
    }
  },
  computed:{
    provinceList(){
      return this.region.filter(item=>item.pid == 1)
    },
    municipalityList(){
      if(!this.form.provinceId) return []
      return this.region.filter(item=>item.pid == this.form.provinceId)
    },
    districtList(){
      if(!this.form.municipalityId) return []
      return this.region.filter(item=>item.pid == this.form.municipalityId)
    }
  },
  methods: {
    handleChange(value='',type) {
      switch (type){
        case 1:{
          this.form.provinceId = value
          this.form.municipalityId = ''
          this.form.districtId = ''
          break
        }
        case 2:{
          this.form.municipalityId = value
          this.form.districtId = ''
          break
        }
        case 3:{
          this.form.districtId = value
          break
        }
      }
      this.$nextTick(()=>{
        this.$emit('change',this.form)
      })
    }
  }
}
</script>

<style lang='less' scoped>
.regionselect-container{
  display: flex;
  align-items: center;
  /deep/.ant-select{
    width: 160px;
  }
} 
</style>

注意:如果不用form表单包裹,当存在下级数据情况下改变上级数据,下级的options以及绑定的数据都更新,但是select框的数据不会修改,强制置空源数据也无法清除,默认select框会读取缓存数据,试了好长时间,最后选择用form表单包裹。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值