数据动态变化时实现多选及回显

复制代码
<template>
  <el-dialog title="设置权限" :visible.sync="showDialog" :close-on-click-modal="false" :append-to-body="true" width="800px">
    <div v-loading="loading">
      <el-radio-group v-model="setPowerRadio">
        <el-radio :label="0" style="display:block;line-height: 30px;">所有人可见</el-radio>
        <el-radio :label="1" style="display:block;line-height: 30px;">选择可见</el-radio>
      </el-radio-group>
      <div v-show="setPowerRadio==1">
        <el-row>
          <el-col :span="10" style="height: 300px;border: 1px solid #CBCBCB;">
            <div class="power-department-border">部门</div>
            <el-tree :data="unitsList" :empty-text="emptyText" node-key="id" ref="tree" :default-expand-all="true"
              :highlight-current="true" :render-content="renderContentStation" @node-click="handleNodeClick"
              class="power-col-left-border"></el-tree>
          </el-col>
          <el-col :span="14" style="padding: 0 10px;height: 300px;">
            <!-- ref="multipleTable" -->
            <!--选择项发生变化 @selection-change="handleSelectionChange" -->
            <el-table border :data="tableData" tooltip-effect="dark" style="width: 100%" ref="multipleTable"
              @select="handleSelectionRow" @select-all="handleSelectionAll" class="power-col-right-overflow">
              <el-table-column type="selection" width="55">
              </el-table-column>
              <el-table-column prop="userName" label="姓名">
              </el-table-column>
            </el-table>
          </el-col>
        </el-row>
        <div class="select-people">
          <div>已选择({{ tableDataRight.length }}):</div>
          <div>
            <span v-for="(item, index) in tableDataRight" :key="index">
              {{ item.userName }}<span v-if="tableDataRight.length != index + 1">,</span>
            </span>
          </div>
        </div>
      </div>
      <div class="text-center-margin-20-0">
        <el-button @click="showDialog = false">取 消</el-button>
        <el-button type="primary" @click="onSubmit()">确 定</el-button>
      </div>
    </div>
  </el-dialog>
</template>
<script>
  export default {
    data() {
      return {
        showDialog: false,
        loading: false,
        setPowerRadio: 0, //0所有 1选择
        CurrentDepartmentId: "", //当前部门id
        unitsList: [], //部门数组
        filterText: '', //关键字查询
        emptyText: '',
        id: '', //父组件id
        tableData: [], //人员显示
        leftCodes: [], //左侧列表id集合
        tableDataRightCodes: [], //选中的人员id数组
        tableDataRight: [], //选中的人员总数据
        search: 0, // 1.搜索开始  0搜索结束
      };
    },
    watch: {
      filterText(val) {
        this.$refs.tree.filter(val);
      },
    },
    methods: {
      add(row, type) {
        this.showDialog = true;
        this.routerType = type;
        this.$nextTick(() => {
          if (row.fid) {
            this.id = row.fid;
          } else {
            this.id = row.id;

          }
          this.getCatetoryAuthLink(); //获取指定分类授权信息
          this.getDepartmentLink();
        });
      },
      //获取指定分类授权信息
      getCatetoryAuthLink() {
         //读初始选中的信息
         this.tableDataRight = res.data.data.userList; 
         this.leftCodes = this.tableDataRight.map(dev => dev.id);
      },
      //获取左侧树型数据
      getDepartmentLink() {
        this.unitsList = []
        this.loading = true;
        this.search = 1;
        getDepartment().then(res => {
          if (res.data.code == 200) {
            let dataLink = res.data.data
            this.unitsList = dataLink.list;
            this.$nextTick(() => {
              this.loading = false;
              if (dataLink.list.length != 0) {
                this.CurrentDepartmentId = dataLink.list[0].id;
                this.$refs.tree.setCurrentKey(dataLink.list[0].id);
                this.getNewPeople(dataLink.list[0].id);
              }
            })
          } else {
            this.loading = false;
            this.emptyText = '暂无数据'
            this.$message.error(res.data.msg);
          }
        });
      },
      //树-转换
      handleNodeClick(value) {
        this.CurrentDepartmentId = value.id;
        this.search = 1;
        this.$nextTick(() => {
          this.getNewPeople(value.id);
        })
      },
      //部门下的人员
      getNewPeople(id) {
        this.tableData = []
        let param = {
          departmentId: id,
          page: false,
        }
        getUserList(param).then(res => {
          if (res.data.code == 200) {
            this.tableData = res.data.data.list;
            this.defaultChoose(this.tableDataRight, this.tableData);
            this.$nextTick(() => {
              this.search = 0;
            });
          } else {
            this.$message.error(res.data.msg);
          }
        });
      },
      //选择单行
      handleSelectionRow(row, selected) {
        if (this.search) return;
        let booleanValue = this.tableDataRight.some(item => {
          return item.id == selected.id
        })
        //包含
        if (booleanValue) {
          this.tableDataRight = this.tableDataRight.filter(item => item.id != selected.id)
        } else {
          this.tableDataRight.push(selected)
        }
      },
      //全选/取消全部
      handleSelectionAll(selection) {
        if (this.search) return;
        if (selection.length != 0) {
          let arr = [...this.tableDataRight, ...selection];
          this.$nextTick(() => {
            // this.tableDataRight = Array.from(new Set(arr)) //简单去重
            let unique = new Map(); //复杂去重
            arr.forEach(item => unique.set(item.id, item));
            this.tableDataRight = [...unique.values()];
          })
        } else {
          this.tableData.forEach(item => {
            this.tableDataRight = this.tableDataRight.filter(ele => ele.id != item.id)
          })
        }
      },
      // 已选择的设备需要默认勾选
      // arr所有选中的;tableArr右侧表格显示数据
      defaultChoose(arr, tableArr) {
        /*
        注意:这里不能直接遍历arr,element和item 他们在内存中的地址不同,所以他们是两份不同的数据,所以这么写 toggleRowSelection(element, true) 是不会回显选中的
         */
        for (let index = 0; index < tableArr.length; index++) {
          const item = tableArr[index];
          arr.forEach(element => {
            if (element.id == item.id) {
              this.$nextTick(() => {
                this.$refs.multipleTable.toggleRowSelection(item, true);
              });
            }
          });
        }
      },
      //处理名称-站点
      renderContentStation(h, {
        node,
        data,
        store
      }) {
        return ( < div >
          <span title = {
            data.departmentName
          }
          class = 'style-demo' > {
            data.departmentName
          } </span> </div > );
      },
      onSubmit() {
        if (this.setPowerRadio == 1 && this.tableDataRight.length == 0) {
          this.$message.warning("选择人员不可为空");
          return false;
        }
        let userIdList = this.tableDataRight.map(dev => dev.id);
        let param = {}
        if (this.routerType == '素材分类') {
          param = {
            categoryId: this.id,
            fvisible: this.setPowerRadio,
            userIdList: userIdList,
          }
        } else { //素材审核  素材管理
          param = {
            recordId: this.id,
            fvisible: this.setPowerRadio,
            userIdList: userIdList,
          }
        }
        let urlLink = null
        if (this.routerType == '素材分类') {
          urlLink = setCatetoryAuth;
        } else {
          urlLink = setRecordAuth;
        }
        urlLink(param).then(res => {
          if (res.data.code == 200) {
            this.$message.success("操作成功");
            this.showDialog = false;
            if (this.routerType == '素材分类' || this.routerType == '素材管理') {
              this.$emit("refresh");
            }
          } else {
            this.$message.error(res.data.msg);
          }
        });
      }
    }
  }

</script>
<style scoped>
  .select-people {
    border: 1px solid #CBCBCB;
    background: #F0F5F7;
    color: #000000;
    margin: 10px;
    width: calc(100% - 20px);
    min-height: 100px;
    padding: 10px;
    box-sizing: border-box;
  }

  .power-department-border {
    border: 1px solid #CBCBCB;
    background: linear-gradient(180deg, #F0F5F7 93%, #DFE4E6 97%);
    box-sizing: border-box;
    vertical-align: middle;
    text-align: center;
    line-height: 1.5;
    padding: 5.5px 0;
    font-weight: bold;
    color: #666666;
    font-size: 16px;
    font-size: calc(var(--scale) * 16px);
    border-bottom: 1px solid #CBCBCB;
  }

</style>
相关推荐
dsyyyyy11016 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen6 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客8 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖8 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty8 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚9 小时前
软件测试期末考试
vue.js
小二·9 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜10 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain50910 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年27511 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax