elementui ツリー遅延読み込みレイヤー ツリー ノードの追加

ノードをレイヤー ツリーに追加します。

node.children= res.data

this.$refs.tree.updateKeyChildren(node.id, node.children)

 遅延読み込みケース 1:

<template>
  <div
    class="vtree"
    style="width: 100%; padding: 5px; box-sizing: border-box; height: 100%"
  >
    <div class="treeInput">
      <el-input
        placeholder="输入编目名称"
        suffix-icon="el-icon-search"
        v-model="filterText"
        size="mini"
      >
      </el-input>
    </div>
    <div class="title">数据编目</div>
    <div style="height: 16px; text-align: center; padding: 4px 33px">
      <div v-if="count > 0">
        <span
          style="
            display: inline-block;
            color: #606266;
            float: left;
            font-size: 12px;
            padding: 2px;
          "
          >查询到:{
   
   { count }}个编目</span
        >
        <img
          title="清空选中以及条件"
          style="cursor: pointer; float: left; padding-left: 5px"
          height="16"
          :src="require('@/assets/images/clearAll.png')"
          @click="clearSelectNode"
        />
        <img
          title="查看上一个"
          style="cursor: pointer; float: right; padding-left: 5px"
          height="16"
          :src="require('@/assets/images/down.png')"
          @click="nextSelectNode"
        />
        <img
          title="查看下一个"
          style="cursor: pointer; float: right"
          height="16"
          :src="require('@/assets/images/up.png')"
          @click="preSelectNode"
        />
      </div>
    </div>
    <!-- 林草湿督查下拉框 -->
    <el-select
      size="mini"
      style="width: 100%"
      v-model="treeActive"
      @change="treeChange"
      placeholder="请选择"
    >
      <el-option
        v-for="item in Treedata"
        :key="item.value"
        :label="item.title"
        :value="item.id"
      >
      </el-option>
    </el-select>
    <!-- :check-on-click-node="true" 点击字复选框勾选-->
    <el-scrollbar style="flex: 1; width: 100%; height: 100%">
      <el-tree
        show-checkbox
        style="background: #fff; height: 98%"
        node-key="id"
        :data="data"
        :default-expanded-keys="defaultKeys"
        highlight-current
        @check="changeStates"
        :check-strictly="checkStrictly"
        :filter-node-method="filterNode"
        ref="tree"
        :expand-on-click-node="false"
        auto-expand-parent
        current-node-key
        :default-checked-keys="[0]"
        :props="defaultProps"
        :load="loadNode"
        lazy
      >
        <span
          class="span-ellipsis"
          slot-scope="{ node, data }"
          style="width: 100%"
        >
          <span :title="node.label" style="float: left">{
   
   {
            node.label.length > 11
              ? node.label.substring(0, 11) + "..."
              : node.label
          }}</span>
          <div
            v-if="
              node.data.type == 1 ||
              node.data.type == 2 ||
              data[0].name == '湖南省'
            "
            @click="admincataDc(node)"
            style="
              width: 15px;
              height: 15px;
              box-sizing: border-box;
              display: inline-block;
              position: absolute;
              right: 40px;
            "
          >
            <i
              class="el-icon-circle-plus"
              style="color: #1a86f0; font-size: 21px"
              title="添加"
            ></i>
          </div>
          <div
            v-if="node.data.type == 2"
            @click="handleDelete(node)"
            style="
              width: 15px;
              height: 15px;
              box-sizing: border-box;
              display: inline-block;
              position: absolute;
              right: 15px;
            "
          >
            <i
              class="el-icon-remove"
              style="color: #1a86f0; font-size: 21px"
              title="删除"
            ></i>
          </div>
        </span>
      </el-tree>
    </el-scrollbar>
    <!-- 林草湿督查添加 -->
    <el-dialog
      title="编目信息"
      :visible.sync="DcdialogVisible"
      v-if="DcdialogVisible"
      width="27%"
      append-to-body
      :close-on-click-modal="false"
      style="margin-top: 1rem"
      :before-close="handleClose"
    >
      <div style="height: 3.5rem">
        <el-scrollbar style="height: 100%">
          <el-row style="padding: 0 0.2rem">
            <el-form
              :rules="rules"
              ref="ruleForm"
              :label-position="labelPosition"
              label-width="2.2rem"
              :model="formInfo"
              class="demo-form-inline"
            >
              <el-row>
                <el-form-item label="编目名称" prop="productName">
                  <el-input
                    v-model="formInfo.productName"
                    placeholder=""
                  ></el-input>
                </el-form-item>
              </el-row>
              <el-row>
                <el-form-item label="同级编目排序" prop="num">
                  <el-input-number
                    v-model="formInfo.num"
                    placeholder=""
                  ></el-input-number>
                </el-form-item>
              </el-row>
            </el-form>
          </el-row>
        </el-scrollbar>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="DcdialogVisible = false">取 消</el-button>
        <el-button
          type="primary"
          style="margin-right: 20px"
          @click="AddproductDisplaySave('ruleForm')"
          >新 增</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { mapActions } from "vuex";
import http from "@/service/interface.js";
export default {
  data() {
    return {
      checkStrictly: false,
      defaultProps: {
        children: "children",
        label: "name",
      },
      defaultKeys: [],
      filterText: "",
      count: 0,
      current_node_key: "",
      Treedata: [
        {
          title: "林草经营档案数据",
          id: "6",
        },
      ],
      treeActive: "6",
      DcdialogVisible: false, //督查新增节点
      formInfo: {
        productName: "",
        num: 1,
      },
      rules: {
        productName: [
          { required: true, message: "请输入编目名称", trigger: "blur" },
        ],
        num: [
          { required: true, message: "请选择同级编目排序", trigger: "blur" },
        ],
      },
      node: null,
      data: [],
      Shengnode: {
        data: {
          id: 10031,
        },
      },
    };
  },
  props: ["activeName", "type"],
  mounted() {
    this.treeChange();
  },
  methods: {
    admincataDc(node) {
      console.log(node);
      this.node = node;
      (this.formInfo = {
        productName: "",
        num: 1,
      }),
        (this.DcdialogVisible = true);
    },
    AddproductDisplaySave(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          http
            .informAdd({
              name: this.formInfo.productName,
              order: this.formInfo.num,
              pid: this.node.data.id,
              type: this.type,
              firstLevel: this.treeActive,
            })
            .then((res) => {
              this.$message.success(res.data);
              this.DcdialogVisible = false;
              let node = {
                level: 1,
                data: {
                  id: this.node.id,
                },
              };
              this.refreshTreeNode(this.node);
            });
        } else {
          this.$message({
            message: "新增校验不通过!",
            type: "warning",
          });
          return false;
        }
      });
    },

    /* 刷新当前节点 */
    refreshTreeNode(node) {
      console.log(node);
      // 更改当前节点的加载状态
      node.loaded = false;
      // 重新加载数据,入参为加载数据完成后执行的回调函数
      node.loadData(() => {
        // 设置选中节点
        this.$refs.tree.setCurrentKey(node?.data?.id || 0);
      });
    },

    /* 刷新父节点 */
    refreshParentTreeNode(node, isChangeSelect) {
      // 更改父节点的加载状态
      node.parent.loaded = false;
      // 重新加载数据
      node.parent.loadData(() => {
        if (!isChangeSelect) {
          // 不改变选中项
          this.$refs.treeRef.setCurrentKey(node?.data?.id || 0);
        } else {
          // 选中父节点
          this.currentNode = node.parent;
          this.$refs.treeRef.setCurrentKey(node.parent?.data?.id || 0);
        }
      });
    },
    treeChange() {
      localStorage.setItem("treeActive", JSON.stringify(this.treeActive));
      this.$emit("treeChange", this.treeActive);
    },
    // tree懒加载
    loadNode(node, resolve) {
      if (node.level === 0) {
        let id = JSON.parse(localStorage.getItem("xzbmCode"));
        let name=localStorage.getItem('xzbmName')
          http
            .findChildrenById({
              id: id,
              type: this.activeName,
              firstLevel: this.treeActive,
            })
            .then((res) => {
              let Mydata = [
                {
                  name: name,
                  id: id,
                  type:1,
                  children: [],
                },
              ];
              this.data = Mydata;
              return resolve(Mydata);
            });
       
      } else if (node.level >= 1) {
        http
          .findChildrenById({
            id: node.data.id,
            type: this.activeName,
            firstLevel: this.treeActive,
          })
          .then((res) => {
            return resolve(res.data);
          });
      }
    },
    // 弹出对话框-删除
    handleDelete(row) {
      let promptMessage = "此操作将永久删除该数据, 是否继续?";
      this.$confirm(promptMessage, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        closeOnClickModal: false,
      })
        .then(() => {
          let obj = {
            id: row.data.id,
            name: row.data.name,
          };
          http.informClear(obj).then((res) => {
            if(res.status!=200){
              this.$message.error(res.data);
              return
            }
            this.$message.success(res.data);
            this.refreshTreeNode(this.node);
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    changeStates(data, node) {
      console.log(data, node);
      this.setNodeIds(node.checkedKeys);
    },
    nextSelectNode() {
      ++this.currentSelectIndex;
      if (this.currentSelectIndex > this.selectList.length - 1) {
        --this.currentSelectIndex;
        return;
      }
      this.moveToCurrentNode(this.selectList[this.currentSelectIndex]);
    },
    preSelectNode() {
      --this.currentSelectIndex;
      if (this.currentSelectIndex < 0) {
        ++this.currentSelectIndex;
        return;
      }
      this.moveToCurrentNode(this.selectList[this.currentSelectIndex]);
    },
    clearSelectNode() {
      this.filterText = "";
      for (var i = 0; i < this.$refs.tree.store._getAllNodes().length; i++) {
        this.$refs.tree.store._getAllNodes()[i].expanded = false;
      }
    },
    moveToCurrentNode(nodeId) {
      this.$refs.tree.setCurrentKey("10140");
      this.$refs.tree.setCurrentKey(nodeId);
      let c = this.$refs.tree.store.nodesMap[nodeId];
      this.expandNode(c);
      let self = this;
      setTimeout(function () {
        self.$el
          .querySelector(".el-tree-node.is-current.is-focusable")
          .scrollIntoView({
            behavior: "smooth", // 平滑过渡
            block: "center", // 上边框与视窗顶部平齐。默认值
          });
      }, 400);
    },
    expandNode: function (node) {
      if (node.parent) {
        node.parent.expanded = true;
        this.expandNode(node.parent);
      }
    },
    filterNode(value, data) {
      if (!value) return true;
      if (data.name.indexOf(value) > -1) {
        this.selectList.push(data.id);
      }
      return true;
    },
    ...mapActions("manage", {
      setNodeIds: "setNodeIds",
    }),
  },
  watch: {
    filterText(val) {
      this.selectList = [];
      this.currentSelectIndex = 0;
      this.count = 0;
      this.$refs.tree.filter(val);
      if (this.selectList.length > 0) {
        this.count = this.selectList.length;
        // 默认选中第一个
        this.moveToCurrentNode(this.selectList[0]);
      }
    },
    data() {
      let arr = [];
      arr = this.data[1] ? this.data[1].children : this.data[0].children;
      if (arr) {
        arr.forEach((item) => {
          this.defaultKeys.push(item.id);
        });
      }
      // this.defaultKeys.push(this.data[1].id, this.data[0].id);
    },
  },
};
</script>

<style lang="less" scoped>
.span-ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.vtree {
  opacity: 0.8;
  background-color: #fff;
  border-radius: 4px 3px 4px 4px;
  border: 1px solid rgba(223, 229, 249, 1);
  text-align: center;
  overflow: auto !important;
  width: 20%;
  display: flex;
  flex-direction: column;
}
.treeInput {
  position: static;
  top: 0;
  left: 0;
}
.title {
  font-size: 17px;
  font-family: "Arial Normal", Arial;
  font-weight: 600;
  font-style: normal;
  width: 80px;
  margin: 10px 0 0 0;
}
.vtree i.el-input__icon.el-icon-search {
  line-height: 2.5;
}
.el-tree {
  color: #606266;
  font-weight: 500;
  overflow: scroll;
}
/deep/ .el-scrollbar__wrap {
  // height: 640px;
  height: 700px;
}
/deep/ .el-scrollbar__view {
  height: 100% !important;
}
.vtree
  .el-tree--highlight-current
  /deep/
  .el-tree-node.is-checked
  > .el-tree-node__content {
  /* background-color: rgba(0,153,250,0.1); */
  color: rgb(64, 158, 255);
}
.vtree
  .el-tree--highlight-current
  /deep/
  .el-tree-node.is-current
  > .el-tree-node__content {
  background-color: rgba(0, 153, 250, 0.1);
  color: #0099fa;
  font-weight: bold;
}
.vtree
  .el-tree--highlight-current
  /deep/
  .el-tree-node.is-focusable
  > .el-tree-node__content {
}
.vtree
  .el-tree--highlight-current
  /deep/
  .el-tree-node.is-focusable
  > .el-tree-node__content:hover {
  background-color: rgba(0, 153, 250, 0.1);
}
.vtree
  .el-tree--highlight-current
  /deep/
  .el-tree-node:focus
  > .el-tree-node__content {
  background-color: rgba(0, 153, 250, 0.1);
}

.search_input /deep/ .el-input__inner {
  height: 32px;
  line-height: 32px;
  border-radius: 30px !important;
  background-color: rgba(234, 234, 234, 0.5) !important;
  color: #999999 !important;
}
.el-tree img,
i {
  vertical-align: middle;
  float: right;
  margin-left: 3px;
  width: 15px;
  height: 15px;
  color: #3c6ef0;
  cursor: pointer;
}
</style>

遅延読み込みケース 2: 

<el-cascader
   ref="cascader"
   :show-all-levels="false"
   expandTrigger="click"
   :options="cityData"
   v-model="cityName"
   placeholder="行政区划"
   class="cascaderBox"
   :props="defaultProps"
   @change="handleChange"
 >
</el-cascader>
-------------------------------------------

      cityData: [],
      cityName: "",
      defaultProps: {
        checkStrictly: true,
        label: "label",
        value: "value",
        children: "children",
        lazy: true,
        lazyLoad: this.lazyLoad,
      },
 handleChange(value) {
      // 选中后自动收起菜单
      if (this.$refs.cascader) {
        this.$refs.cascader.dropDownVisible = false;
      } else {
        return;
      }
      // 解决选中任意一级后出现暂无数据情况
      const panelRefs = this.$refs.cascader.$refs.panel;
      if (panelRefs.activePath.length !== 0) {
        panelRefs.activePath.forEach((item) => {
          if (item.children.length === 0) {
            panelRefs.lazyLoad(panelRefs.getCheckedNodes()[0]);
          }
        });
      }
    },
    getXzqhData() {
      this.cityData = [];
      let xzbmName = localStorage.getItem("xzbmName");
      let value = JSON.parse(localStorage.getItem("xzbmCode"));
      this.cityData.push({
        label: xzbmName,
        value: value,
      });
      this.cityName = value;
    },
    // tree懒加载
    lazyLoad(node, resolve) {
      // level代表当前点击选择哪一项,,比如0代表第一次进去加载数据,1是选择省后的操作
      if (node.level >= 1) {
        http.superCity({ areaCode: node.data.value }).then((res) => {
          if (res.status == 200) {
            var resArr = [];
            let arr = res.data;
            arr.forEach((item) => {
              resArr.push({
                value: item.value,
                label: item.label,
                leaf: Array.from(item.value + "").length == 12,
              });
            });
            return resolve(resArr);
          } else {
            return resolve([]);
          }
        });
      }
    },

おすすめ

転載: blog.csdn.net/ANNENBERG/article/details/130146871
おすすめ