likes
comments
collection
share

进来看我套娃!Vue3实现Table嵌套 select 并单独校验...

作者站长头像
站长
· 阅读数 32

前情提要

场景: 产品提出了一个套娃需求,但貌似也合理...画不多说,直接上原型。可以看到弹窗里是一个表单,其中一项内容以表格形式呈现以实现项目的多选,表格中每行又嵌套select,还需要对勾上的那行中的select做单独校验...

进来看我套娃!Vue3实现Table嵌套 select 并单独校验...

问题: 先将这个魔鬼需求拆成两步:首先肯定实现一个大表单,点击save后校验表单内容usersproject,然后在勾选的时候对那行的选择框进行校验..

Step 1:实现表单 对表单嵌套表格的数据进行校验

<template>
    <el-form
      ref="dialogFormRef"
      :model="empowerForm"
      label-position="top"
      style="width: 100%"
      :rules="rules"
    >
      <el-form-item label="Authorized Users" prop="authorizedUsers">
        <el-select
          v-model="empowerForm.authorizedUsers"
          style="width: 100%"
          placeholder="please select authorized Users"
        >
        </el-select>
      </el-form-item>
      <el-form-item label="Authorized Project" prop="authorizedProject">
        <el-table
          ref="multipleTableRef"
          :data="projectData"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column label="Tool" prop="tool" />
          <el-table-column prop="name" label="Project Name"/>
          <el-table-column prop="key" label="Project Key" />
          <el-table-column label="Permission" align="center" width="300">
             <template #default="scope">
                <el-select clearable v-model="scope.row.permission" placeholder="Select">
                    <el-option
                     v-for="(item, index) in scope.row.permissionList"
                     :key="index"
                     :label="item.name"
                     :value="item.type"
                      />
                    </el-select>
                  </template>
                </el-table-column>
        </el-table>
      </el-form-item>
    </el-form>
</template>

element-plus提供了这个多选的函数,监听函数改变formdata就可以实现rule的校验..这个实现起来还是挺简单的~就挑关键信息写了~

const rules = ref({
  authorizedUsers: [
    { required: true, message: "Please select User", trigger: "change" },
  ],
  authorizedProject: [
    {
      required: true,
      message: "Please select project",
      trigger: "change",
    },
  ],
});
const handleSelectionChange = (selection) => {
  empowerForm.authorizedProject = selection;
};

Step 2 在勾选的时候对选中的行内select进行校验

校验肯定要么把这个select作为一个大的表单的一项,利用validateField进行校验,这就要求prop是不同的类似于:prop="'formData.'+scope.$index+'.permission'",但由于现在场景下table本身就已经是表单的一项,prop怎么写实在是绕不出来。。

换个思路..校验还可以是一个表单,利用动态ref对整个表单实现校验,这样貌似也可行,说干就干

  <el-table-column label="Permission" align="center" width="300">
    <template #default="scope">
      <el-form
        :model="scope.row"
        :validate-on-rule-change="true"
        :ref="(el) => setFormRefs(el, scope.row.id)"
      >
        <el-form-item
          prop="permission"
          :rules="[
            {
              required: true,
              validator: checkPermission,
            },
          ]"
        >
          <el-select
            clearable
            v-model="scope.row.permission"
            placeholder="Select"
          >
            <el-option
              v-for="(item, index) in scope.row.permissionList"
              :key="index"
              :label="item.name"
              :value="item.type"
            />
          </el-select>
        </el-form-item>
      </el-form>
    </template>
  </el-table-column>

在监听多选的事件里面利用ref对该行的表单进行校验,但是table监听多选事件并没有获得当前勾选到那行的参数,只能获取到一个勾选数组,而动态ref也是一个数组,所以利用唯一性id进行匹配校验。

//获取动态ref
const setFormRefs = (el, id) => {
  if (el) {
    permissionRefs.push({
      id,
      el,
    });
  }
};

//监听多选事件
const handleSelectionChange = (selection) => {
  validatePermission(selection);
  empowerForm.authorizedProject = selection;
};

//校验选中的行内表单
const validatePermission = (selection) => {
  permissionRefs.map((ref) => {
    if (selection.length) {
      selection.map((item) => {
        if (ref.id === item.id) {
          ref.el.validate((valid) => {});
        } else {
          //清空未选择的校验信息
          ref.el.clearValidate();
        }
      });
    } else {
      ref.el.clearValidate();
    }
  });
};

这样就实现了在勾选或者清除时对行内select的校验或者是校验的清除~

这样一个魔鬼需求一开始面对的时候确实感觉难以下手..(也有菜的原因)后来逐步解剖完成功能,最终实现了想要的效果~很有成就感哈哈哈

完结撒花🎉..

转载自:https://juejin.cn/post/7269962653795975183
评论
请登录