Vue elementUI表单嵌套表格并对每行进行校验详解


Posted in Vue.js onFebruary 18, 2022

效果展示

先看看这是不是需要的效果^_^

Vue elementUI表单嵌套表格并对每行进行校验详解

如图,ElementUI 表单里嵌套了表格,表格内每行能进行【保存】【新增】【编辑】【删除】【重置】等操作,同时可以对每行的某些字段进行校验(而不是整个表单校验!),这种需求很常见,所以记录下来。

代码链接

gitee地址

关键代码

表格数据

// 数据格式必须是【对象嵌套数组】,【form】绑定表单,【list】绑定表格
form: {
  // 表格数据
  list: [
      { id: 1, name: '小叶', age: '12', phone: '123456', show: true },
      { id: 2, name: '小李', age: '23', phone: '123457', show: true },
      { id: 3, name: '小林', age: '12', phone: '123458', show: true }
  ]
},

组件嵌套

  1. 添加字段校验的时候,格式必须写成这样的 :prop="'list.' + scope.$index + '.name'"
    这是 elementui 规定的格式,渲染后的结果为 list.1.name
  2. 每个字段要动态绑定表单的 rules 属性
  3. 如果不是以上的格式,会出错!!!
// 表单必须嵌套在表格的外面,表单必须绑定【rules】【ref】属性
<el-form :model="form" :rules="rules" ref="form">
   <el-table :data="form.list">
       <el-table-column prop="name" label="姓名">
           <template scope="scope">
              // 每个字段动态的绑定表单的【prop】【rules】属性
              <el-form-item :prop="'list.' + scope.$index + '.name'"                                              :rules="rules.name">
                    <el-input size="mini" v-model="scope.row.name" placeholder="请输入"                             clearable></el-input>
               </el-form-item>
           </template>
       </el-table-column>
  </el-table>
</el-form>

校验方法

  1. 表单的字段对象存在于 this.$refs['form'].fields 中,并且字段对象具有 prop【datas.1.name】 属性和 validateField 方法【验证 datas.1.name 能否通过校验】
  2. 但是 validateField 方法需要手动创建来验证能否通过校验
  3. 必须创建,否则会出错!!!
// 表单校验方法
// 【form】是需要校验的表单,就是表单中【ref】绑定的字段
// 【index】是需要传入的行数,字段【scope.$index】
validateField(form, index) {
     let result = true;
     for (let item of this.$refs[form].fields) {
         if(item.prop.split(".")[1] == index){
             this.$refs[form].validateField(item.prop, err => {
                 if(err !="") {
                     result = false;
                 }
             });
         }
         if(!result) break;
     }
     return result;
}

重置方法

// 对【需要校验】的表单字段进行重置
// 参数同校验方法,如果是全部重置
reset(form, index) {
    this.$refs[form].fields.forEach(item => {
        if(item.prop.split(".")[1] == index){
            item.resetField();
        }
    })
}
// 如果需要全部重置可以直接质控表单中字段
// 【row】是每行传入的数据
resetRow(row) {
    row.name = "";
    row.age = "";
    row.phone = "";
}

完整代码

因为用的是在线链接,网络不稳定时页面不一定能加载出来,使用时可以更换成本地的!

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue表单嵌套表格逐行验证</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="external nofollow" >
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id="app">
        <!-- 页面组件 -->
        <h2 style="text-align: center; line-height: 23px;color: #909399;">vue表单嵌套表格逐行验证</h2>
        <el-form :model="form" :rules="rules" ref="form" :inline="true"
            style="margin: 23px auto 0px; width: 96%; overflow: hidden;">
            <el-table border :data="form.list">
                <el-table-column align="center" prop="id" label="序号" width="55">
                </el-table-column>
                <el-table-column align="center" prop="name" label="姓名">
                    <template scope="scope">
                        <el-form-item :prop="'list.' + scope.$index + '.name'" :rules="rules.name"
                            v-if="scope.row.show">
                            <el-input size="mini" v-model="scope.row.name" placeholder="请输入" clearable>
                            </el-input>
                        </el-form-item>
                        <div v-if="!scope.row.show">{{scope.row.name}}</div>
                    </template>
                </el-table-column>
                <el-table-column align="center" prop="age" label="年龄">
                    <template scope="scope">
                        <el-form-item :prop="'list.' + scope.$index + '.age'" :rules="rules.age" v-if="scope.row.show">
                            <el-input size="mini" v-model="scope.row.age" placeholder="请输入" clearable>
                            </el-input>
                        </el-form-item>
                        <div v-if="!scope.row.show">{{scope.row.age}}</div>
                    </template>
                </el-table-column>
                <el-table-column align="center" prop="phone" label="联系方式">
                    <template scope="scope">
                        <el-form-item :prop="'list.' + scope.$index + '.phone'" :rules="rules.phone"
                            v-if="scope.row.show">
                            <!-- <el-form-item v-if="scope.row.show"> -->
                            <el-input size="mini" v-model="scope.row.phone" placeholder="请输入" clearable>
                            </el-input>
                        </el-form-item>
                        <div v-if="!scope.row.show">{{scope.row.phone}}</div>
                    </template>
                </el-table-column>
                <el-table-column label="操作" align="center" width="290" fixed="right">
                    <template slot-scope="scope">
                        <el-button type="text" style="color: #E6A23C;" @click="save(scope.$index, scope.row)"
                            v-if="scope.row.show" icon="el-icon-check">保存
                        </el-button>
                        <el-button type="text" style="color: #409EFF;" @click="edit(scope.row)" v-if="!scope.row.show"
                            icon="el-icon-edit">编辑
                        </el-button>
                        <el-button type="text" style="color: #67C23A;" v-if="scope.$index+1 == listLength"
                            @click="addRow(scope.$index, scope.row)" icon="el-icon-plus">新增
                        </el-button>
                        <el-button type="text" style="color: #F56C6C;" @click="delRow(scope.$index, scope.row)"
                            icon="el-icon-delete">删除
                        </el-button>
                        <el-button type="text" style="color: #909399;" @click="reset('form', scope.$index)"
                            v-if="scope.row.show" icon="el-icon-refresh">重置
                        </el-button>
                        <!-- <el-button type="text" style="color: #909399;" @click="resetRow(scope.row)"
                            v-if="scope.row.show" icon="el-icon-refresh">重置
                        </el-button> -->
                    </template>
                </el-table-column>
            </el-table>
        </el-form>
    </div>
</body>

</html>
<script>
    var app = new Vue({
        el: '#app',
        data() {
            return {
                // 表单数据
                form: {
                    // 表格数据
                    list: [{ id: 1, name: '', age: '', phone: '', show: true }]
                },
                // 表单验证规则
                rules: {
                    name: [{ required: true, message: '请输入姓名!', trigger: 'blur' }],
                    age: [{ required: true, message: '请输入年龄!', trigger: 'blur' }],
                    phone: [{ required: true, message: '请输入联系方式!', trigger: 'blur' }],
                },
                // 表格长度默认为 1
                listLength: 1,
            }
        },

        methods: {
            // 校验
            validateField(form, index) {
                let result = true;
                for (let item of this.$refs[form].fields) {
                    if (item.prop.split(".")[1] == index) {
                        this.$refs[form].validateField(item.prop, err => {
                            if (err != "") {
                                result = false;
                            }
                        });
                    }
                    if (!result) break;
                }
                return result;
            },

            // 重置【只针对校验字段】
            reset(form, index) {
                this.$refs[form].fields.forEach(item => {
                    if (item.prop.split(".")[1] == index) {
                        item.resetField();
                    }
                })
            },

            // 重置【全部】
            resetRow(row) {
                row.name = "";
                row.age = "";
                row.phone = "";
            },

            // 保存
            save(index, row) {
                if (!this.validateField('form', index)) return;
                row.show = false;
            },

            // 新增
            addRow(index, row) {
                if (!this.validateField('form', index)) return;
                this.form.list.push({
                    id: index + 2,
                    name: '',
                    age: '',
                    phone: '',
                    show: true
                });
                this.listLength = this.form.list.length;
            },

            // 编辑
            edit(row) {
                row.show = true;
            },

            // 删除
            delRow(index, row) {
                if (this.form.list.length > 1) {
                    this.form.list.splice(index, 1);
                    this.listLength = this.form.list.length;
                } else {
                    this.form.list = [{
                        id: 1,
                        name: '',
                        age: '',
                        phone: '',
                        show: true
                    }];
                }
            },
        }
    })
</script>

总结

到此这篇关于Vue elementUI表单嵌套表格并对每行进行校验的文章就介绍到这了,更多相关elementUI表单嵌套表格内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue中echarts的用法及与elementui-select的协同绑定操作
Nov 17 Vue.js
在Vue中使用CSS3实现内容无缝滚动的示例代码
Nov 27 Vue.js
基于vue项目设置resolves.alias: '@'路径并适配webstorm
Dec 02 Vue.js
Vue实现手机号、验证码登录(60s禁用倒计时)
Dec 19 Vue.js
梳理一下vue中的生命周期
Dec 30 Vue.js
通过vue.extend实现消息提示弹框的方法记录
Jan 07 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
详解vue3中组件的非兼容变更
Mar 03 Vue.js
Vue+Element UI实现概要小弹窗的全过程
May 30 Vue.js
vue-router中hash模式与history模式的区别
Jun 23 Vue.js
vue实现拖拽交换位置
Apr 07 Vue.js
vue实力踩坑之push当前页无效
Apr 10 Vue.js
vue项目支付功能代码详解
Feb 18 #Vue.js
Vue自定义铃声提示音组件的实现
Jan 22 #Vue.js
Vue提供的三种调试方式你知道吗
Jan 18 #Vue.js
详解Vue项目的打包方式(生成dist文件)
Jan 18 #Vue.js
Element-ui Layout布局(Row和Col组件)的实现
Dec 06 #Vue.js
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
Nov 27 #Vue.js
Vue实现跑马灯样式文字横向滚动
Nov 23 #Vue.js
You might like
摩卡咖啡
2021/03/03 咖啡文化
php异常处理使用示例
2014/02/25 PHP
从性能方面考虑PHP下载远程文件的3种方法
2015/12/29 PHP
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
Jquery replace 字符替换实现代码
2010/12/02 Javascript
读jQuery之三(构建选择器)
2011/06/11 Javascript
关于jQuery UI 使用心得及技巧
2012/10/10 Javascript
javascript url几种编码方式详解
2016/06/06 Javascript
JS实现动态表格的添加,修改,删除功能(推荐)
2016/06/15 Javascript
Seajs是什么及sea.js 由来,特点以及优势
2016/10/13 Javascript
JS验证字符串功能
2017/02/22 Javascript
微信小程序 可搜索的地址选择实现详解
2019/08/28 Javascript
微信小程序实现首页弹出广告
2020/12/03 Javascript
Python 调用DLL操作抄表机
2009/01/12 Python
python实现给数组按片赋值的方法
2015/07/28 Python
Python3学习urllib的使用方法示例
2017/11/29 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
python Pandas如何对数据集随机抽样
2019/07/29 Python
python递归下载文件夹下所有文件
2019/08/31 Python
tensorflow-gpu安装的常见问题及解决方案
2020/01/20 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
2020/04/01 Python
jupyter使用自动补全和切换默认浏览器的方法
2020/11/18 Python
python模拟点击玩游戏的实例讲解
2020/11/26 Python
用python-webdriver实现自动填表的示例代码
2021/01/13 Python
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
马耳他航空公司官方网站:Air Malta
2019/05/15 全球购物
PREMIUM-MALL法国:行李、箱包及配件在线
2019/05/30 全球购物
怀旧香味蜡烛:Homesick
2019/11/02 全球购物
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
酒吧总经理岗位职责
2013/12/10 职场文书
讲文明树新风演讲稿
2014/05/12 职场文书
综合素质自我评价怎么写
2014/09/14 职场文书
执法作风整顿剖析材料
2014/10/11 职场文书
学雷锋主题班会教案
2015/08/13 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang
vue3种table表格选项个数的控制方法
2022/04/14 Vue.js