el-cascader+懒加载+省市区镇+纯前端实现+vue

需求:1、不要一次引入全部数据,加载过慢;2、传入数据要回显;3、暂不增加后端接口

一、首先找到全国的省市区镇信息,但是不能一次性引入,需要分开

找了很久最后发现了这个宝藏划区 (按照等级划分,起名为各个区域标号)GitHub - lizeze/china_region: 行政区域数据, 包括省,市,区,县,镇,街道

将左边的数据1-4换了名字为province、city、district、street,可以不换,看个人偏好。

可直接下载已修改过的。

二、直接封装组件

1、懒加载

2、数据回显

直接上代码: 

<template>
  <div class="cascaderArea">
    <el-cascader
      v-if="showCascader"
      :props="props"
      :options="nowData"
      v-model="selectedOptions"
      placeholder="请选择区域"
      @change="handleChange"
      style="width: 100%"
    ></el-cascader>
  </div>
</template>
<script>
export default {
  name: 'cascaderArea',
  props: ['Address'],
  watch: {
    Address: {
      deep: true,
      immediate: true,
      handler(newVal,oldVal) {
        if(newVal && newVal.length > 0){
          this.selectedOptions = newVal;
          this.setArea(this.selectedOptions)
        }
      }        
    },
  },
  data() {
    return {
      showCascader: true,
      selectedOptions: this.Address,
      type: ['province','city','district','street'],
      nowData: [],
      props: {
        lazy: true,
        lazyLoad: (node, resolve) => {
          const { level, children } = node;
          // 防止数据重复加载
          if (children && children.length > 0) return resolve(nodes)
          const nodes = [];
          let id = level === 0 ? '100000' : node.data.id;
          let realData = require(`../assets/json/city_data/${this.type[level]}/${id}.json`);
          realData.map((item) => {
            let area = {
              value: item.name,
              label: item.name,
              leaf: node.level >= 3,
              id: item.adcode,
            };
            nodes.push(area)
          })
          resolve(nodes)
        },
      }
    }
  },
  methods: {
    // 数据回显
    setArea(arr) {
      this.showCascader = false;
      this.nowData = []
      let optionsList = [];
      let realList = [];
      for (let i=0; i < arr.length; i++) {
        let id = i === 0 ? '100000' : realList[i-1].id;
        let realData = require(`../assets/json/city_data/${this.type[i]}/${id}.json`);
        for (let j=0; j < realData.length; j++) { 
          let area = {
            value: realData[j].name,
            label: realData[j].name,
            leaf: i >= 3,
            id: realData[j].adcode,
          };
          if (i === 0) {
            optionsList.push(area)
          }else if (i === 1){
            optionsList[realList[0].index].children.push(area)
          }else if (i === 2){
            optionsList[realList[0].index].children[realList[1].index].children.push(area)
          }else if (i === 3){
            optionsList[realList[0].index].children[realList[1].index].children[realList[2].index].children.push(area)
          }
          if(realData[j].name === arr[i]){
            area.index = j;
            area.children = [];
            realList.push(area)
          }
        }
      }
      this.nowData = optionsList;
      this.$nextTick(() => {
        this.showCascader = true;
      })
    },
    handleChange(value) {
      this.$emit('city', value)
    },
  }
}
</script>
<style lang="scss" scoped>
</style>

这其中还有一些可以优化的地方,但是大致思路就是这些了,如果后续增加接口,直接将请求本地资源换位请求接口即可。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃彩虹吐司的安琪拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值