【仿el-transfer穿梭框】el-tree+el-table组合实现,踩坑记

效果图如下:
【仿el-transfer穿梭框】el-tree+el-table组合实现,踩坑记_第1张图片
样式代码:

    <el-dialog
      title="请选择xx组"
      :visible.sync="quoteDialog"
      width="70%"
      :close-on-click-modal="false"
    >
      <el-row>
        <el-col :span="9" :xs="24" style="margin-left: 30px">
          <el-card class="box-card">
            <div style="margin: 30px 10px 30px 10px; height: 300px">
              <el-tree
                ref="tree"
                :data="departTree"
                node-key="id"
                :props="defaultProps"
                :filter-node-method="filterNode"
                :render-content="renderContent"
                show-checkbox
                @check-change="handleCheckChange"
              />
            </div>
          </el-card>
        </el-col>
        <el-col :span="4" :xs="24">
          <div class="transfer" style="margin-left: 20px">
            <el-button
              icon="el-icon-arrow-right"
              class="mr10"
              @click="transferRight"
            ></el-button>
            <el-button
              icon="el-icon-arrow-left"
              class="mr10"
              style="margin-top: 30px"
              @click="transferLeft"
            ></el-button>
          </div>
        </el-col>
        <el-col :span="9" :xs="24">
          <el-card class="box-card">
            <div style="margin: 30px 10px 30px 10px">
              <el-table
                width="100%"
                ref="staffTable"
                height="300px"
                border
                @row-click="rowuseClick"
                @selection-change="handleSelect"
                :data="tableRightData"
              >
                <el-table-column
                  type="selection"
                  width="55"
                  align="center"
                ></el-table-column>
                <el-table-column label="" align="center" prop="groupName" />
              </el-table>
            </div>
          </el-card>
        </el-col>
      </el-row>
      <!--脚-->
      <div slot="footer" class="dialog-footer">
        <el-button @click="sure" type="primary">确 认</el-button>

        <el-button @click="quoteDialog = false">取 消</el-button>
      </div>
    </el-dialog>

主要思路就是左树右表,
通过树的复选框勾选事件,选中项push到临时数组,点击右箭头赋值给右侧的列表
通过列表的复选框勾选事件,重新设置勾选节点数组,踩坑也就是在这里踩的

仅贴相关代码,有啥问题欢迎沟通交流

//树复选框事件
    handleCheckChange(data, checked) {
    //向临时数组里追加选中项
      if (checked) {
        this.tempArr.push(data);
      }
//getCheckedKeys可以获取已勾选的节点数组,保存下来,后面要用
      this.getTreekey = this.$refs.tree.getCheckedKeys();
    }, 
//向右箭头点击事件
    transferRight() {
      // 右侧表格拼接左侧选中项(即临时数组)
      this.tableRightData = this.tableRightData.concat(this.tempArr);
      let result = [];
      //双重for循环,定义flag变量,先向result中追加一项,然后走内部的循环去比对,找不到还是会继续向result中追加一项,直到找到相同的id,这么做是因为每次选完后,如果再打开弹窗重新勾选,对比两次重复勾选项,有相同id的不会push到result数组里,这样保证result里都是唯一id的
      for (let i = 0; i < this.tableRightData.length; i++) {
        let flag = true;
        for (let j = 0; j < result.length; j++) {
          if (this.tableRightData[i].id === result[j].id) {
            flag = false;
          }
        }
        if (flag) {
          result.push(this.tableRightData[i]);
        }
      }
      this.tableRightData = result;
    },

//列表复选框事件,选中项赋值给selectRightData 数组
   handleSelect(sele, row) {
      this.selectRightData = sele;     
    },
   /** 向左箭头点击事件*/
   //比较重要的就是这个
    transferLeft() {
    //过滤右侧列表数组,和列表选中数组进行对比,!this.selectRightData是取反,即右侧列表数组不包含选中数组的内容
      this.tableRightData = this.tableRightData.filter(
        (item) => !this.selectRightData.some((ele) => ele.id === item.id)
      );
      //this.getTreekey在树复选框的时候把节点id存起来了,这里要用到
      let arr = [];
      arr = this.getTreekey.filter(
      //过滤已有的树节点,筛选不包含列表选中的节点组成新的数组
        (item) => !this.selectRightData.some((ele) => ele.id === item)
      );
    //调用setCheckedKeys,重新设置树选中节点
      this.$refs.tree.setCheckedKeys(arr);
     
    },

你可能感兴趣的:(bug收录,前端,vue.js)