VUEel-tree组件左边勾选,右边清除交互问题
短信预约 -IT技能 免费直播动态提醒
el-tree组件左边勾选,右边清除交互
需求
使用el-tree组件,左边可以勾选节点,右边展示已经勾选的节点。
效果
代码实现
<template>
<div class="treeWrapper">
<div class="leftView">
<el-input placeholder="请输入内容" v-if="relationTree.length" v-model="filterTreeName" @change="filterChange"/>
<el-checkbox v-if="relationTree.length" class="select-box" v-model="menuNodeAll"
@change="handleCheckedTreeNodeAll($event)">全选
</el-checkbox>
<el-tree :data="relationTree" show-checkbox node-key="id" ref="tree" :props="defaultProps" @check="hanldTreeCheck"
default-expand-all :filter-node-method="filterNode" :default-checked-keys="checkedKeys">
</el-tree>
</div>
<div class="rightView">
<header>
<span>已选择 {{ checkList.length }} 个</span>
<span @click="removeRightTreeAll">全部清除</span>
</header>
<div class="checkedItem" v-if="checkList.length">
<li v-for="(m, i) in checkList" :class="['align-center','justify-between',m.checkFlag ? 'mark':'']" :key="i">
<p>{{ m.name }}</p>
<svg-icon icon-class="deleteTreeItem" @click="tagClose(m, i)"/>
</li>
</div>
<div class="right-nodata f_c_m" v-else>暂无数据</div>
</div>
</div>
</template>
<script>
export default {
name: "baseTree",
props: {
relationTree: {
type: Array,
default: () => [],
},
checkedKeys: {
type: Array,
default: () => [],
},
},
data() {
return {
filterTreeName: "",
menuNodeAll: false,
defaultProps: {
children: "relationResps",
label: "name",
},
// 选中机器人
checkList: [],
checkDataList: [],
};
},
mounted() {},
methods: {
filterNode(value, data) {
if (!value) {
return true;
}
return data.name.includes(value);
},
// 过滤
filterChange() {
this.$refs.tree.filter(this.filterTreeName);
},
// 全部清除
removeRightTreeAll() {
this.checkList = [];
if (this.menuNodeAll) {
this.menuNodeAll = !this.menuNodeAll;
}
const parentCheckedLength = this.$refs.tree.getCheckedKeys().length;
if (parentCheckedLength !== 0) {
this.$refs.tree.setCheckedNodes([]);
}
this.checkDataList = [];
this.$emit("treeclick", this.checkDataList);
},
// 全选
handleCheckedTreeNodeAll(data) {
if (this.menuNodeAll) {
//如果是当前值是全选,依次遍历节点设置勾选,同时过滤的disabled为true的
// 深度遍历
let stack = [...this.relationTree],
node;
while ((node = stack.shift())) {
console.log(node.id);
this.$refs.tree.setChecked(node.id, true, true);
// 如果有子元素的话进行压栈操作
if (node.children) stack.unshift(...node.children);
this.checkList = this.$refs.tree.getCheckedNodes(true, false);
this.hanldTreeCheck(this.$refs.tree.getCheckedNodes(this.checkList));
}
} else {
//当前值不是全选,设置勾选列表为空
this.$refs.tree.setCheckedKeys([]);
this.checkList = [];
this.$emit("treeclick", this.checkList);
}
},
// 当tree 复选框被点击的时候触发
hanldTreeCheck(data) {
const childNodeList = this.$refs.tree.getCheckedNodes(true, false);
this.checkList = childNodeList;
this.checkDataList =
(childNodeList.length &&
childNodeList.map((instance) => {
// 机器人
const {
id: equipmentId,
name: equipmentName,
parentId: instanceParentId,
checkFlag: checkFlag,
} = instance;
// 门店
const {
id: storeId,
name: storeName,
parentId: instanceStoreParentId,
} = this.$refs.tree.getNode(instanceParentId).data;
// 公司
const {id: companyId, name: companyName} =
this.$refs.tree.getNode(instanceStoreParentId).data;
return {
storeId,
storeName,
equipmentId,
equipmentName,
companyId,
companyName,
checkFlag,
};
})) ||
[];
this.$emit("treeclick", this.checkDataList);
},
// 右侧组件点击“关闭”按钮触发
tagClose(item, index) {
// 在已选中项的下标中删除
this.checkList.splice(index, 1);
if (this.checkDataList.length) {
this.checkDataList.splice(index, 1);
this.$emit("treeclick", this.checkDataList);
}
// 在tree树控件中更改选中状态.
//setChecked 接收三个参数,1. 勾选节点的 key 或者 data 2. boolean 类型,节点是否选中 3. boolean 类型,是否设置子节点 ,默认为 false
this.$refs.tree.setChecked(item.id, false, true);
// 重新计算已选中树形节点
this.hanldTreeCheck();
},
},
};
</script>
<style lang="scss" scoped>
.treeWrapper {
overflow: hidden;
display: grid;
grid-template-columns: 50% 50%;
grid-auto-rows: 336px;
margin: 10px auto;
width: 100%;
border-radius: 6px;
border: 1px solid #dbdbdb;
.leftView {
display: flex;
flex-direction: column;
.el-tree {
height: 100%;
}
.select-box {
display: flex;
justify-content: space-between;
flex-direction: row-reverse;
margin-top: 10px;
padding: 0 18px 0 10px;
.el-checkbox__label {
font-size: 10px;
font-weight: bold;
color: #222222;
}
}
.el-input {
margin: 10px auto 0;
width: 85% !important;
}
.el-tree {
border: none !important;
overflow: overlay;
.el-tree-node__content {
padding-right: 10px !important;
.el-checkbox {
order: 2;
flex: 1;
text-align: right;
}
.custom-tree-node {
order: 1;
> span {
display: block;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
> .el-tree-node > .el-tree-node__content {
padding-left: 10px !important;
}
}
}
.rightView {
position: relative;
display: flex;
flex-direction: column;
padding: 0 0 0 18px;
border-left: 1px solid #dbdbdb;
> header {
display: flex;
justify-content: space-between;
margin: 16px 0 12px 0;
padding-right: 10px;
font-size: 10px;
> span:nth-child(1) {
color: #222222;
}
> span:nth-child(2) {
color: #592c82;
cursor: pointer;
}
}
.checkedItem {
height: 100%;
overflow: overlay;
> li {
height: 26px;
margin-right: 18px;
}
.mark {
color: red;
}
}
}
.right-nodata {
color: #909399;
position: absolute;
left: 50%;
top: 60%;
transform: translate(-50%, -50%);
}
}
</style>
vue el-tree延时过滤
最近做了一个项目,把SQL服务器,数据库,表的结构呈现在el-tree内,以便作数据表和字段的描述维护。
el-tree获取数据库数据,前端呈现分层后,如何快速的找出一个节点,根据饿了么官方文档,el-tree有一个过滤的功能。 :filter-node-method=”filterNode”。
但是此功能在input输入框每次输入一个字符就会立即过滤整个树形结构,导致需要过滤的字符还没有输入完毕,el-tree已经过滤了很多遍,造成卡顿的现象。
比如要在树形结构中过滤包含字符为“Test”的节点,输入T后el-tree就会立即过滤包含T的数据,输入e后第二次过滤包含Te的数据,输入Tes后第三次过滤包含Tes的数据,输入完Test后是第四次过滤。
为此,需要在input输入过滤的同时,在watch内增加延时功能。
<div class="treeheight" style="float:left;overflow:auto;width:30%;border:1px solid">
<el-input :placeholder="this.$t('SQLTreemanage.filterboxdefault')" v-model="filterText"></el-input>
<el-tree
:props="props1"
:load="loadNode1"
@node-click="handlenodeclick"
:lazy="true"
:filter-node-method="filterNode"
:render-content="renderContent"
ref="tree2"
:expand-on-click-node="false"
>
</el-tree>
</div>
const debounce = (function () {
let timer = 0
return function (func, delay) {
clearTimeout(timer)
timer = setTimeout(func, delay)
}
})()
export default {
data () {
filterText: ''
}
}
watch: {
filterText (val) {
debounce(() => {
this.$refs.tree2.filter(val)
}, 1000);
}
通过延时过滤的功能,在input输入字符后,可在设置的延时时间1000(1秒)后进行过滤,减少了整个el-tree过滤的次数。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341