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

Detailed Example of MySQL InnoDB Locking Mechanism

1. InnoDB locking mechanism The InnoDB storage en...

Steps to deploy hyper-V to achieve desktop virtualization (graphic tutorial)

The hardware requirements for deploying Hyper-V a...

Sample code for cool breathing effect using CSS3+JavaScript

A simple cool effect achieved with CSS3 animation...

Vue form input binding v-model

Table of contents 1.v-model 2. Binding properties...

Mysql NULL caused the pit

Using NULL in comparison operators mysql> sele...

How to reset Zabbix password (one-step)

Problem Description Since we don't log in to ...

WeChat applet learning notes: page configuration and routing

I have been studying and reviewing the developmen...

How to implement distributed transactions in MySQL XA

Table of contents Preface XA Protocol How to impl...

Vue implements multi-grid input box on mobile terminal

Recently, the company has put forward a requireme...

Implementation code of html floating prompt box function

General form prompts always occupy the form space...

Vue recursively implements custom tree components

This article shares the specific code of Vue recu...

WeChat applet implements user login module server construction

I chose node.js to build the server. Friends who ...

Singleton design pattern in JavaScript

Table of contents 1. What is a design pattern? 2....