封装el-cascader 联级选择省市区

根绝业务要求,很多页面需要用到省市区选择。

1、首先准备在util文件下准备一个util.js文件

function setAreaMyList(datas,level) {
  for (var i in datas) {
    if (datas[i].level == level||(datas[i].children&&datas[i].children.length<1)) {
      delete datas[i].children
    } else {
      setAreaMyList(datas[i].children,level);
    }
  }
}
// 往外暴露一个方法
export const getAreaMyList = (list,level) =>{
  let datas = _.cloneDeep(store.state.common.areaMyList)
  console.log('getAreaMyList',datas);
  if(level!='salesLine'){
    setAreaMyList(datas,level)
  }
  return datas
}

2、首先创建一个cascaderAreaSome.vue文件

<!--  -->
<template>
  <el-form-item :label="label" prop="mappingLevel">
    <el-cascader
      size="mini"
      v-model="area"
      ref="cascader"
      :collapse-tags='multiple'
      :filterable='multiple'
      :options="areaList"
      @change="handleChange"
      :props="cascaderProps"
    ></el-cascader>
  </el-form-item>
</template>

<script>
import { getAreaMyList } from '@/util/util'
import _ from 'lodash'
import { mapGetters } from 'vuex';


export default {
  components: {},
  data() {
    return {
      areaList: [],
      area: [],
      cascaderProps: {
        label: 'label',
        value: 'value',
        checkStrictly: this.checkStrictly,
        multiple: this.multiple,
      },
      form: {
      }
    };
  },
  props: {
    /****
     * 新增多选
     * 之前功能不动,
     * 多选只负责查询,
     * 没有反填功能,
     * 
     */
    multiple: {
      default: false,
    },
    defaultAreaCodes: {
      default: null
    },
    isSetDefault: {
      default: true
    },
    showDefault: {
      default: true
    },
    level: {
      default: 'district'
    },
    label: {
      default: '行政区划:'
    },
    value: {
      default: Object.create({})
    },
    checkStrictly: {
      default: true,
    },
    getareaFromForm: {
      default: false,
    }
  },
  computed: {
    ...mapGetters(['defaultArea', 'areaMyList'])
  },
  watch: {
    form(v) {
      this.setDefault()
    },
    value(v) {
      this.form = v
    },
    defaultArea: {
      deep: true,
      handler(v) {
        this.setDefault()
      }
    },
    areaMyList: {
      deep: true,
      handler(v) {
        this.setDefault()
      }
    },
  },
  created() {
    this.areaList = _.cloneDeep(getAreaMyList(this.areaMyList, this.level))
    this.form = this.value
    this.setDefault()
  },
  methods: {
    setDefault() {

      if(this.multiple) return;

      console.log('setDefault');
      if (!this.isSetDefault) return
      if (this.defaultAreaCodes) {
        this.area = [this.defaultAreaCodes.provinceCode, this.defaultAreaCodes.cityCode, this.defaultAreaCodes.districtCode,]
      } else {
        let area = _.cloneDeep(this.defaultArea.areas)
        switch (this.level) {
          case 'province':
            area.splice(1, 3)
            break;
          case 'city':
            area.splice(2, 3)
            break;
          default:
            break;
        }
        this.area = area
      }
      this.handleChange(this.area)
      if (this.isSetDefault && this.showDefault) {
        console.log('this.area', this.area)
      } else {
        this.area = []
        this.form.province = ''
        this.form.city = ''
        this.form.district = ''
      }
    },
    handleChange(value) {
      if(this.multiple) {
        if (!value) return
        let provinceList = []
        let cityList = []
        let districtList = []
        value.forEach((element) => {
          let len = element.length;
          let index = len - 1
          switch(len) {
            case 1 :
              provinceList.push(element[index])
              break;
            case 2 :
              cityList.push(element[index])
              break;
            case 3 :
              districtList.push(element[index])
              break;
            default:
              break;
          }

        });

        this.form.province = provinceList
        this.form.city = cityList
        this.form.district = districtList
        this.$emit('input', this.form)

        return 
      }


      console.log('handleAreaChange', value);
      if (!value) return
      this.form.province = value[0] ? value[0] : ''
      this.form.city = value[1] ? value[1] : ''
      this.form.district = value[2] ? value[2] : ''
      let pickList = []
      let provinceObj = {}
      let cityObj = {}
      let districtObj = {}

      value.forEach((element, i) => {
        switch (i) {
          case 0:
            provinceObj = this.areaList.find(v => {
              return v.value == element
            })
            pickList.push(provinceObj)
            break;
          case 1:
            console.log('provinceObj', provinceObj);
            cityObj = provinceObj.children.find(v => {
              return v.value == element
            })
            pickList.push(cityObj)
            break;
          case 2:
            console.log('cityObj', cityObj);
            districtObj = cityObj.children.find(v => {
              return v.value == element
            })
            pickList.push(districtObj)
            break;
          default:
            break;
        }
      });
      console.log('pickList', pickList);
      this.$emit('input', this.form)
      this.$nextTick(() => {
        this.$emit('setPickList', pickList)
      })
      this.$nextTick(() => {
        this.$emit('setLastPick', pickList[pickList.length - 1])
      })
    }
  },
}
</script>
<style lang='scss' scoped>
</style>

3、在main.js里面引用,绑定全局(根据业务要求,其他页面也在使用)

import cascaderAreaSome from './components/filter/cascaderAreaSome.vue'
Vue.component("cascaderAreaSome", cascaderAreaSome) //挂在到全局

4、在页面中使用

<template>
 <el-col :span="6">
            <cascaderAreaSome
              :isSetDefault="false"
              ref="cascaderArea"
              v-model="filterForm"
              :multiple="true"
            />
          </el-col>
</template>
export default {
  data() {
    return {
      filterForm: {
        city: [],
        district: [],
        province:[], 
      },
    
    };
  },

此疯转的省市区下拉选择支持多选,单选、回显

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值