最近有个功能需要用到级联相关的操作,再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>