(vue2)element ui 中form可编辑table。并且每一行数据是联动回显以及动态增减

前景提要。用户需要一个可编辑table。并且实现动态增减默认回显一行。会根据选择的Type是什么类型来显示编辑的input的类型。

先缕清逻辑:

1.默认回显一行。而且已知前端的table需要唯一值id。如果设置index为id那么动态增减会出现问题(增减的时候控制Index会重复)。可以用动态生成唯一Id。我这里用到的是nanoid。然后动态增减用数组splice方法

 <el-table :border="true" ref="tableBox" :data="ruleForm.tableData">
          <!-- 动态增减 -->
          <el-table-column min-width="20" label="" align="">
            <template slot-scope="scope">
              <div style="font-size: 20px">
                <i
                  class="el-icon-remove"
                  v-if="tableData.length > 1"
                  @click="clinkTableBtn('del', scope.row)"
                ></i>
                <i
                  class="el-icon-circle-plus"
                  @click="clinkTableBtn('add', scope.row)"
                ></i>
              </div>
            </template>
          </el-table-column>
</el-table>
data() {
//默认回显的第一行数据
		tableData:[
          {
            type: "",
            value: "",
            id: generateNanoId(),
          },
        ],
        rules: {
	        field: [
	          { required: true, message: "请选择类型", trigger: "blur" },
	        ]
        }
 }
 methods: {
 //table动态增减
    clinkTableBtn(type, row) {
      const index = this.tableData.findIndex((item) => item.id == row.id);
      if (type === "add") {
        let addData = {
          type: "and",
          value: "",
          id: generateNanoId(),
        };
        this.tableData.splice(index + 1, 0, addData);
      } else if (type === "del") {
        this.tableData.splice(index, 1);
      }
    },
 }

2.重点是根据type类型来动态回显当前行编辑的类型。我们的type的格式大概是[{name:“city”,type:“string”,options:[]}]。首先根据这个数组来渲染slect的options选项v-for就行。然后此时option的value我选的是整个数组。这样方便后面回显类型。然后数组中type的enum是string,number,datatime。如果options.length>0则string和input变成select。里面的内容就是options的内容。

3.避免你编辑一格其他会同时编辑也就是要保证当前的编辑name唯一。用到了slot-scope=“scope”

4.table中某些编辑列必传。以及table表头显示小红星

<el-table-column
            prop="type"
            label="type"
            :render-header="addRedStar"
            width="100px"
            align="center"
          >
            <template slot-scope="scope">
              <el-form-item
              	//保证唯一
                :prop="'tableData.' + scope.$index + '.field'"
                :rules="rules.field"
              >
                <el-select
                  v-model="scope.row.field"
                  placeholder="请选择"
                >
                  <el-option
                   	v-for="(item, index) in scope.row.field"
                    label="item.name" 
                    value="item"></el-option>
                </el-select>
              </el-form-item>
            </template>
 </el-table-column>
 <el-table-column prop="scenicArea" label="Value" align="center">
            <template slot-scope="scope">
              <!-- 选中的数据源筛选条件为日期 -->
              <el-form-item
                :prop="'tableData.' + scope.$index + '.ValueDatetime'"
                v-if="scope.row.field.type == 'datetime'"
                :rules="rules.ValueDatetime"
              >
                <el-date-picker
                  v-model="scope.row.ValueDatetime"
                  placeholder="选择日期"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  type="datetime"
                  style="width: 80%"
                >
                </el-date-picker>
              </el-form-item>
              <!-- 选中的数据源筛选条件为string -->
              <el-form-item
                :prop="'tableData.' + scope.$index + '.ValueString'"
                v-if="scope.row.field.type == 'string'"
                :rules="rules.ValueString"
              >
                <el-select
                  v-model="scope.row.ValueString"
                  placeholder="请选择"
                  v-if="scope.row.field.options.length > 0"
                >
                  <el-option
                    v-for="item in scope.row.field.options"
                    :key="item"
                    :label="item"
                    :value="item"
                  >
                    <span style="float: left">{{ item }}</span>
                  </el-option>
                </el-select>
                <el-input
                  v-model="scope.row.ValueString"
                  placeholder="请输入"
                  v-else
                ></el-input>
              </el-form-item>
              <!-- 选中的数据源筛选条件为Number -->
              <el-form-item
                :prop="'tableData.' + scope.$index + '.ValueNumeric'"
                v-if="scope.row.field.type == 'numeric'"
                :rules="rules.ValueNumeric"
              >
                <el-select
                  v-model="scope.row.ValueNumeric"
                  placeholder="请选择"
                  v-if="scope.row.field.options.length > 0"
                >
                  <el-option
                    v-for="item in scope.row.field.options"
                    :key="item"
                    :label="item"
                    :value="item"
                  >
                    <span style="float: left">{{ item }}</span>
                  </el-option>
                </el-select>
                <el-input
                  type="number"
                  v-model="scope.row.ValueNumeric"
                  placeholder="请输入"
                  v-else
                ></el-input>
              </el-form-item>
            </template>
</el-table-column>

methods(){
   // 表头生成必填校验红星样式
    addRedStar(h, { column }) {
      return [
        h("span", { style: "color: red" }, "*"),
        h("span", " " + column.label),
      ];
    },
}

5.提交。你会发现我的Value那一列有三个字段:ValueString,ValueNumeric,ValueDatetime。是因为切换type的时候上一个选中的value我没做清空处理。就会导致页面没有但是数据中的value已存在。所以我就定了三个不同的字段。(另一种解决就是切换type的时候来调用select的click方法,传id然后更新tableData匹配后当前的value为“”)我懒没这样写

6.这个时候就不能用组件自带的方法来判断必填项是否填入了。用到了this.$refs.ruleForm.validate

7.避免多次点击保存调用接口。可以在加一个loading状态


 <el-button
          type="primary"
          @click="submit"
          >保存</el-button
        >
        
submit() {
this.$refs.ruleForm.validate((valid, value) => {
		if (valid) {
			console.log(this.tableData)
		}else{
			this.$message.error("请填写必填项");
		}
	})
}

总结注意事项:1.table的唯一id,2.每一编辑行的唯一性el-form-item的**:prop=“‘filter.’ + scope.$index + ‘.field’”**,el-select的 v-model=“scope.row.field”。3.保存判断必填项

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值