自学内容网 自学内容网

基于el-tree实现懒加载穿梭条

一、关键代码 
<template>
  <div>
    <!-- 左侧待选列表 -->
    <div class="left-box">
      <p>待选列表</p>
      <el-input placeholder="输入关键词过滤" v-model="leftFilterText" clearable/>
      <el-tree
        ref="treeLeft"
        :data="leftData"
        show-checkbox
        node-key="id"
        props="defaultProps"
        :load="loadNode"
        lazy
        :filter-node-method="filterNode"  
      >
      </el-tree>
    </div>
    <!-- 穿梭按钮 -->
    <div class="oper-box">
      <el-button circle type="primary" icon="el-icon-arrow-left" @click="removeData"></el-button>
      <el-button circle type="primary" icon="el-icon-arrow-right" @click="addData"></el-button>
    </div>
    <div class="right-box">
      <p>已选列表</p>
      <el-input placeholder="输入关键词过滤" v-model="rightFilterText" clearable/>
      <el-tree
        ref="treeRight"
        :data="rightData"
        show-checkbox
        node-key="id"
        props="defaultProps"
        :filter-node-method="filterNode"  
      >
      </el-tree>
    </div>
  </div>
</template>

<script>
  data(){
    return {
      checkAll: false,
      leftFilterText: '',
      rightFilterText: '',
      defaultProps: {
        chilren: 'children',
        label: 'labelName',   // 适配后端下发的数据字段名
        isLeaf: 'leaf',   // leaf 字段判断节点是否为叶子节点
        // 配置禁选的节点
        disabled: function(data, node) {
          // 如这里配置父节点、带有disable属性的节点禁选
          if('children' in data || data.disable) {
            return true;
          } else {
            return false;
          }
        }
      },
      leftData: [],
      rightData: []
    }
  },
  watch: {
    leftFilterText(val) {
      this.$refs.treeLeft.filter(val);
    },
    rightFilterText(val) {
      this.$refs.treeRight.filter(val);
    }
  },
  methods: {
    // 根据关键词过滤节点
    filterNode(value, data) {
      if(!value) return true;
      // labeName 为defaultProps中配置的label值,未配置默认为label
      return data.labeName.indexOf(value) !== -1;
    },
    // 懒加载出树结构的最后一层节点
    async loadNode(node, resolve) {
      if(node.level === 0) {
        return resolve(node.data);   // 顶层数据默认展示
      } else {
        if(node.data.children && node.data.children.length > 0) {
          return resolve(node.data.children);
        } else {  // 最后一层数据,异步懒加载
          let tempData = await this.getDynamicData(node.data.id);
          return resolve(tempData);
        }
      }
    },
    // 获取数据接口
    getDynamicData(id) {
      
    },
    // 移除节点
    removeData() {
      // 右侧选中节点
      let removeKeys = this.$refs.treeRight.getCheckedKeys();
      this.rightData = this.rightData.filter(item => !removeKeys.includes(item.id));

      // 左侧:仅保留右侧列表中有的数据为勾选状态
      let leftCheckKeys = this.rightData.map(item => item.id);
      this.$refs.treeLeft.setCheckedKeys(leftCheckKeys);
    },
    // 添加节点
    removeData() {
      // 获取左侧选中节点,作为右侧的数据
      let checkNodes = this.$refs.treeLeft.getCheckedNodes();
      let checkKeys = this.$refs.treeLeft.getCheckedKeys();
      this.rightData = checkNodes;
    },
  }
</script>



🎨 过滤节点函数:filterNode

1、watch 监听关键词;filterNode 必须有返回值,否则数据显示不出来;

2、关键词不为空时,函数的返回值 data.labeName.indexOf(value) !== -1; 其中 labeName 为defaultProps中配置的label值,未配置默认为label

🎨 异步加载函数:loadNode

根据 node.level 去匹配数据层级,判断是否需要调用接口获取数据

🎨 样式自定义

二、最终效果:(效果图仅供参考)

(1) 左侧列表为树形结构,且最后一级节点懒加载;(数据量大时,可以有效提高加载速度)

(2)右侧选中的列表无树形结构,为左侧选中的所有节点


原文地址:https://blog.csdn.net/m0_48571414/article/details/136512501

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!