Vue elementUI form nested table and verification of each row detailed explanation

Vue elementUI form nested table and verification of each row detailed explanation

Effect display

First see if this is the desired effect^_^

As shown in the figure, a table is nested in the ElementUI form. Each row in the table can perform operations such as [Save], [Add], [Edit], [Delete], and [Reset]. At the same time, certain fields in each row can be verified (instead of the entire form!). This requirement is very common, so it is recorded.

Code Link

gitee address

Key Code

Tabular Data

 // The data format must be [object nested array], [form] binds to form, [list] binds to table form: {
  // Table data list: [
      { id: 1, name: 'Xiaoye', age: '12', phone: '123456', show: true },
      { id: 2, name: 'Xiao Li', age: '23', phone: '123457', show: true },
      { id: 3, name: '小林', age: '12', phone: '123458', show: true }
  ]
},

Component Nesting

  1. When adding field validation, the format must be written like this: prop="'list.' + scope.$index + '.name'"
    This is the format specified by elementui. The rendered result is list.1.name
  2. Each field should be dynamically bound to the rules attribute of the form
  3. If it is not in the above format, an error will occur! ! !
 // The form must be nested outside the table, and the form must be bound to the [rules] [ref] attribute <el-form :model="form" :rules="rules" ref="form">
   <el-table :data="form.list">
       <el-table-column prop="name" label="Name">
           <template scope="scope">
              // Each field is dynamically bound to the form's [prop] [rules] attributes <el-form-item :prop="'list.' + scope.$index + '.name'" :rules="rules.name">
                    <el-input size="mini" v-model="scope.row.name" placeholder="Please enter" clearable></el-input>
               </el-form-item>
           </template>
       </el-table-column>
  </el-table>
</el-form>

Verification method

  1. The form's field object exists in this.$refs['form'].fields, and the field object has prop [datas.1.name] attribute and validateField method [verify whether datas.1.name can pass the validation]
  2. However, the validateField method needs to be created manually to verify whether it can pass the validation
  3. Must be created, otherwise an error will occur! ! !
 // Form validation method // [form] is the form that needs to be validated, that is, the field bound to [ref] in the form // [index] is the number of rows that need to be passed in, field [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 method

 // Reset the form fields that need to be verified // The parameters are the same as the verification method. If all fields are reset, reset(form, index) {
    this.$refs[form].fields.forEach(item => {
        if(item.prop.split(".")[1] == index){
            item.resetField();
        }
    })
}
// If you need to reset all fields, you can directly control the fields in the form // [row] is the data passed in each row resetRow(row) {
    row.name = "";
    row.age = "";
    row.phone = "";
}

Complete code

Because it uses an online link, the page may not be loaded when the network is unstable. You can switch to a local one when using it!

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

<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 form nested table row by row validation</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- Import style -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="external nofollow" >
    <!-- Import component library-->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>

<body>
    <div id="app">
        <!-- Page Components -->
        <h2 style="text-align: center; line-height: 23px;color: #909399;">Vue form nested table row by row verification</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="Serial number" width="55">
                </el-table-column>
                <el-table-column align="center" prop="name" label="Name">
                    <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="Please enter" 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="age">
                    <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="Please enter" 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="Contact information">
                    <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="Please enter" clearable>
                            </el-input>
                        </el-form-item>
                        <div v-if="!scope.row.show">{{scope.row.phone}}</div>
                    </template>
                </el-table-column>
                <el-table-column label="operation" 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">Save</el-button>
                        <el-button type="text" style="color: #409EFF;" @click="edit(scope.row)" v-if="!scope.row.show"
                            icon="el-icon-edit">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">Add</el-button>
                        <el-button type="text" style="color: #F56C6C;" @click="delRow(scope.$index, scope.row)"
                            icon="el-icon-delete">Delete</el-button>
                        <el-button type="text" style="color: #909399;" @click="reset('form', scope.$index)"
                            v-if="scope.row.show" icon="el-icon-refresh">Reset</el-button>
                        <!-- <el-button type="text" style="color: #909399;" @click="resetRow(scope.row)"
                            v-if="scope.row.show" icon="el-icon-refresh">Reset</el-button> -->
                    </template>
                </el-table-column>
            </el-table>
        </el-form>
    </div>
</body>

</html>
<script>
    var app = new Vue({
        el: '#app',
        data() {
            return {
                // Form data form: {
                    // Table data list: [{ id: 1, name: '', age: '', phone: '', show: true }]
                },
                // Form validation rules: {
                    name: [{ required: true, message: 'Please enter your name! ', trigger: 'blur' }],
                    age: [{ required: true, message: 'Please enter your age! ', trigger: 'blur' }],
                    phone: [{ required: true, message: 'Please enter your contact information! ', trigger: 'blur' }],
                },
                // The default table length is 1
                listLength: 1,
            }
        },

        methods: {
            // ValidatevalidateField(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 [only for validation fields]
            reset(form, index) {
                this.$refs[form].fields.forEach(item => {
                    if (item.prop.split(".")[1] == index) {
                        item.resetField();
                    }
                })
            },

            // Reset [all]
            resetRow(row) {
                row.name = "";
                row.age = "";
                row.phone = "";
            },

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

            // Add 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 edit(row) {
                row.show = true;
            },

            // Delete 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>

Summarize

This is the end of this article about Vue elementUI form nested table and checking each row. For more relevant elementUI form nested table content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue3+Element+Ts implements basic search reset and other functions of the form
  • Two ways to introduce Element-plus UI styles in Vue3.0
  • vue3 + elementPlus reset form problem

<<:  Detailed explanation of several clever applications of position:sticky sticky positioning

>>:  Understanding and solutions of 1px line in mobile development

Recommend

In-depth understanding of MySQL master-slave replication thread state transition

Preface The basic principle of MySQL master-slave...

MySQL 5.7.17 installation and use graphic tutorial

MySQL is a relational database management system ...

Implementation of importing and exporting vue-element-admin projects

vue-element-admin import component encapsulation ...

The role and opening of MySQL slow query log

Preface The MySQL slow query log is a type of log...

Analysis of the usage of Xmeter API interface testing tool

XMeter API provides a one-stop online interface t...

Solution to Nginx session loss problem

In the path of using nginx as a reverse proxy tom...

How to use docker to deploy Django technology stack project

With the popularity and maturity of Docker, it ha...

Tutorial on installing lamp-php7.0 in Centos7.4 environment

This article describes how to install lamp-php7.0...

Four data type judgment methods in JS

Table of contents 1. typeof 2. instanceof 3. Cons...

Some "pitfalls" of MySQL database upgrade

For commercial databases, database upgrade is a h...

Detailed explanation of crontab scheduled execution command under Linux

In LINUX, periodic tasks are usually handled by t...

Application of CSS3 animation effects in activity pages

background Before we know it, a busy year is comi...

mysql5.7.19 zip detailed installation process and configuration

MySQL v5.7.19 official version (32/64 bit install...