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…