【Vue项目实战7】(下)el-tree==>【node-click】点击节点展示全部父节点信息==>使用$store封装全局组件

1,258 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

上一节回顾:juejin.cn/post/711126…

一、【实战】添加节点点击函数==> 点击展示全部节点信息

 

@node-click="handle"

 功能说明:(1)点击节点,获取选中节点(node); (2)获取选中节点的父节点 ==> 进而获取选中节点的所有父节点(用于展示全部选择路径)

使用到的函数

(1)node-click 节点被点击时的回调.共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。

(2)getCurrentKey() 获取当前被选中节点的 key,必须设置 node-key 属性,若没有节点被选中则返回 null

1.node-click说明

节点被点击时的回调.共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。

      console.log("this is node:", node);
    },

  我们可以通过点击函数node-click,在函数中使用node,获取到当前选中节点的全部信息(包含id,name,parentId,以及他全部children信息)

2.getParent获取选中节点所有父节点(递归实现)

    getParent(array, key) {
      let result = [];
      let toToo = true;
      const catchData = (array, key) => {
        array.forEach((item) => {
          if (!toToo) return;
          result.push(String(item["name"]));
          if (item["id"] === key) {
            toToo = false;
          } else if (item["children"]) {
            catchData(item["children"], key);
          } else {
            result.pop();
          }
        });
        toToo && result.pop();
      };
      catchData(array, key);
      console.log(result, "result");
      return result;
    },

返回的parent数组如下

3.判断展示全部节点信息

前端通过判断treeGroup的长度来控制显示。

在handel函数中调用获取全部父节点信息的函数

        <el-col :span="24">
          <p>
            资源分组:
            {{ this.treeGroup[0] }}
            <i
              class="el-icon-d-arrow-right"
              v-if="this.treeGroup.length > 1"
            ></i>
            {{ this.treeGroup[1] }}
            <i
              class="el-icon-d-arrow-right"
              v-if="this.treeGroup.length > 2"
            ></i>
            {{ this.treeGroup[2] }}
            <i
              class="el-icon-d-arrow-right"
              v-if="this.treeGroup.length > 3"
            ></i>
            {{ this.treeGroup[3] }}
            <i
              class="el-icon-d-arrow-right"
              v-if="this.treeGroup.length > 4"
            ></i>
            {{ this.treeGroup[4] }}
          </p>
        </el-col>
      </div>
      // console.log("this is node:", node);
      let selectKey = "";
      let parent = [];
      selectKey = this.$refs.tree.getCurrentKey(); //当前选中节点id
      parent = this.getParent(this.$refs.tree.data, selectKey);
      this.treeGroup = parent;
      // console.log("parent", parent);
      selectKey = this.$refs.tree.getCurrentKey();
      parent = this.getParent(this.$refs.tree.data, selectKey);
    },

二、【实战】全局使用tree组件==>使用$store存储全局变量

前情提要:由于多个页面都需要使用到资源树组件进行辅助查询,甲方要求把这个资源树放在全局的导航路由sidebar中.对于需要Tree组件时显示,不需要的时候隐藏。


1.Vuex的使用

在vue的项目里父子组件间可以用props 或者 $emit 等方式 进行数据传递,而如果项目稍微大一点的话有很多平行组件,这个时候在这些组件间传递数据,使用这些方法会比较麻烦,在本案例中,Tree资源树组件和页面没有父子组件之间的关系,而且需要多处使用到,因此我们可以vuex来解决这个问题。

参考链接: https://www.jb51.net/article/191612.htm

2. store全局参数和函数

接下来的主要代码在store/index.js中 treeData getTree() 用于存储资源树数据

treeShow treeVis() 用于控制资源树的显示与隐藏

treeGroup getNode() 上一节提到过的,用于存储选中节点的全部父节点信息数组

treeGroupKey getNodeKey() 用于存储当前选中节点的groupid

leaf getLeaf() 用于存储选中节点

const store = new Vuex.Store({
  modules: {
    app,
    user,
    tagsView,
    permission,
    settings,
  },
  state: {
    treeData: [],
    // 控制左侧树的显示
    treeShow: false,
    // 选中节点的上级节点
    treeGroup: [],
    // 选中节点的groupid
    treeGroupKey: "",
    // 叶节点
    leaf:[],
  },
  getters,
  mutations: {
    // 控制左侧树的显示
    treeVis() {
      this.state.treeShow = true;
    },
    // 获取选中的上级节点
    getNode(state, parent) {
      state.treeGroup = parent;
    },
    // 获取选中节点的groupid
    getNodeKey(state, key) {
      state.treeGroupKey = key;
    },
    getLeaf(state,parent){
      state.leaf = parent
    },
    getTree(state, data) {
      state.treeData = data;
    },
  },
});
 
export default store;

3.如何在页面中使用

(1)sidebar中引用Tree组件

(2)this.$store.commit存储数据

step 1:  在Tree组件中,使用 this.$store.commit("getTree", res);存储整个树结构数据到全局的treeData中。(这里展示调接口获取的数据存储)

    // 获取资源分组树结构
    // this.getGroupTree();
// },
getGroupTree() {
      getResourceGroupTree().then((response) => {
        var res = response.data;
        this.$store.commit("getTree", res);    // treeData
      });
    },

step 2:  在handel节点点击函数中,存储节点信息。

使用this.store.commit("getNode", parent);将选中节点的全部父节点信息通过getNode存储到全局的treeGroup中;使用this.store.commit("getNode", parent); 将选中节点的全部父节点信息通过getNode存储到全局的treeGroup中; 使用this.store.commit("getNodeKey", selectKey);将选中节点的key值通过getNodeKey存储到treeGroupKey中

      let selectKey = "";
      let parent = [];
      if (node.children.length > 0) {
        this.$store.commit("getLeaf", "");
      } else {
        console.log("叶");
        selectKey = this.$refs.tree.getCurrentKey();
        parent = this.getParent(this.$refs.tree.data, selectKey);
        this.$store.commit("getLeaf", parent);
      }
      selectKey = this.$refs.tree.getCurrentKey();
      parent = this.getParent(this.$refs.tree.data, selectKey);
      this.$store.commit("getNode", parent);
      this.$store.commit("getNodeKey", selectKey);
    },

(3)页面中通过this.$store.state使用全局数据

step  1:   使用this.$store.state.treeShow = true;展示全局资源树组件

    this.getResourceList();
    this.$store.state.treeShow = true;
  },
destroyed() {
    this.$store.state.treeShow = false;
  },

step 2: 在页面通过this.$store.state.treeGroup展示选中资源树信息

            ><p>
              资源分组:
              {{ this.$store.state.treeGroup[0] }}
              <i
                class="el-icon-d-arrow-right"
                v-if="this.$store.state.treeGroup.length > 1"
              ></i>
              {{ this.$store.state.treeGroup[1] }}
              <i
                class="el-icon-d-arrow-right"
                v-if="this.$store.state.treeGroup.length > 2"
              ></i>
              {{ this.$store.state.treeGroup[2] }}
              <i
                class="el-icon-d-arrow-right"
                v-if="this.$store.state.treeGroup.length > 3"
              ></i>
              {{ this.$store.state.treeGroup[3] }}
              <i
                class="el-icon-d-arrow-right"
                v-if="this.$store.state.treeGroup.length > 4"
              ></i>
              {{ this.$store.state.treeGroup[4] }}
            </p></el-col
          >

step 2:  结合查询函数查询信息

    getResourceList() {
      console.log(this.$store.state.treeGroupKey);
      const params = {
        ...this.queryParams,
        groupId: this.$store.state.treeGroupKey,  // 资源树选中资源的groupid
      };
      getResource(params).then((response) => {
        this.resourceData = response.data.list;
        this.total = response.data.totalCount;
      });
    },