最近有个功能需要用到级联相关的操作,再element上看到有相关组件,就直接拿来用了
https://element.eleme.cn/#/zh-CN/component/cascader
<el-cascader-panel :options="options"></el-cascader-panel>
但是官方文档上给的方法和属性也不是很全面,只有简单的操作,像其他手动操作的方法以及展开,回显等操作均没有展示
下面将该组件的一些用法总结一下:
首先我们需要阅读下源码:
https://github.com/ElemeFE/element/tree/dev/packages/cascader-panel/src
很多操作看源码就能很清楚的找到
首先我们使用该组件,并为其指定 ref,这样我们就能通过ref 调用组件的方法了
<el-cascader-panel ref="mycas2" :options="options2" :props="props" v-model="data2" @change="getData"></el-cascader-panel>
获取选中的节点,这个方法在文档上也有说明:
getCheckedNodes获取选中的节点数组 (leafOnly) 是否只是叶子节点,默认值为 false
this.$refs.mycas2.getCheckedNodes()// 包含选中的父节点 this.$refs.mycas2.getCheckedNodes(true)// 只有叶子节点
通过外部方法,选中或者取消选中节点,而不是直接点击节点选中,一般用于自定义需求以及回显。
首选我们得能取到目标节点,然后才能进行下一步操作,对于回显来说,你可以采用v-model 绑定的值回显,需要按照指定格式复制给model即可,我们不采用这种方式,我们直接找节点进行回显,我们有了值,需要根据该值查找节点,在源码里面我们可以找到这个方法
getNodeByValue(val) { return this.store.getNodeByValue(val); },
那我们也可以直接调用了
this.$refs.singleCascader.getNodeByValue(value)
找到节点如何进行选中操作呢,我们需要看下节点的源码
https://github.com/ElemeFE/element/blob/dev/packages/cascader-panel/src/node.js
源码如下
doCheck(checked) { if (this.checked !== checked) { if (this.config.checkStrictly) { this.checked = checked; } else { // bottom up to unify the calculation of the indeterminate state this.broadcast('check', checked); this.setCheckState(checked); this.emit('check'); } } }
我们就可以直接进行调用
this.$refs.singleCascader.getNodeByValue(value).doCheck(true) // 选中 this.$refs.singleCascader.getNodeByValue(value).doCheck(false) // 取消选中
但是我们发现做了上面操作之后,发现并没有生效,没有选中
又读了一下源码,发现 doCheck 之后,多选需要执行下 calculateMultiCheckedValue 方法,可以在清空所有选中节点的代码中看到
源码如下:
clearCheckedNodes() { const { config, leafOnly } = this; const { multiple, emitPath } = config; if (multiple) { this.getCheckedNodes(leafOnly) .filter(node => !node.isDisabled) .forEach(node => node.doCheck(false)); this.calculateMultiCheckedValue(); } else { this.checkedValue = emitPath ? [] : null; } }
于是我们还需要如下操作:
this.$refs.mycas2.calculateMultiCheckedValue()
通过外部方法选中或者取消选中,思路与上面类似,需要找到该节点或者有该节点的值即可
然后就是自动展开功能,展开到某个层级,源码中看到有展开所有节点的方法
expandNodes(nodes) { nodes.forEach(node => this.handleExpand(node, true /* silent */)); },
如果展开到某个节点我们可以直接
this.$refs.mycas2.handleExpand(node,true)
如果是初始加载就展开,可以如下设置,自己根据层级展开即可
if(this.$refs.mycas2){ this.$nextTick(()=>{ let caspanel=this.$refs.mycas2 let node= caspanel.menus[0] caspanel.handleExpand(node,true) caspanel.handleExpand(node[0],true) }) }
清除所有选中节点,官方文档也已经写清楚了
this.$refs.mycas2.clearCheckedNodes()
示例代码如下:
<template> <div> <div> <span class="demonstration">测试</span> <el-button style="margin-left:10px" size="mini" type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> <el-button size="mini" type="" icon="el-icon-refresh" @click="handleReset">重置</el-button> <div> <span>已选择:{{dataClasses2.length}}人</span> <el-tag v-for="(item,index) in dataClasses2" :key="index" closable="" @close="closeTag(item)">{{item.label}}</el-tag> </div> <el-cascader-panel ref="mycas2" :options="options2" :props="props" v-model="data2" @change="getData" v-show="showEl"></el-cascader-panel> <el-checkbox-group v-model="checkList" v-show="!showEl"> <el-checkbox v-for="(item,index) in stuList" :key="index" :label="item.id" :value="item.id" @change="selectBox(item,$event)">{{item.name}}</el-checkbox> </el-checkbox-group> </div> </div> </template> <script> export default { data() { return { props: { multiple: true }, dataClasses: [], checkList: [], data2: [], dataClasses2: [], stuList: [ { id: 211, name: "小黄", }, { id: 212, name: "小z", }, { id: 213, name: "小z", }, ], showEl: true, options2: [ { value: "1", label: "一年级", children: [ { value: 11, label: "一班", children: [ { value: 111, label: "小明", }, { value: 112, label: "小红", }, { value: 113, label: "小率", }, { value: 114, label: "小栏", }, { value: 115, label: "小子", }, { value: 116, label: "小白", }, { value: 117, label: "小嘿", }, ], }, { value: 12, label: "二班", children: [ { value: 211, label: "小1", }, { value: 212, label: "小2", }, { value: 213, label: "小3", }, { value: 214, label: "小4", }, { value: 215, label: "小5", }, { value: 216, label: "小6", }, { value: 217, label: "小7", }, ], }, { value: 13, label: "三班", }, { value: 14, label: "四班", }, ], }, { value: "2", label: "二年级", children: [ { value: 21, label: "一班", }, { value: 22, label: "二班", }, { value: 23, label: "三班", }, { value: 24, label: "四班", }, ], }, { value: "3", label: "三年级", }, ], }; }, created() { // 初始化展开 this.$nextTick(() => { let node = this.$refs.mycas2.menus[0]; this.$refs.mycas2.handleExpand(node, true); this.$refs.mycas2.handleExpand(node[0], true); this.$refs.mycas2.handleExpand(node[0].children[0], true); }); }, methods: { // 关闭标签时,取消节点的选择 closeTag(item) { console.log(item); item.doCheck(false); this.$refs.mycas2.calculateMultiCheckedValue(); }, // 获取选择的叶子节点,根据层级过滤 getData() { this.dataClasses2 = this.$refs.mycas2 .getCheckedNodes() .filter((n) => n.level == 3); }, // 查询 handleQuery() { this.showEl = false; }, // 重置 handleReset() { this.showEl = true; }, // 外部选择或者取消 selectBox(item, value) { this.$refs.mycas2.getNodeByValue(item.id).doCheck(value); this.$refs.mycas2.calculateMultiCheckedValue(); }, }, }; </script> <style scoped> </style>