el-tree+懒加载+搜索+可选择节点

9,196 阅读3分钟

写在前面

(此篇涉及的东西都很简单) 我司需求是,勾选选项,保存配置时将选择的选项提交到后台,需要搜索功能,因为数据过多所以需要懒加载。项目是vue+element开发的,所以选择了el-tree。

1.el-tree懒加载

点击一级节点,懒加载对应的二级节点(只有两级)

懒加载树:

<el-tree
    v-if="pzShow"
    show-checkbox
    node-key="code"
    :props="pzProps"
    @check-change="pzCheckedChange"              
    v-loading="pzMapIsLoading"
    element-loading-text="加载中..."
    :default-checked-keys="pzCheckedCode"
    ref="tree"
    lazy
    :load="pzLoadNode" (懒加载)
    accordion
    check-strictly
></el-tree>

数据结构:

pzProps: {
  label: "name",
  children: "children",
  isLeaf: "leaf"
}

node-key绑定的是code,所以根据一级节点的code(可在pzLoadNode方法的第一个参数中获得),获取二级节点。

pzLoadNode(node, resolve) {
  this.pzMapIsLoading = true;
  // 获取一级节点
  if (node.level === 0) {                 
    getPzMapOpts().then(res => {
      this.pzMapIsLoading = false;
      this.pzMap = res.data.data.pzMap;
      return resolve(this.pzMap);
    });
  }
  if (node.level > 1) return resolve([]);
  //获取二级节点
  if (node.level === 1) {
    this.pzMapIsLoading = false;
    getPzMapTree(node.data.code).then(res => {
      this.pzChildrenList = res.data.data;
      if (this.pzChildrenList.length == 0) {
        this.$message.error("数据拉取失败,请刷新再试!");
        return;
      }
      resolve(this.pzChildrenList);
    });
  }
}

2.搜索

我做了两棵树,一棵懒加载树,一棵搜索树。
当时想做在一棵树里,但是搜索树需要一级节点默认展开,而懒加载树要点击一级节点才能展开,这点冲突了。
尝试给load(是否懒加载)和defaule-expand-all(是否全部默认展开)绑定事件,失败。
最终选择做两棵树: 初始展示懒加载树,搜索时懒加载树隐藏,搜索树pzShow:true。

搜索树:

  <el-tree
    v-if="!pzShow"
    :data="pzList"
    show-checkbox
    node-key="code"
    @check-change="pzCheckedChange"
    v-loading="pzSearchMapIsLoading"
    element-loading-text="加载中..."
    :default-checked-keys="pzCheckedCode"
    ref="tree"
    default-expand-all
    check-strictly
  ></el-tree>

3.可选择节点

最开始用的check事件,获取当前节点的信息和已选择的节点组成的数组。

但是!不能和懒加载一起用,如果一级节点没有被点开,这个节点的子节点的选择情况是获取不到的,checkedKeys参数中只有点开过的节点的子节点的选择情况。这导致上一次勾选后,这次不点开,这次保存节点时已选节点里没有上次选择的节点。上次就相当于白选了。这哪能行啊!
并且这个check事件在两棵树已选择节点同步上也很麻烦,要自己写。后改用check-change事件。
因为可以获得当前选中状态发生变化的节点信息,所以在两棵树上绑定同一个默认选中数组:default-checked-keys=“pzCheckedCode”
当选中节点/取消选中时向这个数组中添加/删除节点,这样两棵树共用一组默认选中节点,就可以实现同步啦。
并且未点开的一级节点下的已选择节点已经在默认选中数组中了,就算不点开,保存节点时也不会白选了。

pzCheckedChange(node,checked,leaf) {
  if(checked === true) {
    this.pzCheckedCode.push(node.code);
  } else {
    this.pzCheckedCode = _.difference(this.pzCheckedCode,[node.code]);
  }
}

这算是我进公司实习的第一个独立开发的功能,当时搞得焦头烂额的(自己技术实在烂),然后还出了bug,给同事添了很多麻烦。最终还是搞好了。做完之后才发现其实很简单,没有涉及到很复杂的方法什么的,为什么就搞了那么久。。。挫败

第一次写东西,可能有些地方表达不清楚或者用法不对,恳请大家批评改正!如果有需要我帮助的我会认真解答!谢谢!