vue實(shí)現(xiàn)樹形結(jié)構(gòu)增刪改查的示例代碼
其實(shí)很多公司都會有類似于用戶權(quán)限樹的增刪改查功能,正好最近我剛寫了一個(gè)樹形結(jié)構(gòu)的增刪改,在這里和大家分享一下,如果有不合理的地方歡迎評論,我會盡快優(yōu)化~~ 先附上一下效果圖
這個(gè)是沒有點(diǎn)擊編輯時(shí),產(chǎn)品的需求是選中某個(gè)節(jié)點(diǎn),取得該節(jié)點(diǎn)對應(yīng)的設(shè)備數(shù)據(jù),所以初始頁面是下面這個(gè)樣子的。

這個(gè)是點(diǎn)擊了編輯之后,顯示節(jié)點(diǎn)的編輯按鈕

點(diǎn)擊最上面的添加按鈕,顯示最外層父節(jié)點(diǎn)的添加畫面

修改節(jié)點(diǎn)名稱

因?yàn)槲覀兊男枨笫蔷庉嬇c非編輯兩種狀態(tài),所以我用了兩個(gè)樹形組件,通過v-if進(jìn)行控制。(v-if:該組件不存在,v-show:組件占用空間,只是不展示)
<el-tree
v-if="treeSetData.editFlg"
ref="tree"
:key="treeSetData.tree_key"
:data="treeSetData.treeData"
node-key="id"
:render-content="renderContent"
:expand-on-click-node="false"
:default-expand-all="treeSetData.defaultExpandAll"
highlight-current
@node-click="handleNodeClick"
class="tree-style"
></el-tree>
<el-tree
v-else
ref="tree"
:key="treeSetData.tree_key"
:data="treeSetData.treeData"
node-key="id"
:render-content="renderContent"
:expand-on-click-node="false"
:default-expand-all="treeSetData.defaultExpandAll"
highlight-current
class="tree-style"
></el-tree>
樹形組件的字段說明我就不一一贅述了,可以通過element-ui的樹形組件官網(wǎng)查看,但是我要單獨(dú)說明一下以下方法,
- render-content:自定義節(jié)點(diǎn)內(nèi)容,renderContent:為方法名。
- @node-click:節(jié)點(diǎn)點(diǎn)擊時(shí)調(diào)用,因?yàn)橹挥性诜蔷庉嫚顟B(tài)下才存在節(jié)點(diǎn)點(diǎn)擊效果,因此該方法我只寫在了非編輯的樹形組件內(nèi)
所需data說明
// 樹形結(jié)構(gòu)所需數(shù)據(jù)
treeSetData:{
defaultExpandAll:true, // 是否默認(rèn)展開
editFlg:true, // 是否是編輯狀態(tài)
treeData: [], // 樹形組件數(shù)據(jù)集
// 編輯樹形數(shù)組內(nèi)容
editList:[],
// 刪除樹形數(shù)據(jù)數(shù)組內(nèi)容
deleteList:[],
// 添加樹形數(shù)據(jù)數(shù)組內(nèi)容
addList:[],
// 是否添加flg
addNodeFlg:false,
// 默認(rèn)的id
defaultId:5000,
// 新增的最外層節(jié)點(diǎn)名稱
newName:'',
tree_key: 0,
},
說明一下最外層節(jié)點(diǎn)的添加方法,其實(shí)主要的核心思想是控制下方的輸入框以及按鈕的展示與否,然后點(diǎn)擊確認(rèn)按鈕之后,在原有的樹形組件data里新增一條數(shù)據(jù)。
實(shí)現(xiàn)畫面

添加按鈕的html代碼
<el-button type="text" @click="add_new_Area" class="button-style"><i class="el-icon-plus" style="margin-right:5px"></i>添加</el-button>
添加按鈕點(diǎn)擊方法【add_new_Area】
add_new_Area() {
this.treeSetData.addNodeFlg = true;
},
文本框的代碼片段
<el-row class="add_question" v-show="treeSetData.addNodeFlg">
<el-col :span="11" style="margin:0px 5px">
<el-input v-model="treeSetData.newName" placeholder="通行區(qū)域" size="mini"></el-input>
</el-col>
<el-col :span="12">
<el-button size="mini" type="primary" plain @click.stop="add_area_sure">確定</el-button>
<el-button size="mini" type="warning" plain @click.stop="add_area_cancel">取消</el-button>
</el-col>
</el-row>
確認(rèn)按鈕【add_area_sure】
add_area_sure() {
// 添加節(jié)點(diǎn)數(shù)據(jù),因?yàn)槭亲钌蠈?,所以默認(rèn)父ID是pid,id的話是我初始化設(shè)置的【defaultId】的自加,大家自己在data中加一下【defaultId】字段就可以了
const nodeObj = {
id: this.treeSetData.defaultId++,
name: this.treeSetData.newName,
isEdit: false,
children: [],
pid:0
};
this.treeSetData.treeData.push(nodeObj);
this.treeSetData.addNodeFlg = false;
this.treeSetData.addList.push(nodeObj);
},
取消按鈕【add_area_cancel】
add_area_cancel() {
this.treeSetData.addNodeFlg = false;
this.treeSetData.newName = "";
},
至此就可以實(shí)現(xiàn)最外層節(jié)點(diǎn)的添加了。
編輯狀態(tài)下的幾點(diǎn)增刪改的話,其實(shí)就是通過自定義節(jié)點(diǎn)內(nèi)容的【renderContent】這個(gè)方法實(shí)現(xiàn)的,快下班了我就不一一說明了,有時(shí)間再補(bǔ)吧,先把主要代碼提出來~
// 通行區(qū)域樹操作group node,
renderContent(h, { node, data, store }) {
if(this.treeSetData.editFlg == false){
return (
<span class="tree-span">
<span>{this.showOrEdit(data)}</span>
<div class="tree_node_op">
<i class="el-icon-edit" on-click={ev => this.nodeEdit(ev, store, data)} style="padding-left: 10px;"></i>
<i class="el-icon-circle-plus" on-click={() => this.nodeAdd(node, data)} style="margin-left: 5px;"></i>
<i class="el-icon-remove" on-click={() => this.nodeDelete(node, data)} style="margin-left: 5px;"></i>
</div>
</span>
);
} else {
return (
<span class="tree-span">
<span>{this.showOrEdit(data)}</span>
<div class="tree_node_op">
</div>
</span>
);
}
},
// 節(jié)點(diǎn)編輯
showOrEdit(data) {
if (data.isEdit) {
return (
<el-input
type="text"
value={data.name}
on-blur={ev => this.edit_sure(ev, data)}
size="mini"
class="input-style"
></el-input>
);
} else {
return <span className="node_labe">{data.name}</span>;
}
},
nodeEdit(ev, store, data) {
data.isEdit = true;
this.$nextTick(() => {
const $input =
ev.target.parentNode.parentNode.querySelector("input") ||
ev.target.parentElement.parentElement.querySelector("input");
!$input ? "" : $input.focus();
});
},
// 確認(rèn)編輯
edit_sure(ev, data) {
const $input =
ev.target.parentNode.parentNode.querySelector("input") ||
ev.target.parentElement.parentElement.querySelector("input");
if (!$input) {
return false;
} else {
data.name = $input.value;
data.isEdit = false;
}
// 修改編輯樹形數(shù)據(jù)的內(nèi)容
let editFilter = this.treeSetData.editList.filter((item)=>item.id == data.id);
if (editFilter.length == 0){
this.treeSetData.editList.push(data);
} else {
this.treeSetData.editList.forEach((item,i)=>{
if(item.id == data.id) {
this.treeSetData.editList[i].name = data.name;
}
})
}
},
// 增加節(jié)點(diǎn)
nodeAdd(node, data) {
if (data.pid !== 0){
this.$message({type:'error',message:'通行區(qū)域最多只能有兩級層次結(jié)構(gòu)。'});
return false;
} else {
const newChild = { id: this.treeSetData.defaultId++, name: '新增的通行區(qū)域', isEdit:false, pid:data.id, children: [] };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
this.treeSetData.addList.push(newChild);
}
},
// 節(jié)點(diǎn)刪除
nodeDelete(node, data) {
this.treeSetData.deleteList.push(data);
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
},
然后將上面處理完的數(shù)據(jù)(要增加的數(shù)據(jù):addList,要修改的數(shù)據(jù):editList,要刪除的數(shù)據(jù):deleteList)整體提交給后臺去做數(shù)據(jù)庫處理就可以了,但是需要注意一下以下的幾種情況。
// 先添加,后修改的數(shù)據(jù)整合
this.treeSetData.addList.forEach((item,i)=>{
let editFilter = this.treeSetData.editList.filter((value)=>value.id == item.id);
if(editFilter.length !== 0){
this.treeSetData.addList[i] = editFilter[0];
this.treeSetData.editList = this.treeSetData.editList.filter((value)=>value.id !== item.id);
}
})
// 先添加,后刪除的數(shù)據(jù)整合
this.treeSetData.deleteList.forEach((item,i)=>{
let addFilter = this.treeSetData.addList.filter((value)=>value.id == item.id);
if(addFilter.length !== 0){
this.treeSetData.deleteList = this.treeSetData.deleteList.filter((value)=>value.id !== item.id);
this.treeSetData.addList = this.treeSetData.addList.filter((value)=>value.id !== item.id);
}
})
// 先編輯,后刪除的數(shù)據(jù)整合
this.treeSetData.deleteList.forEach((item,i)=>{
let editFilter = this.treeSetData.editList.filter((value)=>value.id == item.id);
if(editFilter.length !== 0){
this.treeSetData.editList = this.treeSetData.editList.filter((value)=>value.id !== item.id);
}
})
樹形組件樣式
<style lang="less">
.el-message-box {width: 450px;}
.button-style {padding: 0px}
.input-style {height: 15px;width: 140px;}
.through-panel-body {
padding-top:12px;
width: 100%;
display: flex;
.panel-area-left {
position: relative;
width: 360px;
border:2px solid rgba(240,240,240,1);
border-radius: 5px;
.head-title {
display:flex;justify-content: space-between;padding:10px 10px;
h5{border-left:solid 3px #FB8742;padding-left:5px;height: 20px;line-height:20px;font-size:16px;}
}
.area-tree {
width: 100%;
.tree-style {
margin: 0px 0px 10px 10px;
height:88%;
overflow-y: auto;
}
.el-tree-node__content {
padding-left: 10px;display: flex;width: 100%;
.tree-span {
display: flex; width: 100%;
.tree_node_op {
margin-left: 10px;color: #D3D3D3;
}
}
}
}
.add_question {
margin: 10px 0px;
}
.foot-style{
padding-right:5px;
height: 40px;
text-align: right;
}
}
.panel-area-right {
margin-right: 5px;
width: 100%;
padding-left: 15px;
height: 100%;
.el-row {
width: 100%;
display: flex;
justify-content: space-between;
.located-class {
width: 50%;
}
.device-floor-class {
width: 50%;
display: flex;
justify-content: flex-end;
}
}
}
}
</style>
到此這篇關(guān)于vue實(shí)現(xiàn)樹形結(jié)構(gòu)增刪改查的示例代碼的文章就介紹到這了,更多相關(guān)vue 樹形結(jié)構(gòu)增刪改查內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue?elementUI實(shí)現(xiàn)樹形結(jié)構(gòu)表格與懶加載
- vue開發(fā)樹形結(jié)構(gòu)組件(組件遞歸)
- vue Element-ui表格實(shí)現(xiàn)樹形結(jié)構(gòu)表格
- vue實(shí)現(xiàn)樹形結(jié)構(gòu)樣式和功能的實(shí)例代碼
- vue實(shí)現(xiàn)的樹形結(jié)構(gòu)加多選框示例
- vue樹形結(jié)構(gòu)獲取鍵值的方法示例
- Vue.js 遞歸組件實(shí)現(xiàn)樹形菜單(實(shí)例分享)
- vuejs使用遞歸組件實(shí)現(xiàn)樹形目錄的方法
- 用 Vue.js 遞歸組件實(shí)現(xiàn)可折疊的樹形菜單(demo)
- vue遞歸組件實(shí)現(xiàn)樹形結(jié)構(gòu)
相關(guān)文章
Ant?Design?Vue中的table與pagination的聯(lián)合使用方式
這篇文章主要介紹了Ant?Design?Vue中的table與pagination的聯(lián)合使用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
Vue2 配置 Axios api 接口調(diào)用文件的方法
本篇文章主要介紹了Vue2 配置 Axios api 接口調(diào)用文件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
vue3+vite+vant項(xiàng)目下按需引入vant報(bào)錯(cuò)Failed?to?resolve?import的原因及解決
這篇文章主要給大家介紹了關(guān)于vue3+vite+vant項(xiàng)目下按需引入vant報(bào)錯(cuò)Failed?to?resolve?import的原因及解決方案,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
vue中如何利用js函數(shù)截取時(shí)間的年月日時(shí)分秒
時(shí)分秒都是跟月份一樣,從0開始數(shù)的,不用+1,因?yàn)樵率?-12月,而時(shí)分秒是0-23和0-59,下面這篇文章主要給大家介紹了關(guān)于vue中如何利用js函數(shù)截取時(shí)間的年月日時(shí)分秒的相關(guān)資料,需要的朋友可以參考下2022-11-11
element-ui中table組件的toggleRowSelection()方法使用
這篇文章主要介紹了element-ui中table組件的toggleRowSelection()方法使用,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
前端插件庫之vue3使用vue-codemirror插件的步驟和實(shí)例
CodeMirror是一款基于JavaScript、面向語言的前端代碼編輯器,下面這篇文章主要給大家介紹了關(guān)于前端插件庫之vue3使用vue-codemirror插件的步驟和實(shí)例,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07

