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开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 Vue.js
vue使用exif获取图片旋转,压缩的示例代码
Dec 11 Vue.js
Vue项目中使用mock.js的完整步骤
Jan 12 Vue.js
vue动态设置路由权限的主要思路
Jan 13 Vue.js
Vue实现图书管理案例
Jan 20 Vue.js
浅谈Vue开发人员的7个最好的VSCode扩展
Jan 20 Vue.js
Vue实现todo应用的示例
Feb 20 Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
VUE实现吸底按钮
Mar 04 Vue.js
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
Jun 09 Vue.js
Element-ui Layout布局(Row和Col组件)的实现
Dec 06 Vue.js
vue递归实现树形组件
Jul 15 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
PHP Ajax实现无刷新附件上传
2016/08/17 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
用jquery写的一个万年历(自写)
2014/01/20 Javascript
动态添加option及createElement使用示例
2014/01/26 Javascript
jquery 删除字符串最后一个字符的方法解析
2014/02/11 Javascript
jQuery打印指定区域Html页面并自动分页
2014/07/04 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
jquery实现邮箱自动填充提示功能
2015/11/17 Javascript
JS实现的仿淘宝交易倒计时效果
2015/11/27 Javascript
jQuery实现调整表格单列顺序完整实例
2016/06/20 Javascript
Angularjs使用directive自定义指令实现attribute继承的方法详解
2016/08/05 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
js仿微信语音播放实现思路
2016/12/12 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
react-native使用react-navigation进行页面跳转导航的示例
2017/09/07 Javascript
JavaScript代码调试方法实例小结
2019/01/05 Javascript
JS对象和字符串之间互换操作实例分析
2019/02/02 Javascript
Python通过poll实现异步IO的方法
2015/06/04 Python
用python编写第一个IDA插件的实例
2018/05/29 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
解决python测试opencv时imread导致的错误问题
2019/01/26 Python
法院实习人员自我鉴定
2013/09/26 职场文书
大学总结自我鉴定
2014/01/18 职场文书
珍珠鸟教学反思
2014/02/01 职场文书
会计电算化应届生自荐信
2014/02/25 职场文书
团购业务员岗位职责
2014/03/15 职场文书
会计毕业生自荐书
2014/06/12 职场文书
竞选班干部演讲稿600字
2014/08/20 职场文书
幼儿园端午节活动方案
2014/08/25 职场文书
机票销售员态度不好检讨书
2014/09/27 职场文书
试用期自我评价范文
2015/03/10 职场文书
校园运动会广播稿
2015/08/19 职场文书
2016反腐倡廉警示教育心得体会
2016/01/13 职场文书
导游词之镇江焦山
2019/11/21 职场文书
JavaScript流程控制(分支)
2021/12/06 Javascript