美文网首页
《element》el-tree 全选和半选等相关配置

《element》el-tree 全选和半选等相关配置

作者: BA_凌晨四点 | 来源:发表于2021-05-25 17:17 被阅读0次

    <template> 结构:

    <el-tree
      ref="tree"
      :data="dataList"
      show-checkbox
      node-key="id"
      :render-content="renderContent"
      @check="handleCheckChange"
      :default-checked-keys="[1]"
      default-expand-all
      :props="defaultProps"
    ></el-tree>
    

    data:

    data: () => ({
      isCheckAll: false, // 是否全选
      pickStatus: 1, // 0 空,1 半选,
      treeLens: 0, // el-tree 深度
      dataList: [], // 要渲染的成el-tree的数组
      isFirstPickAll: true, // 是不是第一次点击全选的
      defaultProps: { // 渲染el-tree属性参数
        children: 'children',
        label: (data, node) => data,
      },
    });
    

    渲染成HTML

    通过 jsx 渲染,更加灵活

    /**
     * 全选 el-tree 节点
     * @param {function} h VNode,渲染函数
     * @param {Object} node 节点,里面有许多属性,包括data和
    store
     * @param {Object} data 也可以在这里通过获取数据的属性
    (node.label)
     * @param {Object} store
     * @return {Object} jsx表达式
     */
    renderContent(h, { node, data, store }) {
      return (
        <span style="display:flex;">
          <span>
            {node.label.name}
          </span>
          <span style="flex: 0 0 1">{node.label.financialAccountCode}</span>
        </span>
      )
    },
    

    当页面一进来的时候获取选中的状态

        /**
         * 设置已经选中的项
         * @params {Number} sub 类型下标
         */
        async setChecked(sub) {
          const type = sub || this.defaultType
          try {
            const pickedIds = await this.getTypeInfo(type)  // 请求后端获取选中的id
            this.$refs.tree.setCheckedKeys(pickedIds) // 将这些id对应的项 改成勾选状态
            this.handleCheckChange() // 这个函数式用于 判断空状态和半选状态,具体如下面代码片段
          } catch (error) {
            console.log('el-tree 没有完全构建完成')
          }
        },
    

    用于全选

    这里我用了另外的一个独立复选框做全选。

    <el-checkbox
      v-model="isCheckAll"
      @change="pickAll"
      :indeterminate="pickStatus == 1"
    ></el-checkbox>
    

    判断半选状态和空状态

        /**
         * 判断半选状态和空装填
         * @param {Object} data 当前点击的节点数据
         * @param {Object} checked 目前el-tree选中的数据(包括未选中的)
         * 注意:由于该函数一开始运行,是无法获取选中节点的(即没有参数),所以获取选中节点不应该在这里 通过参数获取,这些参数只能勾选某个节点时才能获得
         */
       handleCheckChange(data, checked, indeterminate) {
      // 获取选中的节点
      const picked = this.$refs.tree.getCheckedNodes()
      // 获取半选中节点
      this.halfCheckNodes = this.$refs.tree.getHalfCheckedNodes()
      this.halfStatus = (picked.length > 0) && (picked.length < this.treeLens - 1) // 注意这里要减去深度遍历中的根节点
      // 当选中的节点处于 > 0,并 < 整棵树的深度时候,则开启半选
    },
    

    什么时候是空状态?当不处于半选,并且不处于全选的时候就是空。
    也就是 indeterminate 为false,并且 checkbox 为不选中

    获取树的深度

    /**
     *  获取数据深度,用于全选时候做判断
     * @returns
     */
    getTreeLens() {
      //  获取根节点
      const rootNode = this.$refs.tree && this.$refs.tree.getNode
    (this.dataList[0].id).parent
      const _this = this
      // travelNodes(rootNode)
      ;(function travelNodes(tmpRoot) {
        // 选中该节点
        // tmpRoot.checked = true;
        _this.treeLens++ // 这里开始计算
        // 叶子节点
        try {
          if (tmpRoot.childNodes.length) {
            // 不是叶子节点,递归遍历
            const tmpChildNoes = tmpRoot.childNodes
            for (let i = 0; i < tmpChildNoes.length; i++) {
              travelNodes(tmpChildNoes[i])
            }
          }
        } catch (err) {
          console.log('el-tree没有完全渲染完..')
        }
      })(rootNode)
    },
    

    它的原理是:
    其实就像普通的复选框,双向绑定的 checkbox,点击就是选中状态。
    不过为了还要显示出半选状态,所以要依赖属性indeterminate。当indeterminate的值为 true,即半选状态。

    用于全选的处理函数

        /**
         * 全选 el-tree 节点
         */
        pickAll() {
          this.pickStatus = 0 // 先设置为空状态(为的就是 indeterminate 这个属性为false,才能为选中状态)
    
          // 先判断是不是第一次点击,因为第一次点击,无论处于什么状态 肯定是要全选的
          if (this.isFirstPickAll) {
            this.$refs.tree.setCheckedNodes(this.dataList)  // 设置所有节点为选中状态
            this.isFirstPickAll = false
          } else { // 第一次以后:
            if (this.isCheckAll) { // 那个另外的独立复选框勾选了
              this.$refs.tree.setCheckedNodes(this.dataList) // 设置所有节点为选中状态
            } else {
              this.$refs.tree.setCheckedKeys([]) // 设置所有节点为空状态
            }
          }
    
        // 最后判断一下状态
        this.handleCheckChange();
    
        },
    

    保存设置

    <button @click="save">保存</button>
    
    save() {
    // 获取选中状态的 key
    const pickedKeys = this.$refs.tree.getCheckedKeys()
    // 获取半选状态的 key
    const halfPickedKeys = this.halfCheckNodes.reduce(
      (acc, item) => {
        acc.push(item.id)
        return acc
      },
      [],
    )
    // 拿到选中的key后,然后该干嘛干嘛...
    }
    

    组件挂在完成后:

      async mounted() {
        await this.setChecked() // 设置后端传来的选中的节点
        this.getTreeLens() // 获取树的长度
        this.handleCheckChange(); // 设置当前状态(半选、全选、空)
      },
    

    总结:

    <el-checkbox
      v-model="isCheckAll"
      @change="pickAll"
      :indeterminate="halfStatus"
    ></el-checkbox>
    

    v-model 选中状态,并且indeterminatefalse,则该复选框为选中状态,indeterminatetrue为半选状态,两个都为 false,则空状态

      // 获取选中的节点
      const picked = this.$refs.tree.getCheckedNodes()
      // 获取半选中节点
      this.halfCheckNodes = this.$refs.tree.getHalfCheckedNodes()
    
     // 1.通过node获取
      // console.log('通过node获取', this.$refs.tree.getCheckedNodes())
      // 2.通过key获取
      // console.log('通过key获取', this.$refs.tree.getCheckedKeys())
    
    this.$refs.tree.setCheckedKeys(pickedIds) // 将这些id对应的项 改成勾选状态
    this.$refs.tree.setCheckedNodes(this.dataList) // 设置所有节点为选中状态
    
    // 获取选中状态的 key
    const pickedKeys = this.$refs.tree.getCheckedKeys()
    // 获取半选状态的 key
    const halfPickedKeys = this.halfCheckNodes.reduce(
      (acc, item) => {
        acc.push(item.id)
        return acc
      },
      [],
    )
    

    相关文章

      网友评论

          本文标题:《element》el-tree 全选和半选等相关配置

          本文链接:https://www.haomeiwen.com/subject/bnzxsltx.html