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

2024-06-14 22:20

本文主要是介绍el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

多功能的 el-cascader

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

  • 情况1(二级菜单是产品)
    在这里插入图片描述
  • 情况2(二级菜单也有可能是产品类型,三级是产品)
    在这里插入图片描述

需求如下:

  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个以下就直接拿数据就行,因为勾选层级不固定,可以选不同层级的,所以需要用递归去获取勾选的值,下面是数据结构:
    在这里插入图片描述

  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-cascaderref="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-cascaderref="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 支持多层级,多选(可自定义限制数量),保留最后一级的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061657

相关文章

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

(超详细)YOLOV7改进-Soft-NMS(支持多种IoU变种选择)

1.在until/general.py文件最后加上下面代码 2.在general.py里面找到这代码,修改这两个地方 3.之后直接运行即可

ROS话题通信流程自定义数据格式

ROS话题通信流程自定义数据格式 需求流程实现步骤定义msg文件编辑配置文件编译 在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如:

vue+el国际化-东抄西鉴组合拳

vue-i18n 国际化参考 https://blog.csdn.net/zuorishu/article/details/81708585 说得比较详细。 另外做点补充,比如这里cn下的可以以项目模块加公共模块来细分。 import zhLocale from 'element-ui/lib/locale/lang/zh-CN' //引入element语言包const cn = {mess

力扣SQL50 每位经理的下属员工数量 join

Problem: 1731. 每位经理的下属员工数量 👨‍🏫 参考题解 Code select m.Employee_id, m.name,count(*) reports_count,round(avg(e.age),0) average_agefrom Employees ejoin Employees mon e.reports_to = m.Employee_id

添加自定义的CALayer

iOS开发UI篇—CAlayer(创建图层) 一、添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控制器view的layer上)  1 // 2 // YYViewController.m 3 // 01-创建一个简单的图层 4 // 5 //

el-upload 上传图片及回显照片和预览图片,文件流和http线上链接格式操作

<div v-for="(info, index) in zsjzqwhxqList.helicopterTourInfoList" :key="info.id" >编辑上传图片// oss返回线上地址http链接格式:<el-form-itemlabel="巡视结果照片":label-width="formLabelWidth"><el-upload:action="'http:

android自定义View的和FramgentActivity的一个小坑

对于自定义View //加载样式TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBarView, defStyleAttr, 0);setTitle(typedArray.getString(R.styleable.TitleBarView_main_title));//不能写成

第三十七章 添加和使用自定义标题元素 - 自定义标头的继承

文章目录 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承自定义标头的继承示例 在 `SOAPHEADERS` 参数中指定支持的标头元素自定义标头的继承 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承 自定义标头的继承 如果创建此Web 服务的子类,该子类将继承不特定于方法的标头信息 — 包含在 <request> 或 <response> 元素中的标头信

【MyBatis学习7】MyBatis中的一级缓存

缓存的作用是减轻数据库的压力,提高数据库的性能的。mybatis中提供了一级缓存和二级缓存,先来看一下两个缓存的示意图:    从图中可以看出: 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。二级缓存是mappe