el-tree結合el-tree-transfer實現穿梭框里展示樹形數據

參考文章:我把他的彈框單拉出來一個獨立文件作為組件方便使用,遇到一些問題記錄一下。
在這里插入圖片描述

testComponet.vue

<template><div class="per_container"><div class="per_con_left"><div class="per_con_title">未選</div><div class="check_all"><el-checkbox:indeterminate="config.left.isIndeterminate"v-model="config.left.checkAll"@change="handleCheckAll($event, 'left')">全選/全不選</el-checkbox></div><div class="tree"><el-treeref="treeLeft":data="treeDataArr":props="propsDefault"node-key="id"show-checkbox:filter-node-method="filterNodeLeft"@check-change="handleCheckChange('left')"/></div></div><div class="operation"><el-button type="primary" @click="toRight()">移入<i class="el-icon-d-arrow-right"></i></el-button><el-button type="primary" icon="el-icon-d-arrow-left" @click="toLeft()">移除</el-button></div><div class="per_con_right"><div class="per_con_title">已選</div><div class="check_all"><el-checkbox:indeterminate="config.right.isIndeterminate"v-model="config.right.checkAll"@change="handleCheckAll($event, 'right')">全選/全不選</el-checkbox></div><div class="tree"><el-treeref="treeRight":data="treeDataArr":props="propsDefault"node-key="id"show-checkbox:filter-node-method="filterNodeRight"@check-change="handleCheckChange('right')"/></div></div></div>
</template>
<script>
export default {props: ['treeData'],mounted() {this.treeDataArr = this.treeData;this.allParentKeys = this.treeDataArr.map((item) => {return item.id;});if (this.$refs.treeLeft && this.$refs.treeRight) {this.$nextTick(() => {this.setTreeFilter();});}},created() {// this.treeDataArr = this.treeData;// this.allParentKeys = this.treeDataArr.map((item) => {//     return item.id;// });// if (this.$refs.treeLeft && this.$refs.treeRight) {//     this.$nextTick(() => {//         this.setTreeFilter();//     });// }},  data() {return {propsDefault: {label: "name"},isIndeterminateL: false,isIndeterminateR: false,checkAllLeft: false,checkAllRight: false,treeDataArr: [],checkedKeys: [],halfCheckedKeys: [],checkedNodes: [],config: {left: {isIndeterminate: false,checkAll: false,ref: "treeLeft"},right: {isIndeterminate: false,checkAll: false,ref: "treeRight"}}};},methods: {setTreeFilter() {this.$refs.treeLeft.filter();this.$refs.treeRight.filter();},toLeft() {this.checkedKeys = this.$refs.treeRight.getCheckedKeys();this.halfCheckedKeys = this.$refs.treeRight.getHalfCheckedKeys();this.settreeDataArr(this.treeDataArr, false);this.setTreeFilter();this.$refs.treeLeft.setCheckedKeys(this.checkedKeys);this.$refs.treeRight.setCheckedKeys([]);},toRight() {this.checkedKeys = this.$refs.treeLeft.getCheckedKeys();this.halfCheckedKeys = this.$refs.treeLeft.getHalfCheckedKeys();this.settreeDataArr(this.treeDataArr, true);this.setTreeFilter();this.$refs.treeRight.setCheckedKeys(this.checkedKeys);this.$refs.treeLeft.setCheckedKeys([]);},filterNodeLeft(value, data) {console.log('filterNodeLeft',data);return !data.selected;},filterNodeRight(value, data) {console.log('filterNodeRight',data);return data.selected;},// 遞歸設置數據選中狀態settreeDataArr(tree, type) {const setTree = (treeDataArr) => {treeDataArr.forEach((item, index) => {if (this.checkedKeys.includes(item.id)) {treeDataArr[index].selected = type;}if (item.children && item.children.length) {setTree(item.children);// 判斷半選框是否需要移動if (this.halfCheckedKeys.includes(item.id)) {if (type) {treeDataArr[index].selected = type;} else {const target = treeDataArr[index].children.find((it) => {return it.selected;});if (!target) {treeDataArr[index].selected = type;}}}}});};setTree(tree);},submitEdit() {this.$emit("permissionData", this.treeDataArr);},// 勾選樹結構時判斷是否勾選上面的全選handleCheckChange(type) {this.checkedNodes = this.$refs[this.config[type].ref].getCheckedNodes();const pIds = this.checkedNodes.filter((item) => {return !item.pId;});if (!pIds.length) {this.config[type].checkAll = false;this.config[type].isIndeterminate = false;return;}if (pIds.length === this.allParentKeys.length) {this.config[type].checkAll = true;this.config[type].isIndeterminate = false;} else {this.config[type].isIndeterminate = true;this.config[type].checkAll = false;}},// 全選handleCheckAll(value, type) {const keys = value? this.treeDataArr.map((item) => {return item.id;}): [];this.$refs[this.config[type].ref].setCheckedKeys(keys, false);}}
};
</script>
<style lang="scss" scoped>
.per_container {display: flex;height: 500px;justify-content: space-between;align-items: center;
}
.per_con_left,
.per_con_right {width: 45%;height: 100%;
}
.operation {display: flex;flex-direction: column;align-items: center;justify-content: center;padding: 20px;
}
.operation .el-button {margin-left: 0;margin-bottom: 10px;
}
.per_con_title {height: 42px;line-height: 26px;border-radius: 8px 8px 0 0;padding: 8px;align-self: stretch;background: #f2f6f9;font-size: 16px;box-sizing: border-box;border: 1px solid #d8d8d8;font-weight: 700;text-align: left;
}
.check_all {height: 42px;line-height: 42px;padding: 0 5px;border: 1px solid #d8d8d8;border-top: none;text-align: left;
}
.tree {height: calc(100% - 82px);border: 1px solid #d8d8d8;border-top: none;overflow: auto;
}
</style>

思路
(1)思路二:利用elementUI的filter API對選中節點進行篩選,左側篩選出未選中的,右側篩選出選中的,用的還是同一棵樹,用一個屬性來區分是否選擇,好處是子節點選中,父節點會跟隨保存,不用重新構建樹結構。
(2)通過監聽treeData值變化,調用setTreeFilter也就是this.$refs.treeLeft.filter(); this.$refs.treeRight.filter();
里的filter 方法,filter 是 el-tree 組件用于動態過濾樹節點,配合 filter-node-method 屬性可以實現節點過濾,自定義左右側樹過濾的規則分別是是filterNodeLeft(value, data) { return !data.selected;},filterNodeRight(value, data) {return data.selected;},是否被選中(左移右移來設置selected屬性)

testIndex.vue

<template><div><!-- 其他頁面內容 --><TestComponent :treeData="myTreeData" /></div>
</template><script>
import TestComponent from '@/views/test/test.vue';export default {components: {TestComponent},data() {return {myTreeData: [// 這里放置你的樹形數據{id: 1,name: '父節點1',children: [{id: 2,name: '子節點1'}]}]};},// ... existing code ...
};
</script>

關于監聽treeData變化后給樹賦數據這里遇到問題:我把原文監聽treeData對樹進行初始化一開始寫在created里,導致左右都有樹,然后改為mounted就沒有這個問題。
原因:(操作DOM元素用mounted
依賴 DOM 元素 : setTreeFilter 方法可能依賴于 this.$refs.treeLeftthis.$refs.treeRight 這兩個 DOM 引用。在 created 階段,DOM 元素還未掛載, this.$refs 無法正確獲取到對應的 DOM 元素,從而導致過濾邏輯無法正常執行。而在 mounted 階段,DOM 元素已經掛載完成, this.$refs 可以正常獲取到對應的 DOM 元素,過濾邏輯就能正常工作了。

treeData: {handler(val) {this.treeDataArr = val;this.allParentKeys = this.treeDataArr.map((item) => {return item.id;});if (this.$refs.treeLeft && this.$refs.treeRight) {this.$nextTick(() => {this.setTreeFilter();});}},deep: true,},
————————————————
版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。原文鏈接:https://blog.csdn.net/Error_ABC/article/details/136877442

在這里插入圖片描述

 created() {// this.treeDataArr = this.treeData;// this.allParentKeys = this.treeDataArr.map((item) => {//     return item.id;// });// if (this.$refs.treeLeft && this.$refs.treeRight) {//     this.$nextTick(() => {//         this.setTreeFilter();//     });// }},  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83719.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83719.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83719.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go 后端中雙 token 的實現模板

下面是一個典型的 Go 后端雙 Token 認證機制 實現模板&#xff0c;使用 Gin 框架 JWT Redis&#xff0c;結構清晰、可拓展&#xff0c;適合實戰開發。 項目結構建議 /utils├── jwt.go // Access & Refresh token 的生成和解析├── claims.go // 從請求…

Typescript學習教程,從入門到精通,TypeScript 對象語法知識點及案例代碼(7)

TypeScript 對象語法知識點及案例代碼 TypeScript 是 JavaScript 的超集&#xff0c;提供了靜態類型檢查和其他增強功能。在 TypeScript 中&#xff0c;對象是面向對象編程&#xff08;OOP&#xff09;的基礎。 一、對象概述 在 TypeScript 中&#xff0c;對象是屬性的集合&a…

應用BERT-GCN跨模態情緒分析:貿易緩和與金價波動的AI歸因

本文運用AI量化分析框架&#xff0c;結合市場情緒因子、宏觀經濟指標及技術面信號&#xff0c;對黃金與美元指數的聯動關系進行解析&#xff0c;揭示本輪貴金屬回調的深層驅動因素。 周三&#xff0c;現貨黃金價格單日跌幅達2.1%&#xff0c;盤中觸及3167.94美元/盎司關鍵價位&…

命令行登錄 MySQL 報 Segmentation fault 故障解決

問題描述&#xff1a;對 mysql8.0.35 源碼進行 make&#xff0c;由于一開始因為yum源問題少安裝依賴庫 庫&#xff0c;在鏈接時遇到錯誤 undefined reference to&#xff0c;后來安裝了相關依賴庫&#xff0c;再次 make 成功。于是將 mysqld 啟動&#xff0c;再用 mysql -u roo…

Axure設計數字鄉村可視化大屏:構建鄉村數據全景圖

今天&#xff0c;讓我們一同深入了解由Axure設計的數字鄉村可視化大屏&#xff0c;看看它如何通過精心的布局和多樣化的圖表類型&#xff0c;將鄉村的各類數據以直觀、易懂的方式呈現出來&#xff0c;為鄉村管理者提供有力的數據支持。 原型效果預覽鏈接&#xff1a;Axure數字鄉…

3D個人簡歷網站 4.小島

1.模型素材 在Sketchfab上下載狐貍島模型&#xff0c;然后轉換為素材資源asset&#xff0c;嫌麻煩直接在網盤鏈接下載素材&#xff0c; Fox’s islandshttps://sketchfab.com/3d-models/foxs-islands-163b68e09fcc47618450150be7785907https://gltf.pmnd.rs/ 素材夸克網盤&a…

智能開發工具PhpStorm v2025.1——增強AI輔助編碼功能

PhpStorm是一個輕量級且便捷的PHP IDE&#xff0c;其旨在提高用戶效率&#xff0c;可深刻理解用戶的編碼&#xff0c;提供智能代碼補全&#xff0c;快速導航以及即時錯誤檢查。可隨時幫助用戶對其編碼進行調整&#xff0c;運行單元測試或者提供可視化debug功能。 立即獲取PhpS…

Spark 的運行模式(--master) 和 部署方式(--deploy-mode)

Spark 的 運行模式&#xff08;--master&#xff09; 和 部署方式&#xff08;--deploy-mode&#xff09;&#xff0c;兩者的核心區別在于 資源調度范圍 和 Driver 進程的位置。 一、核心概念對比 維度--master&#xff08;運行模式&#xff09;--deploy-mode&#xff08;部署…

sqli—labs第八關——布爾盲注

一&#xff1a;確定注入類型 按照我們之前的步驟來 輸入 ?id1 and 11-- ?id1 and 12-- 界面正常 第二行界面異常空白 所以注入類型為單引號閉合型 二&#xff1a; 布爾盲注 1.判斷是否使用條件 &#xff08;1&#xff09;&#xff1a;存在注入但不會直接顯示查詢結果 …

ARP 原理總結

&#x1f310; 一、ARP 原理總結 ARP&#xff08;Address Resolution Protocol&#xff09;是用于通過 IP 地址解析 MAC 地址的協議&#xff0c;工作在 鏈路層 與 網絡層之間&#xff08;OSI 模型的第三層與第二層之間&#xff09;。 &#x1f501; ARP通信過程&#xff1a; …

SpringCloud——EureKa

目錄 1.前言 1.微服務拆分及遠程調用 3.EureKa注冊中心 遠程調用的問題 eureka原理 搭建EureKaServer 服務注冊 服務發現 1.前言 分布式架構&#xff1a;根據業務功能對系統進行拆分&#xff0c;每個業務模塊作為獨立項目開發&#xff0c;稱為服務。 優點&#xff1a; 降…

機頂盒刷機筆記

疑難雜癥解決 hitool線刷網口不通tftp超時--》關閉防火墻cm201-2卡刷所有包提示失敗abort install--》找個卡刷包只刷fastboot分區再卡刷就能通過了&#xff08;cm201救磚包 (M8273版子&#xff09;&#xff09; 刷機工具 海兔燒錄工具HiTool-STB-5.3.12工具&#xff0c;需要…

Linux動靜態庫制作與原理

什么是庫 庫是寫好的現有的&#xff0c;成熟的&#xff0c;可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫&#xff0c;不可能每個人的代碼都從零開始&#xff0c;因此庫的存在意義非同尋常。 本質上來說庫是一種可執行代碼的二進制形式&#xff0c;可以被操作系統…

如何通過小智AI制作會說話的機器人玩具?

一、硬件準備與組裝 1. 核心硬件選擇 主控芯片&#xff1a;選擇支持無線網絡連接、音頻處理和可編程接口的嵌入式開發板 音頻模塊&#xff1a;配備拾音麥克風與小型揚聲器&#xff0c;確保語音輸入/輸出功能 顯示模塊&#xff1a;選擇適配的交互顯示屏用于可視化反饋 擴展模…

如何控制郵件發送頻率避免打擾用戶

一、用戶行為 監測用戶與郵件的互動數據&#xff0c;如打開率、點擊率下滑或退訂申請增多&#xff0c;可能是發送頻率過高的警示信號。利用郵件營銷平臺的分析工具&#xff0c;識別這些指標的變動趨勢&#xff0c;為調整提供依據。 二、行業特性與受眾差異 不同行業用戶對郵…

定積分的“偶倍奇零”性質及其使用條件

定積分的“偶倍奇零”性質是針對對稱區間上的奇偶函數積分的重要簡化方法。以下是其核心內容和應用要點&#xff1a; ?一、基本性質 ?偶函數&#xff08;偶倍&#xff09;? 若 f(x) 在 [?a,a] 上為偶函數&#xff08;即 f(?x)f(x)&#xff09;&#xff0c;則&#xff1a; …

如何在 Windows 11 或 10 上安裝 Fliqlo 時鐘屏保

了解如何在 Windows 11 或 10 上安裝 Fliqlo,為您的 PC 或筆記本電腦屏幕添加一個翻轉時鐘屏保以顯示時間。 Fliqlo 是一款適用于 Windows 和 macOS 平臺的免費時鐘屏保。它也適用于移動設備,但僅限于 iPhone 和 iPad。Fliqlo 的主要功能是在用戶不活動時在 PC 或筆記本電腦…

【C/C++】C++并發編程:std::async與std::thread深度對比

文章目錄 C并發編程&#xff1a;std::async與std::thread深度對比1 核心設計目的以及區別2 詳細對比分析3 代碼對比示例4 適用場景建議5 總結 C并發編程&#xff1a;std::async與std::thread深度對比 在 C 中&#xff0c;std::async 和 std::thread 都是用于并發編程的工具&am…

Axure疑難雜癥:垂直菜單展開與收回(4大核心問題與專家級解決方案)

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝!如有幫助請訂閱專欄! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:垂直菜單展開與收回 主要內容:超長菜單實現、展開與收回bug解釋、Axure9版本限制等問題解…

ASIC和FPGA,到底應該選擇哪個?

ASIC和FPGA各有優缺點。 ASIC針對特定需求&#xff0c;具有高性能、低功耗和低成本&#xff08;在大規模量產時&#xff09;&#xff1b;但設計周期長、成本高、風險大。FPGA則適合快速原型驗證和中小批量應用&#xff0c;開發周期短&#xff0c;靈活性高&#xff0c;適合初創企…