el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级

作者 : admin 本文共3894个字,预计阅读时间需要10分钟 发布时间: 2024-06-16 共1人阅读

多功能的 el-cascader

序言:最近遇到一个需求关于级联的,有点东西,这里是要获取某个产品类型下的产品,会存在产品类型和产品在同一级的情况,但是产品类型不能勾选;

  • 情况1(二级菜单是产品)
    el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级插图
  • 情况2(二级菜单也有可能是产品类型,三级是产品)
    el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级插图(1)

需求如下:

  1. 支持多选且保留最后勾选项(不包含父级)
  2. 自定义限制勾选数量(这里最多3个)
  3. 层级不固定,有子级的才可以点击
  4. 父级不能勾选
  5. 返回给后端的参数需要将最后勾选的子级的lable和value值转为字符串以逗号分隔

实现方式

  1. 支持多选可用:props="{ checkStrictly: true, label: 'name', emitPath: false, multiple: true }" multiple: true 实现;
    不包含父级: :show-all-levels="false"

  2. 限制数量这个就比较有趣了,因为官网上的limit在这里没有用,所以得自己去写,需要在数量超过3个的时候 再点下一个的时候替换掉上次勾选那个,3个以下就直接拿数据就行,因为勾选层级不固定,可以选不同层级的,所以需要用递归去获取勾选的值,下面是数据结构:
    el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级插图(2)

  3. 递归获取label值(最多3个,可修改):
    mainProductName:lable值 (字符串)
    mainProductOptions:级联的数据源
    findObjectsByKey:扁平化数组
    mainProductArr:value (数组字符串) 用来编辑时回显 很重要

    mainProductChange(val) {
      const textArr = [];
      if (val.length > 3) {
        val.splice(-2, 1);
        for (let i = 0; i < val.length; i++) {
          let itemValue = findObjectsByKey(this.mainProductOptions, 'id', val[i]);
          textArr.push(itemValue.name);
        }
        this.formData.mainProductName = textArr.join(',');
        this.$message.warning('最多只能选择三种产品');
        return val;
      } else {
        for (let i = 0; i < val.length; i++) {
          let itemValue = findObjectsByKey(this.mainProductOptions, 'id', val[i]);
          textArr.push(itemValue.name);
        }
        this.formData.mainProductName = textArr.join(',');
      }
      this.formData.mainProductArr = val;
    },
    
    //查找多层数组中的符合条件的item
    //arr 被查找的数组  key 查找的key  keyValue 查找的值
    export function findObjectsByKey(arr, key, keyValue) {
      //先把数组扁平化
      function flatten(arr, newarr) {
        //遍历arr数组
        for (var i = 0; i < arr.length; i++) {
          if (arr[i].children instanceof Array) {
            flatten(arr[i].children, newarr);
          } else {
            newarr.push(arr[i]);
          }
        }
        //返回新数组
        return newarr;
      }
      let newArr = flatten(arr, []);
      let itemValue = {};
      for (let item of newArr) {
        if (item[key] == keyValue) {
          itemValue = item;
          return itemValue;
        }
      }
      return itemValue;
    }
    
  4. 不能勾选是产品类型的父级(这里就需要对数据源做个处理),给是产品类型的数据加上 disabled,这时候就需要一个字段来判断了,后端配合一下,我这里用的是(isVariety)方法如下:

     traverseArray(arr) {
          arr.forEach(item => {
            item.disabled = item.isVariety == 0 ? true : false;
            item.value = item.id;
            if (item.children && item.children.length > 0) {
              this.traverseArray(item.children);
            }
          });
        },
    

    为了不修改源数据,所以用一个变量暂存一下

    getIndustryVarietyList({ isVariety: '' }).then(res => {
    	        if (res.data.data.length > 0) {
    	          let temp = res.data.data;
    	          this.traverseArray(temp);
    	          this.mainProductOptions = temp;
    	        }
    	      });
    
  5. 级联代码如下:

 <el-form-item label="主营产品:" prop="mainProductArr">
      <el-cascader
         ref="cascaderArr"
            style="width: 100%"
             v-model="formData.mainProductArr"
             :options="mainProductOptions"
              show-all-levels="false"
              placeholder="最多选择三种产品"
              clearable
              @change="mainProductChange"
              :props="{ checkStrictly: true, label: 'name', emitPath: false, multiple: true }"
                ></el-cascader>
              </el-form-item>
  1. 最后源码
	<template>
<div>
<el-form :model="formData" label-width="120px" :rules="formRules" ref="formData">
<el-col :span="10">
<el-form-item label="主营产品:" prop="mainProductArr">
<el-cascader
ref="cascaderArr"
style="width: 100%"
v-model="formData.mainProductArr"
:options="mainProductOptions"
:show-all-levels="false"
placeholder="最多选择三种产品"
clearable
@change="mainProductChange"
:props="{ checkStrictly: true, label: 'name', emitPath: false, multiple: true }"
></el-cascader>
</el-form-item>
</el-col>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
mainProductOptions: [],
// 表单数据
formData: {
mainProduct: '',
mainProductArr: [],
mainProductName: '',
},
};
},
created() {},
watch: {},
mounted() {
getIndustryVarietyList({ isVariety: '' }).then(res => {
if (res.data.data.length > 0) {
let temp = res.data.data;
this.traverseArray(temp);
this.mainProductOptions = temp;
}
});
},
methods: {
mainProductChange(val) {
const textArr = [];
if (val.length > 3) {
val.splice(-2, 1);
for (let i = 0; i < val.length; i++) {
let itemValue = findObjectsByKey(this.mainProductOptions, 'id', val[i]);
textArr.push(itemValue.name);
}
this.formData.mainProductName = textArr.join(',');
this.$message.warning('最多只能选择三种产品');
return val;
} else {
for (let i = 0; i < val.length; i++) {
let itemValue = findObjectsByKey(this.mainProductOptions, 'id', val[i]);
textArr.push(itemValue.name);
}
this.formData.mainProductName = textArr.join(',');
}
this.formData.mainProductArr = val;
},
traverseArray(arr) {
arr.forEach(item => {
item.disabled = item.isVariety == 0 ? true : false;
item.value = item.id;
if (item.children && item.children.length > 0) {
this.traverseArray(item.children);
}
});
},
},
};

还有个不足就是不能把含有children的勾选框给去掉,有知道的大佬告诉教教我

el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级插图(3)

本站无任何商业行为
个人在线分享-虚灵IT资料分享 » el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级
E-->