实现动态表格表单组件:处理活动读写权限

表格表单组件.png

实现动态表格表单组件:处理活动读写权限

在前端开发中,动态表格表单组件的实现常常需要处理复杂的逻辑和交互,尤其是在涉及权限管理的情况下。在本文中,我们将详细介绍如何使用 Vue.js 和 Element UI 实现一个处理活动读写权限的动态表格表单组件。

功能概述

这个组件的主要功能包括:

  1. 显示参与者的角色和权限。
  2. 支持动态添加和删除参与者。
  3. 通过懒加载和远程搜索获取用户列表。
  4. 表单验证和提交。

实现步骤

1. 定义组件结构

使用 el-dialog 组件创建一个弹窗,包含一个表单和一个表格。表单用于验证输入,表格用于显示和操作数据。

<template>
  <el-dialog
    :title="$t('globalSetParticipants')"
    :visible.sync="participantDialogVisible"
    width="50%"
    @open="participantOpen"
    @close="participantClose"
    :close-on-click-modal="false"
    class="participant-dialog"
  >
    <el-form :rules="participantRules" ref="participantForm" :model="participantFormData">
      <el-table
        row-key="uuid"
        :header-cell-style="{ backgroundColor: '#F7F8FA' }"
        :data="participantFormData.participantTable"
        ref="participantTable"
        border
        stripe
        :height="540"
        v-loading="participantTableLoading"
      >
        <el-table-column prop="roleId" align="center" :label="$t('umRole')">
          <template slot-scope="scope">
            <el-form-item
              :rules="participantRules.roleId"
              :prop="'participantTable.' + scope.$index + '.roleId'"
            >
              <el-select @change="rolesChange(scope.row)" filterable placeholder="" v-model="scope.row.roleId">
                <el-option
                  v-for="roleId in participantRoles"
                  :key="roleId.id"
                  :label="roleId.name"
                  :value="roleId.id"
                ></el-option>
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="userIdArr" align="center" :label="$t('globalpersonnel')">
          <template slot-scope="scope">
            <el-form-item
              :rules="participantRules.userIdArr"
              :prop="'participantTable.' + scope.$index + '.userIdArr'"
            >
              <el-select
                :key="scope.row.uuid"
                :disabled="scope.row.roleId === ''"
                ret="select"
                @visible-change="(flag) => removeKeyword(flag, scope.row.roleId)"
                v-selectLoad="() => load(scope.row.roleId)"
                filterable
                remote
                multiple
                reserve-keyword
                :remote-method="(query) => remoteMethod(query, scope.row.roleId)"
                v-model="scope.row.userIdArr"
                placeholder=""
              >
                <el-option
                  v-for="(item, i) in userInfoOptions"
                  :key="i"
                  :label="item.name"
                  :value="item.id"
                ></el-option>
                <el-option v-if="loadMore" :label="'End'" value="End" disabled />
                <el-option v-else-if="participantUserLoading" :label="'Loading...'" value="Loading" disabled />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="permission" align="center" width="60" :label="$t('globalread-only')">
          <template slot-scope="scope">
            <el-radio-group v-model="scope.row.permission">
              <el-radio label="ReadOnly">{{ "" }}</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
        <el-table-column prop="permission" align="center" width="60" :label="$t('globalReadingandwriting')">
          <template slot-scope="scope">
            <el-radio-group v-model="scope.row.permission">
              <el-radio label="ReadAndWrite">{{ "" }}</el-radio>
            </el-radio-group>
          </template>
        </el-table-column>
        <el-table-column align="center" width="100">
          <template #header>
            <el-button size="mini" type="primary" @click="addParticipant()">{{ $t("globalAdd") }}</el-button>
          </template>
          <template slot-scope="scope">
            <el-button :disabled="participantFormData.participantTable.length === 1" type="danger" size="mini" icon="el-icon-minus" circle @click="removeParticipant(scope.$index)"></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="participantDialogVisible = false">{{ $t("globalCancel") }}</el-button>
      <el-button type="primary" @click="submitParticipants">{{ $t("globalConfirm") }}</el-button>
    </span>
  </el-dialog>
</template>
2. 定义数据和验证规则

data 方法中定义组件所需的数据和验证规则。

data() {
  const participantRole = (rule, value, callback) => {
    if (value === "") {
      callback(new Error("请选择角色"));
    } else {
      callback();
    }
  };
  const participantPersonnel = (rule, value, callback) => {
    if (value.length === 0) {
      callback(new Error("请选择人员"));
    } else {
      callback();
    }
  };
  return {
    getUserpageNum: 1,
    getUserquery: "",
    participantRules: {
      roleId: [
        {
          required: true,
          validator: participantRole
        }
      ],
      userIdArr: [
        {
          required: true,
          validator: participantPersonnel
        }
      ]
    },
    participantDialogVisible: false,
    participantTableLoading: false,
    participantLoadQuery: "",
    participantFormData: {
      participantTable: []
    },
    participantRoles: [],
    userInfoOptions: [],
    selectedCookieList: [],
    participantUserLoading: false,
    currentPage: 1,
    loadMore: true
  };
}
3. 定义方法

methods 中定义处理表单操作、数据加载和交互逻辑的方法。

methods: {
  async participantOpen() {
    this.participantTableLoading = true;
    if (this.participantRoles.length === 0) {
      await this.getRoleList();
    }
    this.getDiDataPermissionList();
  },
  participantClose() {
    this.userInfoOptions = [];
    this.participantFormData.participantTable = [];
  },
  async getDiDataPermissionList() {
    const { code, data } = await diDataPermissionList(this.currentProcessId);
    if (code === "00000") {
      data.forEach(item => {
        if (item.userList && item.userList.length > 0) {
          this.userInfoOptions.push(...item.userList);
        }
      });
      this.userInfoOptions = Array.from(new Set(this.userInfoOptions.map(a => a.id)))
        .map(id => this.userInfoOptions.find(a => a.id === id));
      this.participantFormData.participantTable = data.map(item => ({
        roleId: item.roleId,
        userIdArr: item.userList ? item.userList.map(item => item.id) : [],
        permission: item.permission || "ReadOnly",
        processId: item.processId || this.currentProcessId,
        uuid: vprivacyGetUUID()
      }));
      if (this.participantFormData.participantTable.length === 0) {
        this.participantFormData.participantTable.push({
          roleId: "",
          userIdArr: [],
          permission: "ReadOnly",
          processId: this.currentProcessId,
          uuid: vprivacyGetUUID()
        });
      }
      this.participantTableLoading = false;
    }
  },
  async getRoleList() {
    const { code, data } = await getAllUserRoles();
    if (code === "00000") {
      this.participantRoles = data;
    }
  },
  async load(roleId) {
    if (this.participantUserLoading || this.allLoaded) {
      return;
    }
    this.selectLazyLoad(roleId);
  },
  removeKeyword(flag, roleId) {
    this.participantLoadQuery = "";
    this.currentPage = 1;
    this.userInfoOptions = [];
    if (flag) {
      this.selectLazyLoad(roleId);
    }
  },
  async selectLazyLoad(roleId) {
    this.participantUserLoading = true;
    const { code, data } = await getUserListByRoldId(roleId, {
      search: this.participantLoadQuery,
      pageNum: this.currentPage,
      pageSize: 10
    });
    if (code === "00000") {
      this.currentPage++;
      this.participantUserLoading = false;
      this.userInfoOptions = this.userInfoOptions.concat(data[0].userDTOList.map(item => ({
        name: item.displayName,
        id: item.userId
      })));
      this.userInfoOptions = Array.from(new Set(this.userInfoOptions.map(a => a.id)))
          .map(id => {
            return this.userInfoOptions.find(a => a.id === id);
          });
        this.loadMore = data[0].userDTOList >= 20;
      }
    },
    async remoteMethod(query, roleId) {
      this.userInfoOptions = [];
      this.currentPage = 1;
      this.participantLoadQuery = query;
      await this.selectLazyLoad(roleId);
    },
    rolesChange(row) {
      row.userIdArr = [];
      this.userInfoOptions = [];
    },
    addParticipant() {
      this.participantFormData.participantTable.push({
        roleId: "",
        userIdArr: [],
        permission: "ReadOnly",
        processId: this.currentProcessId,
        uuid: vprivacyGetUUID()

      });
      this.$nextTick(() => {
        this.$refs.participantTable.bodyWrapper.scrollTop = this.$refs.participantTable.bodyWrapper.scrollHeight;
      });
    },
    removeParticipant(index) {
      this.$set(this.participantFormData, "participantTable", this.participantFormData.participantTable.filter((_, i) => i !== index));
    },
    submitParticipants() {
      this.$refs.participantForm.validate(async (valid) => {
        if (valid) {
          this.participantFormData.participantTable.forEach(item => {
            item.processId = this.currentProcessId;
          });
          const { code, data } = await addDiDataPermission(this.participantFormData.participantTable);
          if (code === "00000") {
            this.participantDialogVisible = false;
            this.$message({
              message: this.$t("globalSetsuccessfully"),
              type: "success"
            });
            await this.getList(this.saveSelectObj);
          }
        }
      });
    }
  }
}
</script>

4. 指令的定义

为了实现懒加载功能,我们需要定义一个自定义指令 selectLoad,用于监听下拉框的滚动事件。

directives: {
  selectLoad: {
    inserted(el, binding) {
      const dom = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap");
      dom.addEventListener("scroll", function() {
        const condition = this.scrollHeight - this.scrollTop - this.clientHeight <= 1;
        if (condition) {
          binding.value();
        }
      });
    }
  }
}

5. API 请求

在实际项目中,我们需要与后端进行数据交互,这里假设我们有以下 API 请求方法:

  • diDataPermissionList(processId): 获取参与者列表。
  • getAllUserRoles(): 获取所有角色列表。
  • getUserListByRoldId(roleId, params): 根据角色 ID 获取用户列表。
  • addDiDataPermission(data): 提交参与者数据。

6.style补充

.participant-dialog {  
    //显示滚动条  
    /deep/ .el-table__body-wrapper {  
        overflow-y: auto;  
    }  

    .el-table--border {  

        /deep/ .el-form-item {  
            margin-bottom: 0;  
               // 让校验失败的文字在下拉框中显示
            .el-form-item__error {  
                font-size: 14px;  
                top: 25%;  
                left: 10px;  
            }  
        }  
    }  
}

总结

通过以上步骤,我们实现了一个动态表格表单组件,用于处理活动读写权限。这个组件支持动态添加和删除参与者,使用懒加载获取用户列表,并提供表单验证和数据提交功能。希望本文能够帮助你在实际项目中实现类似的功能。

如需完整代码或更多细节,请参考项目的实际需求和实现。Happy coding!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值