VUE el-tree組件左邊勾選,右邊清除交互問(wèn)題
el-tree組件左邊勾選,右邊清除交互
需求
使用el-tree組件,左邊可以勾選節(jié)點(diǎn),右邊展示已經(jīng)勾選的節(jié)點(diǎn)。
效果

代碼實(shí)現(xiàn)
<template>
<div class="treeWrapper">
<div class="leftView">
<el-input placeholder="請(qǐng)輸入內(nèi)容" 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 }} 個(gè)</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>暫無(wú)數(shù)據(jù)</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",
},
// 選中機(jī)器人
checkList: [],
checkDataList: [],
};
},
mounted() {},
methods: {
filterNode(value, data) {
if (!value) {
return true;
}
return data.name.includes(value);
},
// 過(guò)濾
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) {
//如果是當(dāng)前值是全選,依次遍歷節(jié)點(diǎn)設(shè)置勾選,同時(shí)過(guò)濾的disabled為true的
// 深度遍歷
let stack = [...this.relationTree],
node;
while ((node = stack.shift())) {
console.log(node.id);
this.$refs.tree.setChecked(node.id, true, true);
// 如果有子元素的話進(jìn)行壓棧操作
if (node.children) stack.unshift(...node.children);
this.checkList = this.$refs.tree.getCheckedNodes(true, false);
this.hanldTreeCheck(this.$refs.tree.getCheckedNodes(this.checkList));
}
} else {
//當(dāng)前值不是全選,設(shè)置勾選列表為空
this.$refs.tree.setCheckedKeys([]);
this.checkList = [];
this.$emit("treeclick", this.checkList);
}
},
// 當(dāng)tree 復(fù)選框被點(diǎn)擊的時(shí)候觸發(fā)
hanldTreeCheck(data) {
const childNodeList = this.$refs.tree.getCheckedNodes(true, false);
this.checkList = childNodeList;
this.checkDataList =
(childNodeList.length &&
childNodeList.map((instance) => {
// 機(jī)器人
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);
},
// 右側(cè)組件點(diǎn)擊“關(guān)閉”按鈕觸發(fā)
tagClose(item, index) {
// 在已選中項(xiàng)的下標(biāo)中刪除
this.checkList.splice(index, 1);
if (this.checkDataList.length) {
this.checkDataList.splice(index, 1);
this.$emit("treeclick", this.checkDataList);
}
// 在tree樹(shù)控件中更改選中狀態(tài).
//setChecked 接收三個(gè)參數(shù),1. 勾選節(jié)點(diǎn)的 key 或者 data 2. boolean 類型,節(jié)點(diǎn)是否選中 3. boolean 類型,是否設(shè)置子節(jié)點(diǎn) ,默認(rèn)為 false
this.$refs.tree.setChecked(item.id, false, true);
// 重新計(jì)算已選中樹(shù)形節(jié)點(diǎn)
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%;
/* height: 336px; */
border-radius: 6px;
border: 1px solid #dbdbdb;
.leftView {
display: flex;
flex-direction: column;
/* width: 100%; */
.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;
/* height: 100%; */
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 {
/* flex-basis: 50%; */
position: relative;
display: flex;
flex-direction: column;
padding: 0 0 0 18px;
/* width: 100%; */
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延時(shí)過(guò)濾
最近做了一個(gè)項(xiàng)目,把SQL服務(wù)器,數(shù)據(jù)庫(kù),表的結(jié)構(gòu)呈現(xiàn)在el-tree內(nèi),以便作數(shù)據(jù)表和字段的描述維護(hù)。

el-tree獲取數(shù)據(jù)庫(kù)數(shù)據(jù),前端呈現(xiàn)分層后,如何快速的找出一個(gè)節(jié)點(diǎn),根據(jù)餓了么官方文檔,el-tree有一個(gè)過(guò)濾的功能。 :filter-node-method=”filterNode”。
但是此功能在input輸入框每次輸入一個(gè)字符就會(huì)立即過(guò)濾整個(gè)樹(shù)形結(jié)構(gòu),導(dǎo)致需要過(guò)濾的字符還沒(méi)有輸入完畢,el-tree已經(jīng)過(guò)濾了很多遍,造成卡頓的現(xiàn)象。
比如要在樹(shù)形結(jié)構(gòu)中過(guò)濾包含字符為“Test”的節(jié)點(diǎn),輸入T后el-tree就會(huì)立即過(guò)濾包含T的數(shù)據(jù),輸入e后第二次過(guò)濾包含Te的數(shù)據(jù),輸入Tes后第三次過(guò)濾包含Tes的數(shù)據(jù),輸入完Test后是第四次過(guò)濾。
為此,需要在input輸入過(guò)濾的同時(shí),在watch內(nèi)增加延時(shí)功能。
<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);
}通過(guò)延時(shí)過(guò)濾的功能,在input輸入字符后,可在設(shè)置的延時(shí)時(shí)間1000(1秒)后進(jìn)行過(guò)濾,減少了整個(gè)el-tree過(guò)濾的次數(shù)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3?跨域配置devServer的參數(shù)和設(shè)置方法
這篇文章主要介紹了Vue3?跨域配置devServer的參數(shù)和設(shè)置,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
vue3?elmentPlus?table實(shí)現(xiàn)列寬可拖拽功能
這篇文章主要介紹了vue3?elmentPlus?table實(shí)現(xiàn)列寬可拖拽功能,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
在Vue項(xiàng)目中,防止頁(yè)面被縮放和放大示例
今天小編就為大家分享一篇在Vue項(xiàng)目中,防止頁(yè)面被縮放和放大示例,具有很好的參考 價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
vue:axios請(qǐng)求本地json路徑錯(cuò)誤問(wèn)題及解決
這篇文章主要介紹了vue:axios請(qǐng)求本地json路徑錯(cuò)誤問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
vue刪除html內(nèi)容的標(biāo)簽樣式實(shí)例
今天小編就為大家分享一篇vue刪除html內(nèi)容的標(biāo)簽樣式實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue router動(dòng)態(tài)路由下讓每個(gè)子路由都是獨(dú)立組件的解決方案
這篇文章主要介紹了vue router動(dòng)態(tài)路由下讓每個(gè)子路由都是獨(dú)立組件的解決方案,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-04-04
vue 項(xiàng)目打包時(shí)樣式及背景圖片路徑找不到的解決方式
今天小編就為大家分享一篇vue 項(xiàng)目打包時(shí)樣式及背景圖片路徑找不到的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11

