业务场景

在项目中遇到了一古怪的需求,级联框只让选择某二级分类下的叶子节点,静思思考试验后写了一个可使用方法,记录一下,也给其他的小伙伴们一点思路。

思路

通过记录二级分类的值,每次选择项发生改变的时候遍历新的选择项,如果有其他的二级分类,则只保留新二级分类下的选项,然后改变组件的绑定的值,并记录新的二级分类值。

代码

代码原型和示例数据均为elemnent官方示例的。cascader级联选择器

贴图

UI:
在这里插入图片描述
数据及配置:
在这里插入图片描述
业务处理:
在这里插入图片描述

完整代码

<template>
  <div class="block">
     <span class="demonstration">默认显示所有Tag</span>
     <el-cascader
         v-model="cascadeList"
         :options="options"
         :props="props"
         clearable
         @change="handleChange"/>
 </div>
</template>
 data() {
    return {
      cascadeList: [],
      oldMidVal: "",
      props: { multiple: true },
      options: [
        {
          value: 1,
          label: "东南",
          children: [{
            value: 2,
            label: "上海",
            children: [
              { value: 3, label: "普陀" },
              { value: 4, label: "黄埔" },
              { value: 5, label: "徐汇" },
            ],
          }, {
            value: 7,
            label: "江苏",
            children: [
              { value: 8, label: "南京" },
              { value: 9, label: "苏州" },
              { value: 10, label: "无锡" },
            ],
          }, {
            value: 12,
            label: "浙江",
            children: [
              { value: 13, label: "杭州" },
              { value: 14, label: "宁波" },
              { value: 15, label: "嘉兴" },
            ],
          }],
        }, {
          value: 17,
          label: "西北",
          children: [{
            value: 18,
            label: "陕西",
            children: [
              { value: 19, label: "西安" },
              { value: 20, label: "延安" },
            ],
          }, {
            value: 21,
            label: "新疆维吾尔族自治区",
            children: [
              { value: 22, label: "乌鲁木齐" },
              { value: 23, label: "克拉玛依" },
            ],
          }],
        }],
    };
  },

  methods:{
	handleChange(selectedList) {
	// 如果已经存在二级分类值,说明本次改变之前组件已经有值了
      if (this.oldMidVal) {
      // 本次选择了数据
        if (selectedList.length && selectedList.length > 0) {
        // 本次选择的数据是否含有不是旧二级分类下的值
          let hasOther = selectedList.some(item => item[1] !== this.oldMidVal);
          // 如果有不是旧二级分类下的值
          if (hasOther) {
          // 获取新的二级分类的值
            let otherVal = selectedList.find(item => item[1] !== this.oldMidVal)[1];
            let tempList = [];
            // 获取新二级分类下的本次选择的叶子节点
            this.cascadeList.forEach(item => {
              if (item[1] === otherVal) {
                tempList.push(item);
              }
            });
            // 更改组件绑定的值,保存新的二级分类值
            this.cascadeList = tempList;
            this.oldMidVal = otherVal;
          }
        } else {
        // 如果本次没有选择数据,直接清除之前记录的二级分类值
          this.oldMidVal = "";
        }
      } else {
      // 如果还没有二级分类的值,则直接保存本次的二级分类值即可
        this.oldMidVal = selectedList[0][1];
      }
    },
 }

说明

  • bug:后来发现有个小小的bug,当第一次选择,直接选择一级分类的时候,会将该一级分类下所有的二级分类都选中。
  • 局限:当前这个示例只能解决三联及以上数据的单选二级分类,其他数据类型或者业务要求并不适配;

bug优化

handleChange(selectedList) {
   if (this.oldMidVal) {
     if (selectedList.length && selectedList.length > 0) {
       let hasOther = selectedList.some(item => item[1] !== this.oldMidVal);
       if (hasOther) {
         let otherVal = selectedList.find(item => item[1] !== this.oldMidVal)[1];
         let tempList = [];
         this.cascadeList.forEach(item => {
           if (item[1] === otherVal) {
             tempList.push(item);
           }
         });
         this.cascadeList = tempList;
         this.oldMidVal = otherVal;
       }
     } else {
       this.oldMidVal = "";
     }
   } else {
     // 如果直接选择了一级分类可能会存在多个二级分类,便利只保留第一个二级分类
     let firstMidVal = selectedList[0][1];
     let tempList = [];
     this.cascadeList.forEach(item => {
       if (item[1] === firstMidVal) {
         tempList.push(item);
       }
     });
     this.cascadeList = tempList;
     this.oldMidVal = firstMidVal;
   }
},

总结

总得来说这个需求,只是古怪并不难。对于实现的进一步优化和扩容,比如支持指定二级分类个数,可配置限定的分类级别等就靠各位感兴趣的小伙伴了。


🎉完结撒花🎉 😁有用吗😁 👍点赞呀👍

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐