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

Introduction to installing and configuring JDK under CentOS system

Table of contents Preface Check and uninstall Ope...

VUE Getting Started Learning Event Handling

Table of contents 1. Function Binding 2. With par...

Detailed explanation of Linux text processing tools

1. Count the number of users whose default shell ...

Detailed introduction to logs in Linux system

Table of contents 1. Log related services 2. Comm...

HTML+jQuery to implement a simple login page

Table of contents Introduction Public code (backe...

WeChat Mini Program Lottery Number Generator

This article shares the specific code of the WeCh...

How to create WeChat games with CocosCreator

Table of contents 1. Download WeChat developer to...

How to detect Ubuntu version using command line

Method 1: Use the lsb_release utility The lsb_rel...

How to use vue3+TypeScript+vue-router

Table of contents Easy to use Create a project vu...

Example of how to deploy MySQL 8.0 using Docker

1. Refer to the official website to install docke...

Vue implements small notepad function

This article example shares the specific code of ...

Detailed explanation of the use of props in React's three major attributes

Table of contents Class Component Functional Comp...

Summary of common sql statements in Mysql

1. mysql export file: SELECT `pe2e_user_to_compan...

Vue.js implements tab switching and color change operation explanation

When implementing this function, the method I bor...