基于element-ui二次封装树Tree组件,可以新增修改删除重命名树节点

采用组件化开发进行二次封装;

效果如下:

 

使用页代码如下:

<template>
  <div class="gd-tree">
    <eleTree
      :data.sync="newData"
      :fileDrop="fileDrop"
      :diectoryDrop="diectoryDrop"
      :delete="deleteBtn"
      :edit="editBtn"
    ></eleTree>
  </div>
</template>
<script>
export default {
  name: "eleTreeComponent",
  created() {},
  data() {
    return {
      fileDrop: [
        { text: "add", value: "新增" },
        { text: "rn", value: "修改" },
        { text: "rm", value: "删除" }
      ],
      diectoryDrop: [
        { text: "add", value: "新增" },
        { text: "rn", value: "修改" },
        { text: "rm", value: "删除" }
      ],
      data: [
        {
          label: "一级 1",
          id: 1,
          children: [
            {
              label: "二级 1-1",
              id: 2,
              children: [
                {
                  label: "三级 1-1-1",
                  id: 3
                }
              ]
            }
          ]
        },
        {
          label: "一级 2",
          id: 4,
          children: [
            {
              label: "二级 2-1",
              id: 5,
              children: [
                {
                  label: "三级 2-1-1",
                  id: 6
                }
              ]
            },
            {
              label: "二级 2-2",
              id: 7,
              children: [
                {
                  label: "三级 2-2-1",
                  id: 8
                }
              ]
            }
          ]
        },
        {
          label: "一级 3",
          id: 9,
          children: [
            {
              label: "二级 3-1",
              id: 10,
              children: [
                {
                  label: "三级 3-1-1",
                  id: 11
                }
              ]
            },
            {
              label: "二级 3-2",
              id: 12,
              children: [
                {
                  label: "三级 3-2-1",
                  id: 13
                }
              ]
            }
          ]
        }
      ],
      newData: []
    };
  },
  mounted() {
    setTimeout(() => {
      this.newData = this.data;
    }, 100);
  },
  methods: {
    deleteBtn(id) {
      return new Promise((resolve, reject) => {
        resolve(id);
      });
    },
    editBtn(id) {
      return new Promise((resolve, reject) => {
        resolve(id);
      });
    }
  }
};
</script>

封装组件代码:

 

<template>
  <div class="gd-eleTree">
    <el-tree
      :data="allData"
      node-key="id"
      default-expand-all
      :expand-on-click-node="false"
      :render-content="renderContent"
    ></el-tree>
  </div>
</template>
<script>
let id = 1000;
export default {
  name: "eleTree",
  created() {},
  props: {
    data: {
      type: Array,
      default: () => []
    },
    diectoryDrop: {
      type: Array,
      default: () => []
    },
    fileDrop: {
      type: Array,
      default: () => []
    },
    delete: {
      type: Function,
      default: () => () => {}
    },
    edit: {
      type: Function,
      default: () => () => {}
    }
  },
  mounted() {},
  data() {
    return {
      allData: [],
      currentId: "", //默认当前点击的修改
      currentContent: "" //当前编辑的内容
    };
  },
  watch: {
    data: {
      handler(newVal) {
        this.allData = newVal;
      },
      immediate: true
    }
  },
  methods: {
    findCurrentDelete(id, arr, type) {
      arr.forEach((element, index) => {
        if (element.id === id) {
          if (type == "delete") {
            arr.splice(index, 1);
          } else {
            element.label = this.currentContent;
          }

          return;
        } else if (element.children && element.children.length > 0) {
          this.findCurrentDelete(id, element.children, type);
        }
      });
      return arr;
    },
    remove(id) {
      let arr = JSON.parse(JSON.stringify(this.allData));
      let list = this.findCurrentDelete(id, arr, "delete");
      this.$emit("update:data", list);
    },
    reName(data) {
      this.currentId = data.id;
      this.currentContent = data.label;
    },
    reMove(data) {
      this.delete
        ? this.delete(data.id).then(res => {
            this.remove(res);
          })
        : this.remove(data.id);
    },
    reAdd(data) {
      console.log(data);
      const newChild = {
        id: id++,
        label: ""
      };
      if (!data.children) {
        this.$set(data, "children", []);
      }
      data.children.push(newChild);
      this.currentId = newChild.id;
      this.currentContent = newChild.label;
      console.log(this.allData);
      this.addFlag = true;
    },
    handleCommand(data, value) {
      if (value === "rn") {
        this.reName(data);
      } else if (value == "rm") {
        this.reMove(data);
      } else if (value == "add") {
        this.reAdd(data);
      }
    },
    sureBtn(data) {
      this.edit
        ? this.edit(data.id).then(res => {
            this.editHandle(res);
          })
        : this.editHandle(data.id);
    },
    editHandle(id) {
      let arr = JSON.parse(JSON.stringify(this.allData));
      let list = this.findCurrentDelete(id, arr, "edit");
      console.log(list);
      this.$emit("update:data", list);
      this.currentId = "";
    },
    cancelBtn() {
      this.currentId = "";
    },
    handelInput(v) {
      this.currentContent = v;
    },
    renderContent(h, { node, data, store }) {
      let isParent = data.children && data.children.length > 0;
      let list = isParent ? this.diectoryDrop : this.fileDrop;
      return (
        <span class="custom-tree-node">
          {isParent ? (
            node.expanded ? (
              <i class="el-icon-folder-opened"></i>
            ) : (
              <i class="el-icon-folder"></i>
            )
          ) : (
            <i class="el-icon-document"></i>
          )}
          {data.id === this.currentId ? (
            <el-input
              value={this.currentContent}
              on-input={this.handelInput.bind(this)}
            />
          ) : (
            node.label
          )}

          {data.id !== this.currentId ? (
            <el-dropdown
              size="small"
              trigger="click"
              on-command={this.handleCommand.bind(this, data)}
            >
              <span class="el-dropdown-link">
                <i class="el-icon-arrow-down el-icon--right"></i>
              </span>
              <el-dropdown-menu slot="dropdown">
                {list.map(item => (
                  <el-dropdown-item command={item.text}>
                    {item.value}
                  </el-dropdown-item>
                ))}
              </el-dropdown-menu>
            </el-dropdown>
          ) : (
            <span>
              <el-button type="text" on-click={this.sureBtn.bind(this, data)}>
                确认
              </el-button>
              <el-button type="text" on-click={this.cancelBtn}>
                取消
              </el-button>
            </span>
          )}
        </span>
      );
    }
  }
};
</script>
<style lang="scss" scoped>
.gd-tree {
  ul {
    margin-left: 15px;
    padding-left: 0;
  }
  &-node {
    &_content {
      position: relative;
      cursor: pointer;
      .gd-icon_updown {
        position: absolute;
        left: -12px;
        top: 6px;
        &.is-active {
          top: 1px;
        }
      }
    }
    &_label {
    }
  }
}
.gd-eleTree {
  .el-tree {
    .el-tree-node {
      width: 500px;
    }
    .el-tree-node__content {
      display: flex;
      align-items: center;
      height: 34px;
      cursor: pointer;
    }
    .el-input {
      width: 70%;
    }
    .el-input__inner {
      height: 32px;
      padding: 0 12px;
      width: 95%;
    }
    .custom-tree-node {
      width: 100%;
    }
    .el-dropdown {
      float: right;
    }
  }
}

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值