這篇文章給大家介紹Vue中怎么實現一個無限級聯樹形表格,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
資源
JavaScript框架:vue.js
UI框架:Element UI
源碼
這里需要重點說明的是,主要使用了遞歸的算法以及給數據標識的重要性。詳細說明可以在源碼中查看注釋,也可以通過刪改代碼融會貫通。
<template> <div class="container"> <div class="btn-r"> <el-button type="primary" size="small" @click="addView = true" icon="el-icon-circle-plus-outline" class="add" >添加</el-button > </div> <el-table :data="tableData" style="width: 100%; margin-bottom: 20px" row-key="value" border default-expand-all size="medium" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" > <el-table-column prop="label" label="名稱" sortable> </el-table-column> <el-table-column label="操作" align="center" width="180"> <template slot-scope="scope"> <el-button type="text" size="small" @click="handleClick(scope.row, scope.$index)" >編輯</el-button > <el-button type="text" size="small" @click="deleteClick(scope.row, scope.$index)" >刪除</el-button > </template> </el-table-column> </el-table> <!-- 添加窗口 --> <el-dialog title="添加" :visible.sync="addView" :close-on-click-modal="false" width="30%" @close="closeView" > <el-form :model="form" ref="form" :rules="rules"> <el-form-item label="位置" :label-width="formLabelWidth" prop="location" > <el-select v-model="form.location" placeholder="請選擇位置" @change="locationChange" size="small" > <el-option v-for="item in locationData" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> <el-form-item v-if="sonStatus" label="子位置" :label-width="formLabelWidth" prop="childArr" > <el-cascader size="small" :key="isResouceShow" v-model="form.childArr" placeholder="請選擇子位置" :label="'name'" :value="'id'" :options="tableData" :props="{ checkStrictly: true }" clearable @change="getCasVal" ></el-cascader> </el-form-item> <el-form-item label="名稱" :label-width="formLabelWidth" prop="label" > <el-input v-model="form.label" size="small" autocomplete="off" placeholder="請輸入名稱" ></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="addView = false" size="small" >取 消</el-button > <el-button type="primary" @click="okAdd('form')" size="small" >確 定</el-button > </span> </el-dialog> <!-- 編輯窗口 --> <el-dialog title="編輯" :visible.sync="editView" :close-on-click-modal="false" width="30%" > <el-form :model="data" ref="data" :rules="rules"> <el-form-item label="位置" :label-width="formLabelWidth" prop="location" > <el-select v-model="data.location" placeholder="請選擇位置" size="small" @change="locationChange" > <el-option v-for="item in locationData" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> <el-form-item v-if="sonStatus" label="子位置" :label-width="formLabelWidth" prop="childArr" > <el-cascader :key="isResouceShow" v-model="data.childArr" placeholder="請選擇子位置" size="small" :label="'name'" :value="'id'" :options="tableData" :props="{ checkStrictly: true }" clearable @change="getCasVal" ></el-cascader> </el-form-item> <el-form-item label="名稱" :label-width="formLabelWidth" prop="label" > <el-input v-model="data.label" autocomplete="off" placeholder="請輸入名稱" size="small" ></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="editView = false" size="small" >取 消</el-button > <el-button type="primary" @click="okEdit('data')" size="small" >確 定</el-button > </span> </el-dialog> </div> </template> <script> export default { name: 'Tag', data() { return { location: '', isResouceShow: 1, addView: false, sonStatus: false, editView: false, casArr: [], childArr: [], form: {}, data: {}, idx: '', childkey: [], formLabelWidth: '80px', rules: { label: [ { required: true, message: '請輸入名稱', trigger: 'blur' } ] }, locationData: [ { id: 1, name: '頂' }, { id: 2, name: '子' } ], tableData: [] }; }, methods: { // 監聽關閉窗口 closeView() { this.$refs['form'].resetFields(); // 關閉窗口,清空填寫的內容 }, // 打開編輯 handleClick(item, index) { item.value.length != 1 ? (this.sonStatus = true) : (this.sonStatus = false); this.editView = true; const obj = Object.assign({}, item); this.childkey = item.childkey; this.casArr = item.childArr; this.idx = index; this.data = obj; }, // 遞歸表格數據(編輯) findSd(arr, i, casArr) { if (i == casArr.length - 1) { let index = casArr[i].substr(casArr[i].length - 1, 1); return arr.splice(index, 1, this.data); } else { return this.findSd( arr[casArr[i].substr(casArr[i].length - 1, 1)].children, (i += 1), casArr ); } }, // 確定編輯 okEdit(data) { this.$refs[data].validate(valid => { if (valid) { if (this.data.value.length == 1) { this.tableData.splice(this.idx, 1, this.data); this.$message({ type: 'success', message: '編輯成功' }); this.editView = false; } else { this.findSd(this.tableData, 0, this.childkey); this.$message({ type: 'success', message: '編輯成功' }); this.editView = false; } } else { return false; } }); }, // 遞歸表格數據(刪除) findDel(arr, i, item) { let casArr = item.childkey; if (i == casArr.length - 1) { let index = casArr[i].substr(casArr[i].length - 1, 1); return arr.splice(index, 1); } else { return this.findDel( arr[casArr[i].substr(casArr[i].length - 1, 1)].children, (i += 1), item ); } }, // 刪除 deleteClick(item) { this.$confirm(`此操作將刪除該項, 是否繼續?`, '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }) .then(() => { if (item.children.length != 0) { this.$message.warning({ message: '請刪除子節點', duration: 1000 }); } else { this.casArr = item.childArr; ++this.isResouceShow; // 給級聯控件綁定一個key,防止報錯。 if (item.value.length == 1) { // 刪除的是頂節點 console.log(1); this.tableData.splice(item.value, 1); this.$message({ type: 'success', message: '刪除成功' }); } else { // 刪除的是子節點 console.log(2); this.findDel(this.tableData, 0, item); this.$message({ type: 'success', message: '刪除成功' }); } } }) .catch(err => { console.log(err); this.$message({ type: 'info', message: '已取消刪除' }); }); }, // 是否顯示次位置 locationChange(v) { if (v == 2) { this.sonStatus = true; } else { this.sonStatus = false; } }, // 獲取次位置 getCasVal(v) { this.casArr = v; this.form.childArr = v; }, // 遞歸表格數據(添加) find(arr, i) { if (i == this.casArr.length - 1) { return arr[this.casArr[i].substr(this.casArr[i].length - 1, 1)] .children; } else { return this.find( arr[this.casArr[i].substr(this.casArr[i].length - 1, 1)] .children, (i += 1) ); } }, // 確定添加 okAdd(form) { this.$refs[form].validate(valid => { if (valid) { if (this.sonStatus == false) { this.form.value = String(this.tableData.length); const obj = Object.assign({}, this.form); obj.children = []; obj.childArr = []; this.tableData.push(obj); this.$message({ type: 'success', message: '添加成功' }); this.addView = false; } else { let arr = this.find(this.tableData, 0); this.childArr = [...this.casArr, String(arr.length)]; this.form.value = String(this.casArr[this.casArr.length - 1]) + String(arr.length); delete this.form.children; const obj = Object.assign({}, this.form); obj.children = []; obj.childkey = [...this.casArr, String(arr.length)]; arr.push(obj); this.$message({ type: 'success', message: '添加成功' }); this.addView = false; } } else { return false; } }); } } }; </script> <style lang="scss" scoped> ::v-deep .el-form-item__content { width: 203px; } </style>關于Vue中怎么實現一個無限級聯樹形表格就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。