Vue implements the sample code of adding, deleting, modifying and checking the tree structure

Vue implements the sample code of adding, deleting, modifying and checking the tree structure

In fact, many companies have functions similar to the user permission tree. I just wrote a tree structure of additions, deletions, and modifications recently. I would like to share it with you here. If there is anything unreasonable, please comment and I will optimize it as soon as possible. Attach the effect picture first.

This is when Edit is not clicked. The product requirement is to select a node and obtain the device data corresponding to the node, so the initial page looks like the following.

insert image description here

This is the edit button of the node displayed after clicking Edit

insert image description here

Click the top add button to display the add screen of the outermost parent node

insert image description here

Modify the node name

insert image description here

Because our requirements are two states: editing and non-editing, I used two tree components and controlled them through v-if. (v-if: the component does not exist, v-show: the component takes up space but is not displayed)

<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>

I will not go into detail about the fields of the tree component. You can view them on the element-ui tree component official website, but I will explain the following methods separately.

  • render-content: custom node content, renderContent: is the method name.
  • @node-click: Called when a node is clicked. Since the node click effect only exists in the non-editing state, I only wrote this method in the non-editing tree component.

Required data description

// Data required for the tree structuretreeSetData:{
  defaultExpandAll:true, // Whether to expand by default editFlg:true, // Whether it is in editing state treeData: [], // Tree component data set // Edit tree array content editList:[],
  // Delete the contents of the tree data array deleteList:[],
  // Add tree data array content addList:[],
  // Whether to add flg
  addNodeFlg:false,
  //Default id
  defaultId:5000,
  // Newly added outermost node name newName:'',
  tree_key: 0,
},

Let me explain how to add the outermost node. In fact, the core idea is to control the display of the input box and button below, and then add a new data to the original tree component data after clicking the confirmation button.

Realization screen

insert image description here

Add button html code

<el-button type="text" @click="add_new_Area" class="button-style"><i class="el-icon-plus" style="margin-right:5px"></i>Add</el-button>

Add button click method [add_new_Area]

add_new_Area() {
      this.treeSetData.addNodeFlg = true;
    },

Code snippet for textbox

<el-row class="add_question" v-show="treeSetData.addNodeFlg">
    <el-col :span="11" style="margin:0px 5px">
         <el-input v-model="treeSetData.newName" placeholder="Passage area" size="mini"></el-input>
     </el-col>
     <el-col :span="12">
         <el-button size="mini" type="primary" plain @click.stop="add_area_sure">OK</el-button>
         <el-button size="mini" type="warning" plain @click.stop="add_area_cancel">Cancel</el-button>
     </el-col>
 </el-row>

Confirm button [add_area_sure]

add_area_sure() {
// Add node data. Because it is the top layer, the default parent ID is pid. The id is the self-addition of the [defaultId] I set in the initialization. You can add the [defaultId] field in the data by yourself. 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);
},

Cancel button [add_area_cancel]

add_area_cancel() {
  this.treeSetData.addNodeFlg = false;
  this.treeSetData.newName = "";
},

At this point, the outermost node can be added.

The additions, deletions and modifications in the editing state are actually implemented through the [renderContent] method of the custom node content. I will not explain them one by one as I am about to get off work. I will make up for it when I have time. First, I will present the main code~

// Pass area tree operation 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>
            );
        }
    },

    // Node editing 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();
      });
    },

    // Confirm edit 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;
        }
        // Modify the content of the edit tree data 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;
                }
            })
        }
    },

    // Add node nodeAdd(node, data) {
      if (data.pid !== 0){
        this.$message({type:'error',message:'The access area can have at most two levels of hierarchy.'});
        return false;
      } else {
          const newChild = { id: this.treeSetData.defaultId++, name: 'Newly added access area', isEdit:false, pid:data.id, children: [] };
          if (!data.children) {
            this.$set(data, 'children', []);
          }
          data.children.push(newChild);
          this.treeSetData.addList.push(newChild);
      }
    },

    // Node deletion 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);
    },

Then submit the processed data (data to be added: addList, data to be modified: editList, data to be deleted: deleteList) to the background for database processing, but you need to pay attention to the following situations.

// Add first, then modify the data integration 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);
    }
})
// First add, then delete the data integration 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);
    }
})
// First edit, then delete data integration 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);
    }
})

Tree component style

<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>

This is the end of this article about the sample code for Vue to implement tree structure addition, deletion, modification and query. For more relevant Vue tree structure addition, deletion, modification and query content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Using vue3+ts to implement management background (add, delete, modify and check)
  • Vue uses el-tree lazy loading to implement the add, delete, modify and query functions
  • Vue uses Element to implement the steps of adding, deleting, modifying and packaging
  • VUE+Element implements example source code for adding, deleting, modifying and checking
  • Vue simple operation of adding, deleting, modifying and checking
  • Detailed explanation of the add, delete, modify and query functions of Vue user management

<<:  Docker FAQ

>>:  Solution to the garbled code problem in MySQL 5.x

Recommend

Ubuntu16.04 builds php5.6 web server environment

Ubuntu 16.04 installs the PHP7.0 environment by d...

Docker swarm simple tutorial

swarm three virtual machines 132,133,134 1. Initi...

Things about installing Homebrew on Mac

Recently, Xiao Ming just bought a new Mac and wan...

How to modify the port mapping of a running Docker container

Preface When docker run creates and runs a contai...

Detailed explanation of MySQL master-slave database construction method

This article describes how to build a MySQL maste...

NodeJs high memory usage troubleshooting actual combat record

Preface This is an investigation caused by the ex...

Use Visual Studio Code to connect to the MySql database and query

Visual Studio Code is a powerful text editor prod...

What you need to understand about MySQL locks

1. Introduction MySQL locks can be divided into g...

DIV common attributes collection

1. Property List Copy code The code is as follows:...

Vue implements horizontal beveled bar chart

This article shares the specific code of Vue to i...

Determine whether MySQL update will lock the table through examples

Two cases: 1. With index 2. Without index Prerequ...

HTML simple web form creation example introduction

<input> is used to collect user information ...