在table表格向后端传递勾选数据的时候,难免有时间后,点击当前行的时候,需要知道当前行的checkbox状态,进行一些其他的操作,但是element-ui没有提供,对应的直接api属性

这里我要对select的API方法进行处理,达到我想知道当前行checkbox的是否选中的状态

<el-table
                  ref="multipleTable"
                  :data="addMemberList"
                  tooltip-effect="dark"
                  style="width: 100%"
                  height="420px"
                  max-height="420px"
                  @select="handleUserMemberChangeRow"
                  @select-all="handleUserMemberChange"
                  @selection-change="handleUserMemberChange"
                >

</el-table>

实现思路:通过当前行row的数据,是否在已选择的selection数组中,来判断

// 单个勾选
		handleUserMemberChangeRow(selection, row){
			// 根据当前行是否在selection中,来判断是否勾选,如果是去掉勾选,需要在选中值中去掉
			if(!selection.find(m=> m.user_id == row.user_id)){
				// 不在,说明当前row,没有被选中
                // 执行一些类似过滤的方法
                let zzSelectArr = this.selectedMemberList.filter(item =>                         item.user_id !== row.user_id);
				this.selectedMemberList = JSON.parse(JSON.stringify(zzSelectArr));
			}else{
              // 当前行被选中了
            }
		},

模块功能示意图:

 

此处附上完整代码:

<template>
  <el-drawer
    title="添加成员"
    :visible.sync="drawerFlag"
    direction="rtl"
    size="80%"
    ref="drawer"
    :append-to-body="true"
    :modal-append-to-body="true"
    custom-class="member-drawer"
    @closed="close"
  >
    <div class="ts-drawer-c">
      <div class="member-c">
        <div class="member-public-c">
          <div class="title">成员检索</div>
          <el-tabs v-model="searchType" type="card">
            <el-tab-pane label="成员" name="user">
              <div class="search-c">
                <el-input
                  placeholder="根据姓名、邮箱模糊检索"
                  v-model="userSearchValue"
                  @input="handleUserSearchChange"
                  suffix-icon="el-icon-search"
                >
                </el-input>
              </div>
              <div class="list-c">
                <el-table
                  ref="multipleTable"
                  :data="addMemberList"
                  tooltip-effect="dark"
                  style="width: 100%"
                  height="420px"
                  max-height="420px"
                  @select="handleUserMemberChangeRow"
                  @select-all="handleUserMemberChange"
                  @selection-change="handleUserMemberChange"
                >
                  <el-table-column
                    type="selection"
                    :selectable="checkSelectable"
                    width="55"
                  >
                  </el-table-column>
                  <el-table-column prop="alias_name" label="名称" width="200">
                  </el-table-column>
                  <el-table-column
                    prop="email"
                    label="邮箱"
                    show-overflow-tooltip
                  >
                  </el-table-column>
                </el-table>
              </div>
            </el-tab-pane>
            <el-tab-pane label="组织结构" name="organization">
              <div class="search-c">
                <el-input
                  placeholder="根据部门、姓名模糊检索"
                  v-model="organizeSearchValue"
                  @input="handleOrganizeSearchChange"
                  suffix-icon="el-icon-search"
                >
                </el-input>
              </div>
              <div class="tree-c">
                <el-tree
                  :data="orgMemberList"
                  :props="{
                    label: 'node_name',
                    children: 'children',
                  }"
                  :default-expanded-keys="expandedKeys"
                  show-checkbox
                  @check="handleCheckNodeChange"
                  :filter-node-method="filterNode"
                  node-key="node_id"
                  ref="orgTree"
                >
                  <div class="custom-tree-node" slot-scope="{ node, data }">
                    <span class="node_type_icon">
                      <i
                        class="el-icon-folder"
                        v-if="data.node_type === 'dep'"
                      ></i>
                      <i class="el-icon-user" v-else></i>
                    </span>
                    <span>{{ node.label }}</span>
                  </div>
                </el-tree>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
        <div class="transfer-c">
          <svg-icon icon-class="ts-transfer" class="transfer-icon"></svg-icon>
        </div>
        <div class="member-selected-c">
          <div class="header-c">
            <div class="title">
              已选择成员(共<span>{{ selectedMemberList.length }}人</span>)
            </div>
          </div>
          <div class="list-c">
            <div class="list-c">
              <el-table
                :data="selectedMemberList"
                tooltip-effect="dark"
                style="width: 100%"
                height="520px"
                max-height="520px"
              >
                <el-table-column prop="alias_name" label="名称" width="120">
                </el-table-column>
                <el-table-column
                  prop="email"
                  label="邮箱"
                  width="150"
                  show-overflow-tooltip
                >
                </el-table-column>
                <el-table-column>
                  <template slot-scope="scope">
                    <el-tooltip
                      class="item"
                      effect="dark"
                      content="删除"
                      placement="top"
                    >
                      <i
                        class="el-icon-delete"
                        @click="deleteSelectedMember(scope.row)"
                      ></i>
                    </el-tooltip>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="drawer_footer">
      <el-button @click="drawerFlag = false">取 消</el-button>
      <el-button
        type="primary"
        :loading="submitLoading"
        :disabled="selectedMemberList.length === 0"
        @click="addMembers"
        >{{ submitLoading ? "提交中..." : "确定" }}
      </el-button>
    </div>
  </el-drawer>
</template>

<script>
import * as requestMethod from "../../../../api/applicationCenter/applicationSystem";

export default {
  name: "addMemberDrawer",
  props: {
    app_id: {
      type: Number,
    },
    org_id: {
      type: Number,
    },
  },
  data() {
    return {
      drawerFlag: true,
      submitLoading: false,
      searchType: "user", // 用户:user、 组织结构:organization
      userSearchValue: "",
      organizeSearchValue: "",
      hadMemberList: [], // 已经拥有的成员列表
      originAddMemberList: [], // 左侧初始添加成员列表原始数据
      addMemberList: [], //  左侧添加disabled属性的数据
      orgMemberList: [], // 组织成员列表
      expandedKeys: [], // 默认展开keys,
			originSelectedMemberList: [], // 存储原始已选择的成员信息
      selectedMemberList: [], // 右侧被选中成员列表
    };
  },
  created() {
    this.getMemberData();
  },
  methods: {
    //api交互
    async getMemberData() {
      await this.getHadMemberList();  // 获取已存在成员数据
      this.getAddMemberList(); // 获取左侧成员列表
      this.getAddMemberListByORG();
    },
    getHadMemberList() {
      let param = {
        app_id: this.app_id,
      };
      return requestMethod
        .getMemberList("get", param)
        .then((res) => {
          if (res.code === 200) {
            this.hadMemberList = res.data.items;
						let getOriginData = res.data.items.map((item) => {
              let zz = {};
              zz.email = item.email_address;
              zz.alias_name = item.user_name;
              zz.user_id = item.user_id;
              zz.app_user_id = item.app_user_id;
              zz.role_name = item.role_name;
              zz.role_id = item.role_id;
							zz.disabled = true;
              return zz;
            });
            this.selectedMemberList =  JSON.parse(JSON.stringify(getOriginData)); // 右侧选择值
						this.originSelectedMemberList =  JSON.parse(JSON.stringify(getOriginData)); // 右侧原始选择值
          } else {
            this.$message.error(res.message);
          }
          this.memberTableLoading = false;
        })
        .catch((err) => {
          this.$message.error(err.message);
        });
    },
    getAddMemberList() {
      let params = {
        org_id: this.org_id,
      };
      return requestMethod.getAddMemberList("get", params).then((res) => {
        if (res.code === 200) {
          let memberList = res.data.items.map((item) => {
            item.disabled = false;
            this.hadMemberList.forEach((hadItem) => {
              if (hadItem.user_id === item.user_id) {
                item.disabled = true;
              }
            });
            return item;
          });
          this.originAddMemberList = JSON.parse(JSON.stringify(memberList)); // 左侧原始所有暂存数据
          this.addMemberList = JSON.parse(JSON.stringify(memberList)); // 左侧添加disabled属性的数据
          // 更新成员状态
          this.resetAddMemberStatus();
          console.log({
            originAddMemberList: this.originAddMemberList,
            addMemberList: this.addMemberList,
            hadMemberList: this.hadMemberList,
          });
        }
      });
    },
    getAddMemberListByORG() {
      let params = {
        org_id: this.org_id,
      };
      requestMethod.getAddMemberListByORG("get", params).then((res) => {
        if (res.code === 200) {
          this.orgMemberList = [res.data.items];
          this.expandedKeys = [this.orgMemberList[0].node_id];
          // 初始化节点状态
          this.initNodesStatus(this.orgMemberList);
          console.log({
            orgMemberList: this.orgMemberList,
          });
        }
      });
    },
		// 新增提交
    addMembers() {
      // console.log(this.selectedMemberList);
			let submitMemberList = this.selectedMemberList.filter(item => !item.disabled); // 过滤出新增的成员数据
      if (submitMemberList.length) {
        let users =submitMemberList.map((item) => {
          return {
            app_id: this.app_id,
            user_id: item.user_id,
            user_name: item.alias_name,
            email_address: item.email,
          };
        });
        let params = { users };
        this.submitLoading = true;
        requestMethod
          .addMember("post", params)
          .then((res) => {
            this.submitLoading = false;
            if (res.code === 200) {
              this.$message.success(res.message);
              this.$emit("getMemberList");
              this.close();
            } else {
              this.$message.error(res.message);
            }
          })
          .catch((err) => {
            this.submitLoading = false;
            this.$message.error(err.message);
          });
      }
    },
    // ui交互 成员搜索数据过滤
    handleUserSearchChange(val) {
      if (val) {
        this.addMemberList = this.originAddMemberList.filter(
          (item) =>
            item.alias_name.indexOf(val) !== -1 ||
            item.email.indexOf(val) !== -1
        );
      } else {
        this.addMemberList = this.originAddMemberList;
      }
      // 重置成员选中状态
      this.resetAddMemberStatus();
    },
    handleOrganizeSearchChange(val) {
      this.$refs.orgTree.filter(val);
    },
		// 单个勾选
		handleUserMemberChangeRow(selection, row){
			// console.log(selection);
			// console.log(row.user_id);
			// 根据当前行是否在selection中,来判断是否勾选,如果是去掉勾选,需要在选中值中去掉
			if(!selection.find(m=> m.user_id == row.user_id)){
				let zzSelectArr = this.selectedMemberList.filter(item => item.user_id !== row.user_id);
				this.selectedMemberList = JSON.parse(JSON.stringify(zzSelectArr));
			}
		},
		// 左侧勾选方法
    handleUserMemberChange(arr) {
			// 过滤去重
      let newArr = this.selectedMemberList.filter(item => {
				if(!arr.find(m => m.user_id == item.user_id)) return item;
			});
			let contantArr = [...arr, ...newArr];
      this.selectedMemberList = JSON.parse(JSON.stringify(contantArr));
      // 更新组织结构下添加用户
      this.resetNodesStatus();
    },
    handleCheckNodeChange() {
      let checkedNodes = this.$refs.orgTree.getCheckedNodes();
      let uniqueSet = {}; // 控制用户唯一性
      this.selectedMemberList = checkedNodes
        .filter((node) => {
          let flag = false;
          if (
            node.node_type === "user" &&
            !node.disabled &&
            !uniqueSet[node.user_id]
          ) {
            uniqueSet[node.user_id] = true;
            flag = true;
          }
          return flag;
        })
        .map((item) => {
          return {
            user_id: item.user_id,
            alias_name: item.node_name,
            email: item.email,
            disabled: item.disabled,
          };
        });
      // 更新用户下添加成员
      this.resetAddMemberStatus();
    },
    deleteSelectedMember(del_row) {
      if (del_row) {
        this.selectedMemberList.splice(
          this.selectedMemberList.findIndex(
            (item) => item.user_id === del_row.user_id
          ),
          1
        );

        // 重置成员选中状态
        this.resetAddMemberStatus();

        // 更新组织结构下成员节点状态
        this.resetNodesStatus();
      }
    },
    close() {
      this.$emit("closeAddMemberDrawer");
    },
    // 辅助交互
    checkSelectable(row, index) {
      return !row.disabled;
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.node_name.indexOf(value) !== -1;
    },
		// 根据右侧已有数据反选左侧列表数据(勾选)
    resetAddMemberStatus() {
      // 重置成员选中状态
      this.$nextTick(() => {
        this.addMemberList.forEach((item) => {
          let c_item = this.selectedMemberList.find(
            (s_item) => s_item.user_id === item.user_id
          );
          if (item.disabled || c_item) {
            this.$refs.multipleTable.toggleRowSelection(item, true);
          } else {
            this.$refs.multipleTable.toggleRowSelection(item, false);
          }
        });
      });
    },
    resetNodesStatus() {
      // 更新组织结构下成员节点状态
      let s_keys = this.selectedMemberList.map((item) => item.user_id);
      let h_keys = this.hadMemberList.map((item) => item.user_id);
      let a_keys = s_keys.concat(h_keys);
      this.$refs.orgTree.setCheckedKeys(a_keys);
    },
    initNodesStatus(tree) {
      // 初始化组织结构下节点状态
      if (tree.length) {
        tree.forEach((node) => {
          let c_item = this.hadMemberList.find(
            (hadItem) => hadItem.user_id === node.user_id
          );
          node.disabled = !!c_item;
          if (node.disabled) {
            this.$nextTick(() => {
              this.$refs.orgTree.setChecked(node.node_id, true);
            });
          }
          if (node.children && node.children.length) {
            this.initNodesStatus(node.children);
          }
        });
      }
    },
    filterData(data) {
      let dataList = [];
      const generateList = (obj, node) => {
        const info = {
          id: obj["config_id"],
          name: obj["value_json"],
          key: obj["config_key"],
        };
        if (obj["children"] && obj["children"].length) {
          info.children = [];
          obj["children"].forEach((item) => generateList(item, info));
        }
        if (typeof node === "undefined") {
          dataList.push(info);
        } else {
          node["children"].push(info);
        }
      };
      data.forEach((item) => generateList(item));
      return dataList;
    },
  },
};
</script>

<style lang="less" scoped>
.ts-drawer-c {
  padding: 8px 16px 16px;
  .member-c {
    display: flex;
    align-items: center;
    /*background-color: #2db7f5;*/
    .member-public-c {
      padding: 8px;
      height: 600px;
      width: 62%;
      box-shadow: 0 3px 15px 0 rgba(51, 42, 125, 0.1);
      border-radius: 14px;
      overflow: hidden;
      position: relative;
      .title {
        @flex();
        height: 40px;
        font-weight: bold;
      }
      .search-c {
        margin: 8px 0;
        padding: 0 12px;
      }
      .list-c {
        height: 380px;
        .el-table {
          /deep/ th {
            padding: 18px 0 16px;
            background: rgba(48, 107, 255, 0.03);
          }
          /deep/ .el-table__empty-block {
            margin-top: inherit;
          }
        }
      }
      .tree-c {
        max-height: 420px;
        overflow: auto;
      }
      .paginationC {
        @flex();
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 40px;
        border-top: 1px solid #f8f8f8;
        z-index: 99;
        .block {
          margin: 0 0 0 auto;
        }
      }
    }
    .transfer-c {
      @flex();
      justify-content: center;
      width: 48px;
      .transfer-icon {
        font-size: 20px;
      }
    }
    .member-selected-c {
      height: 600px;
      flex: 1;
      box-shadow: 0 3px 15px 0 rgba(51, 42, 125, 0.1);
      border-radius: 14px;
      overflow: hidden;
      .header-c {
        height: 60px;
        padding: 0 12px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 1px solid #f8f8f8;
        .title {
          font-weight: bold;
        }
      }
      .list-c {
        padding: 0 12px;
        .el-table {
          /deep/ th {
            padding: 18px 0 16px;
            background: rgba(48, 107, 255, 0.03);
          }
          .el-icon-delete {
            cursor: pointer;
          }
          .el-icon-delete:hover {
            color: #4ca5ff;
          }
          /deep/ .el-table__empty-block {
            margin-top: inherit;
          }
        }
      }
    }
  }
  /deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
    background-color: #f2f6fc;
    border-color: #dcdfe6;
  }
}
</style>

GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:3 个月前 )
c345bb45 7 个月前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 7 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐