el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中

这篇具有很好参考价值的文章主要介绍了el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

需求描述

1.实现动态加载选项

2.数据回显

3.组件BUG:再次编辑不再加载

4.点击单选框选中节点时,同时加载下一级选项(额外需求)

5.点击label标签时,能够直接选中该节点(额外需求)


需求描述

需求情景描述

前端使用el-cascader组件来实现一个层级选择器,可以支持单选或多选节点,节点的层级关系和名称都由后端来定义和控制,前端根据后端提供的数据来渲染。

实现该需求,需要后端配合需要提供2个接口:

1.接口1:前端传入指定节点ID,后端返回该节点的下一层所有节点ID信息列表。

2.接口2:前端传入指定节点ID,后端返回该节点从顶部父节点至该节点的所有路径节点ID列表。

级联选择器 el-cascader 使用

最关键的只有这两项:v-model绑定值 和 props 配置项

<el-cascader
	v-model="IdList"
	:props="props"
></el-cascader>

1.实现动态加载选项

常用props配置:

动态加载选项不需要 : options 配置,一般静态的才使用options配置。

  • checkStrictly:true  是否可以选择树干节点作为选项(根据实际需求选择)
  • lazy:true  是否动态加载节点(当然,这正是我们需要的)
  • lazyLoad: this.loadTreeNode 指定加载节点的方法,这里我定义的名字叫loadTreeNode
  • multiple: true  是否支持多选
props: {
    checkStrictly: true, //是否可以选择树干节点作为选项
    lazy: true, // 是否动态加载子节点
    // lazyLoad加载动态数据的方法(仅在 lazy 为 true 时有效)
    lazyLoad: this.loadTreeNode,
},

loadTreeNode ,自定义的加载节点的方法具体逻辑看注释基本就能看明白):

//加载树节点  首次加载页面时就会执行一次,之后每选中一个节点也会调用,来渲染下一层
loadTreeNode(node, resolve) {
    console.log(node);
    // 首次加载时 node为{root:true,level:0}
    // node 节点数据  获取node的level字段的值
    const { level } = node;
    //下一层节点
    const nodes = [];
    //如果有子节点 或者 为根节点(即首次进入level为0)
    //也有人写成 node.level == 0 作用是一样的 
    if (node.hasChildren || node.root) {
        // 0 代表第一次请求
        let nodeId = level == 0 ? null : node.value;
        //这里setTimeout的目的是 显示加载动画
        setTimeout(() => {
            //调用后端接口 获得返回数据
            let ret = this.api(nodeId);
            if (ret && ret.succeeded) {
                //ret.reulst为后端返回的数据
                let nodes = ret.result;
                // 回调渲染下一层
                resolve(nodes);
            } else {
                //后端报错 弹窗提示失败
                this.$message({
                    type: "error",
                    message: "部门层级加载失败,请联系管理员!",
                });
            }
        }, 1);
    } else {
        //如果没有子节点就不发起请求,直接渲染,也避免了点击叶子节点仍然有加载动画的问题
        resolve(nodes);
    }
},

叶子节点 —— 意思是:没有子节点的节点,它就是最底层。

其中 this.api 指的是调用后端提供的第一个接口

接口1:前端传入指定节点ID,返回该节点的下一层所有节点ID信息列表(当nodeId为空时,返回第一层节点)。

返回的数据需要是一个列表,后端返回的数据 List<UserGroupTreeNode> 大概长这样:

el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中

JAVA后端的节点定义可参考:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserGroupTreeNode {
    /**
     * 节点值
     */
    private String value;
    /**
     * 节点标签
     */
    private String label;
    /**
     * 是否为叶子节点(即没有子节点)  true 没有子节点 false 有子节点
     */
    private Boolean leaf;
}

其中value即为节点的ID,label为展示的名称,leaf为是否含有子节点,Bool类型。

value,label,leaf 变量名务必保持一致,否则前端拿到数据之后,得自己转成这个变量名。

(或者指定一下变量名称也行,具体参考element-ui官方文档。)

到这里,这个组件已经可以实现新增保存的操作了。

2.数据回显

问题描述

上面已经解决了层级选择器的数据渲染问题,用来做查询条件筛选或者新增都已经够了。但是当我们需要修改数据时,点击修改打开的弹窗中对应的字段无法正确回显。

预想中的效果应该是:它应该逐层展示,并且点击它想要修改时,层级选择器组件应该默认选中绑定的值。

目前实际的效果却是:打开后,数据虽然对应上了,但是菜单并没有自动展开,要重新一层一层手动去选择展开,才能看到选中的数据,这显然不符合实际需求

解决思路:

1.首先,我们在新增数据时,级联选择器v-model绑定的参数是一个列表,

例如:我们选中【sub-1-2-3】这个节点时,

它实际绑定的值是:["root","sub-1","sub-1-2","sub-1-2-3"]。

而后端实际保存的值一般都是选中节点的id,即"sub-1-2-3"。

2.已知el-cascader组件绑定的值是一个列表,所以当我们需要正确回显,也需要给它赋值一个数组才行。

所以我们需要与后端约定的第二个接口

接口2:前端传入指定节点ID,后端返回该节点从顶部父节点至该节点的所有路径节点ID列表。

格式如下图,需要特别注意的是顺序需要和实际节点层级顺序一致!

el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中

这里返回的是节点的ID数组列表,

前端拿到它后,直接赋值给 el-cascader 组件v-model绑定的变量即可。

然后就可以正常显示啦!

el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中

这样就处理完成了,但是还有一个问题,应该算是element-ui的BUG。

3.组件BUG:再次编辑不再加载

问题情景描述

按照前面的实现后,如果需求是做增删改查,只要涉及到修改,自然需要点击编辑按钮时,在页面中数据回显,才能编辑。但是只有在首次加载页面后,编辑数据A时,数据A回显一切正常,之后关闭弹窗,再编辑其他数据,此时的修改弹窗中el-cascader 组件文本框中,回显都为空,不再正常回显了。

分析原因:

首次编辑数据时,el-cascader 会根据v-model绑定的参数值,

比如["1","2","3","4"] 这个数组

逐层调用lazyLoad获取整个树结构

即:依次将 "1","2","3","4"作为参数,调用lazyLoad,分别渲染头结点"1",头结点下一层,ID为节点"2"的下一层,以及下一层中,ID为“3”的下一层,最后整个合并起来。

整个过程是组件自动完成的。

所以能正确回显。

但是当关闭编辑弹窗,再编辑其他数据时,虽然el-cascader 组件v-model绑定的参数值发生了变化,但是没有再触发调用lazyLoad方法再逐层请求后端渲染整个结构树。

目前网上的解决办法总体有两种思路:

  • 1.给el-cascader组件绑定 options选项,根据v-model绑定参数的值,也就是数组的值,手动调用后端接口,逐个获取下一层的选项,拼接成树结构,将生成树结构给 el-cascader 使用,这样就能正确回显。这种思路其实本质上就是自己写lazyLoad的逻辑,放弃使用官方提供的lazyLoad方法(不推荐)。
  • 2.将 el-cascader 组件 重新渲染一次,既然首次加载的时候能正确调用lazyLoad,那每次都重新来,都当成首次加载就好了,这就是用v-if解决的思路(推荐)。

方法1实现起来太复杂,方法二简单很多,推荐使用方法2。

方法2具体实现:

给 el-cascader组件 加上   v-if="editCascaderVisible" 

<el-cascader
	v-if="editCascaderVisible"
	v-model="IdList"
	:props="props"
></el-cascader>

然后在editRow,即打开修改弹窗方法时,手动控制它刷新一次:

关键代码:

	this.editCascaderVisible = false;
	// 这里搞个定时器重新载入一下组件就可以触发组件拉取数据
	setTimeout(() => {
		this.editCascaderVisible = true;
	}, 1);

完整代码:

editRow(rowData) {

	this.editCascaderVisible = false;
	// 这里搞个定时器重新载入一下组件就可以触发组件拉取数据
	setTimeout(() => {
		this.editCascaderVisible = true;
	}, 1);

	this.IdList= [];
	//在编辑的时候等到DOM更新完成再赋值
	this.$nextTick(() => {
        //将选中数据的值 赋值给表单
		this.dataForm = Object.assign({}, rowData);
	});
    //调用后端接口,获取自顶向下逐个层级ID的列表  这里我el-cascader绑定的变量是IdList
	this.IdList= this.api_getIdList(rowData.groupId);
    //打开修改弹窗
	this.dialogVisible = true;
}

这样每次点击编辑的时候,就都能正确回显了。

另外希望element-ui官方能修复这个问题,这样我们也不用折腾了。

4.点击单选框选中节点时,同时加载下一级选项(额外需求)

需求情景描述

当我们直接点击【万州支行】标签左侧的单选框时,只执行了选中操作,此时不会加载【万州支行】的下属机构,但是实际使用时,我们在点击选中时,又想看到下一级的机构选项怎么办?

如下图所示,因为我们使用的是lazyLoad模式,点击单选框选中时,不会触发加载下一级选项:

el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中

解决思路:已知:当选中的节点发生变化时,就会触发change方法,而我们点击选项文字标签(即label)时,组件就会触发加载下一级节点。所以:我们可以在change方法内,模拟点击文字标签,即可解决这个问题。

由于在页面布局上,单选框radio的同级下一个元素,就是label,所以用dom去获取它的同级下一个元素,再手动执行一次click事件即可。

 实现代码:

<el-cascader
	@change="handleChange"
	v-if="editCascaderVisible"
	v-model="IdList"
	:props="props"
></el-cascader>
//处理单选点击事件
handleChange(e) {
	this.$nextTick(() => {
		const dom = document.getElementsByClassName("el-radio is-checked");
		//这里我把dom打出来看了 最后一个选项才是我选中的节点 即[length-1] 有的博主写的是 第一个元素 即[0] 大家自行尝试
		let radioDom = dom[dom.length - 1];
		const brother = radioDom.nextElementSibling;
		brother.click();
	});
},

5.点击label标签时,能够直接选中该节点(额外需求)

需求情景描述

单选的情况下,要选中某个节点选项,需要点击radio按钮,而radio本身很小,所以它的的可点击区域也很小,想直接点中它,还得眼神好一点才行,不太方便,如果能点击标签页直接选中它就好了。

解决思路:既然点击区域很小,那就用css把它本体放大就好了。把单选框的范围放大到整个标签范围,点击标签相当于点单选框。

实现代码:

<style>
/*单选的级联选择器,点击标签页就可以选中*/
.el-cascader-menu .el-radio {
    display: table;
    vertical-align: middle;
    width: 100%;
    height: 100%;
    position: absolute;
    box-sizing: border-box;
    margin-left: -25px;
    padding-left: 15px;
    margin-top: 6px;
}
.el-cascader-menu .el-radio .el-radio__input {
    display: table-cell;
    vertical-align: middle;
}
</style>



如果对你有帮助,还请点赞支持 ~

记录一下解决过程中对 el-cascader 组件的其他认识:

<el-cascader
	ref="editCascader"
	v-model="departmentIdList"
	:props="propsSearch"
	placeholder="请选择业务部门"
	style="width: 15vw"
></el-cascader>

加入ref,可以使用

this.$refs.editCascader.panel

获取到 el-cascader 对象

可以使用

this.$refs.editCascader.panel.lazyLoad(cqbankNode);

 主动调用lazyLoad绑定的方法,传入的节点要有chidren字段,或者直接取自

let cqbankNode = this.$refs.editCascader.panel.menus[0][0];

menus是菜单项

menus[0]即第一个下拉框列表,

menus[1]即第二个下拉框列表,可以通过修改menus,修改下拉框展示列。

但是根据 menus[0][0] 去获取,有时候节点children为空,可能应该换一个属性去获取,这个思路应该也能做,当时是取值属性来源错了,为空就写不下去了就换思路了。文章来源地址https://www.toymoban.com/news/detail-467309.html

到了这里,关于el-cascader 动态加载选项、编辑时数据回显问题 、单选不加载下一级节点、点击标签选中的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • element ui cascader级联选择器 动态加载以及回显

    当数据比较多的时候,一次性获取全部数据速度太慢,而且体验不太好,所有需要用到懒加载,一级一级的选择数据就能很好避免速度慢的问题。 以及我们使用el-cascader加载默认值的时候,cascader的输入框和联级选择框都会遇到的回显问题。看代码!!! 参数说明: value / v-model 选中

    2024年02月15日
    浏览(63)
  • el-cascader级联选择器那些事

    vue3+element-plus+ts 使用cascader组件提供的getCheckedNodes()

    2024年02月16日
    浏览(44)
  • 更改el-cascade默认的value和label的键值

      后端返回的树结构中,label的key不是el-cascade默认的label,我需要改成对应的字段,但是一直没有成功,我也在文档中找到了说明,但是我没注意这是在props中改,导致一直不成功 这是我一开始错误的写法: 这是正确的写法: 

    2024年04月17日
    浏览(34)
  • vue+element UI 使用el-cascader实现全选功能

    实现效果图     使用el-cascader代码片段 js代码 data数据设置: // 这里是处理成自己需要的数据格式, 需要把全选的这一选项过滤掉 // 原始选择的数据格式 [[\\\'全选\\\'], [1, 2], [1, 3], [1, 4],[5, 6], [5, 7, 8],5, 7, 9],[10]] //因为我自己需要的数据是“2,3,4,5”的格式,做了以下处理 注:本文是

    2024年02月12日
    浏览(51)
  • element ui 层级选择器el-cascader只能选最后一级多选

    在element ui 中el-cascader多选: 每个层级都可以选择,但并不是我需要的,我需要多选只能选最后一级,在网上找了很久都复杂的,最终自己选择用css样式对checkbox进行隐藏。 实现方法: 在css 中加入 关键点在于利用属性选择器,遇到属性是 aria-haspopup (表示点击的时候是否会

    2024年02月11日
    浏览(86)
  • [element-ui] 级联选择器el-cascader不触发change事件

    el-cascader 使用官网的数据是可以的 官网数据中最后一级没有children 就可以了 参考: elementui级联选择器Cascader不触发change事件

    2024年01月23日
    浏览(40)
  • element 的 el-cascader 组件获取级联选中label和value值

    1.  多选时  获取 cascader 级联选择器的 label 值         需要给 el-cascader 加 ref 用以获取值  获取后的样式 2. 单选时获取 cascader 级联选择器的值     

    2024年02月12日
    浏览(58)
  • ElementPlus el-cascader级联选择器 实现一级菜单单选,二级菜单多选

    需求: 利用el-cascader级联实现一级菜单单选,二级菜单多选的功能,如下图所示: 思路: 使用了多选multiply属性,这个属性下,选中的数据结构为:一级为length1的数组,二级为length2的数组。利用标识符,把最后选中的一级菜单的值与标识符做对比,如不同,则让标识符的值

    2024年02月11日
    浏览(48)
  • element-ui el-cascader级联选择器设置指定层级不能选中(示例代码)

    本文为转载原地址:https://www.136.la/shida/show-396330.html 有时候用element-ui el-cascader级联选择器添加分类时会遇到最多添加几级的限定.看了文档,只要给需要禁止选择的选项添加disabled属性就可以.但是使用一层一层循环遍历数据感觉很麻烦,自己写了个遍历的方法,纪录下,方便以后使

    2024年02月11日
    浏览(52)
  • Element UI 中使用el-cascader组件,可以选择任意一级的内容并取消单选框

    当加入checkStrictly后就会出现单选框的问题,修改样式即可;这里使用的less语法,需要有less依赖,加入样式后如果没有生效,可以放在App.vue中的样式下

    2024年02月04日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包