Problem description
The project uses a tree structure, and the main information is usually recorded on the leaves of the tree. But in some cases, the backend is not doing some leaves node status information records, such as leaves node status (whether or not to add, to collect what), after the end is what you need the tree structure data back to the front end, as to the status of what, front end need to record, and state changes, also need to the front to record changes
Let’s first take a look at the effect picture of the project:
rendering
Functional analysis
- When we click the leaf node on the left, change the leaf node to the added state, and append the data on the left to the table on the right:
(Click the leaf node to change the state of the leaf node)
- When we click the leaf node again, change the added state of the leaf node to the unadded state, and delete the corresponding item in the table on the right:
(Click the leaf node to change the state of the leaf node)
- When we delete an item in the right table, we also change the state of the left leaf node:
(Recursively changes the state of the corresponding node in the left tree structure)
This example is the tree component lazy load writing method, about the tree component lazy load writing method, can also refer to my previous article, portal: juejin.cn/post/701367…
Click the leaf node to change the leaf node state
// Click the Add or Not Add button on the tree component node to change the add and not add state of the tree, and at the same time append or delete the corresponding row in the table on the right
changeStatus(node, data) {
// console.log("data is the data bound to the tree node clicked ", data);
if (data.status == "0") {
data.status = "1"; // Here we can directly change the corresponding data on the tree node, it will take effect, not added to become added
this.tableData.push(data); // Append to the table on the right
} else if (data.status == "1") {
data.status = "0"; // Added becomes not added
this.tableData.forEach((item, index) = > {
// Delete the data on the right according to the id
if (item.id == data.id) {
this.tableData.splice(index, 1); }}); }},Copy the code
Note that the HTML changeStatus method is written as a higher-order function for clicking a button: @click=”() => changeStatus(node, data)”
Recursively changes the state of the corresponding node in the left tree structure
// Step 1: Get the ID according to the delete button, then recursively change the tree node status field according to the ID
// Step 2: Delete the corresponding data from the table
removeRow(row) {
// console.log(" row data ", row.id);
// Get all the nodes of the tree array (DOM node). Here are two arrays corresponding to journey to the West and romance of The Three Kingdoms array ().
let allNodesDom = this.$refs.myTree.root.childNodes;
console.log("Node tree structure", allNodesDom);
function bianli(checkedData) {
for (const i in checkedData) {
// It is the innermost layer
if (checkedData[i].childNodes.length == 0) {
// When you go to the innermost layer, check to see if the corresponding ID is the same as the id of the removed row
if (checkedData[i].data.id == row.id) {
// If the ids are the same, change the data of the innermost node of the tree component
checkedData[i].data.status = "0";
break; }}else if (checkedData[i].childNodes.length > 0) {
// If you don't get to the innermost layer, keep calling yourself recursivelybianli(checkedData[i].childNodes); }}return;
}
bianli(allNodesDom); // Call recursively to change data
// Delete the row corresponding to the table on the right by id
this.tableData.forEach((item, index) = > {
if (item.id == row.id) {
this.tableData.splice(index, 1); }})}Copy the code
Code attached
<template>
<div class="box">
<! -- Left tree -->
<div class="leftBox">
<el-tree ref="myTree" :props="props" :load="loadNode" lazy node-key="id">
<span slot-scope="{ node, data }">
<i
class="el-icon-folder-opened"
style="color: #448ff7"
v-show="node.isLeaf ! == true"
></i>
<! -- <span style="padding-left: 8px">{{ node.label }}</span> -->
<span style="padding-left: 8px">{{ data.name }}</span>
<el-button
style="margin-left: 12px"
size="small"
type="text"
v-show="node.isLeaf === true"
@click="() => changeStatus(node, data)"
>
<span :class="{ highLightTree: data.status == '0' }">{{ data.status == "0" ? "Not added" : "added"}}</span>
</el-button>
</span>
</el-tree>
</div>
<! -- Table on the right -->
<div class="rightBox">
<el-table
:data="tableData"
border
style="width: 100%"
:header-cell-style="{ height: '48px', background: '#FAFAFA', color: '#333333', fontWeight: 'bold', }"
>
<el-table-column prop="id" label="Id number"></el-table-column>
<el-table-column prop="name" label="Name"></el-table-column>
<el-table-column prop="home" label="Address"></el-table-column>
<el-table-column label="Operation">
<template slot-scope="scope">
<el-button
@click="removeRow(scope.row)"
type="danger"
plain
size="small"
>Remove < / el - button ></template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
props: {
label: "name".isLeaf: "isLeaf",},tableData: [],}; },methods: {
// Initially load the outermost node
loadNode(node, resolve) {
// Click the node to load the data of the corresponding node
if (node.level == 0) {
this.loadfirstnode(resolve);
}
// If you expand other nodes, dynamically load the list of nodes at the next level from the background
if (node.level >= 1) {
this.loadchildnode(node, resolve); }},// Load the level-1 node
async loadfirstnode(resolve) {
let params = {
level: 0};const res = await this.$api.getTreeData(params);
return resolve(res.data);
},
// Load a collection of children of the node
async loadchildnode(node, resolve) {
// console.log(" over level 2 ", node, node.level);
let params = {
id: node.key,
};
const res = await this.$api.getTreeChildData(params);
return resolve(res.data);
},
// Click the Add or Not Add button on the tree component node to change the add and not add state of the tree, and at the same time append or delete the corresponding row in the table on the right
changeStatus(node, data) {
// console.log("data is the data bound to the tree node clicked ", data);
if (data.status == "0") {
data.status = "1"; // Here we can directly change the corresponding data on the tree node, it will take effect, not added to become added
this.tableData.push(data); // Append to the table on the right
} else if (data.status == "1") {
data.status = "0"; // Added becomes not added
this.tableData.forEach((item, index) = > {
// Delete the data on the right according to the id
if (item.id == data.id) {
this.tableData.splice(index, 1); }}); }},// Step 1: get the ID according to the button, then recursively change the tree node status field according to the ID
// Step 2: Delete the corresponding data from the table
removeRow(row) {
// console.log(" row data ", row.id);
// Get all the nodes of the tree array (DOM node). Here are two arrays corresponding to journey to the West and romance of The Three Kingdoms array ().
let allNodesDom = this.$refs.myTree.root.childNodes;
console.log("Node tree structure", allNodesDom);
function bianli(checkedData) {
for (const i in checkedData) {
// It is the innermost layer
if (checkedData[i].childNodes.length == 0) {
// When you go to the innermost layer, check to see if the corresponding ID is the same as the id of the removed row
if (checkedData[i].data.id == row.id) {
// If the ids are the same, change the data of the innermost node of the tree component
checkedData[i].data.status = "0";
break; }}else if (checkedData[i].childNodes.length > 0) {
// If you don't get to the innermost layer, keep calling yourself recursivelybianli(checkedData[i].childNodes); }}return;
}
bianli(allNodesDom); // Call recursively to change data
// Delete the row corresponding to the table on the right by id
this.tableData.forEach((item, index) = > {
if (item.id == row.id) {
this.tableData.splice(index, 1); }})}},};</script>
Copy the code
For the complete code of the front and back end of this article, please download it on my Gitee. The back end uses the Express analog data interface to return to the front end, and the portal is as follows: gitee.com/ah-shuai/de…