Loading... <p><img src="https://img2020.cnblogs.com/blog/774496/202005/774496-20200520162145857-686298304.png" class="aligncenter"></p> <blockquote> <p>作者:小土豆biubiubiu</p> <p>博客园:<a href="https://www.cnblogs.com/HouJiao/" target="_blank">https://www.cnblogs.com/HouJiao/</a></p> <p>掘金:<a href="https://juejin.im/user/58c61b4361ff4b005d9e894d" target="_blank">https://juejin.im/user/58c61b4361ff4b005d9e894d</a></p> <p>微信公众号:土豆妈的碎碎念(扫码关注,一起吸猫,一起听故事,一起学习前端技术)</p> <p>码字不易,点赞鼓励哟~</p> </blockquote> <h1>前言</h1> <p>本篇文章主要是实践一下<code>Element</code>中的 <a href="https://element.faas.ele.me/#/zh-CN/component/form" target="_blank"><code>Form</code></a> 表单组件。</p> <blockquote> <p>本篇内容较为简单,基本上是参照着文档将表单部分内容实践了一下,后续会持续更新表单的一些常用功能。</p> <p>同时下一篇文章 <code>Element Form表单实践(下)</code> 将会分享项目开发中的一个表单实践,记录在这个过程中遇到的一些问题。</p> </blockquote> <h3>项目环境</h3> <p>为了简单快速,我使用引入<code>cdn</code>静态资源的方式搭建项目的开发环境。</p> <pre><code><!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Element Form表单实践</title> <!-- vue: 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- element: 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- element: 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="box"> <span> {{message}} </span> <el-divider></el-divider> </div> <script> var vm = new Vue({ el: '#box', data: { message: "Element Form表单实践" } }) </script> </body> </html> </code></pre> <p>环境准备好后,直接本地打开页面,就能看到效果。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/7/171ed3df47eaccf2" class="aligncenter"></p> <p>接着我们就开始<code>Element Form</code>表单的实践。</p> <h1>使用Form组件</h1> <h3>典型表单</h3> <p>首先按照官方文档我们先实践一下<code>典型表单</code>。</p> <p><code>典型表单</code>的完整代码如下:</p> <pre><code><!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Element Form表单实践</title> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="box"> <span> {{message}} </span> <el-divider></el-divider> <!-- 典型表单 --> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label="活动名称"> <el-input v-model="form.name"></el-input> </el-form-item> <el-form-item label="活动区域"> <el-select v-model="form.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活动时间"> <el-col :span="11"> <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-col> </el-form-item> <el-form-item label="即时配送"> <el-switch v-model="form.delivery"></el-switch> </el-form-item> <el-form-item label="活动性质"> <el-checkbox-group v-model="form.type"> <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox> <el-checkbox label="地推活动" name="type"></el-checkbox> <el-checkbox label="线下主题活动" name="type"></el-checkbox> <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊资源"> <el-radio-group v-model="form.resource"> <el-radio label="线上品牌商赞助"></el-radio> <el-radio label="线下场地免费"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="活动形式"> <el-input type="textarea" v-model="form.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button>取消</el-button> </el-form-item> </el-form> </div> <script> var vm = new Vue({ el: '#box', data: { message: "Element Form表单实践", form: { name: '', // 活动名称 region: '', // 活动区域 date1: '', // 活动时间-日期 date2: '', // 活动时间-时间 delivery: false, // 即时配送 type: [], // 活动性质 resource: '', // 特殊资源 desc: '' // 活动形式 } }, methods: { onSubmit() { console.log('submit!'); } } }) </script> </body> </html> </code></pre> <p>浏览器打开页面:</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/7/171ed47358340c8e?w=736&h=604&f=png&s=15599" class="aligncenter"></p> <p>可以看到表单组件已经显示到了页面上。</p> <p>接下来,我们就这个表单组件的一些重要的特性进行学习。</p> <h1>表单属性</h1> <blockquote> <p>表单属性指的是设置在<code>el-form</code>元素上的属性</p> </blockquote> <h3>model</h3> <p><code>model</code>属性在前面的用法如下:</p> <pre><code><!-- 典型表单 --> <el-form ref="form" :model="form" label-width="80px"> </el-form> </code></pre> <p><code>model</code>属性是表单的数据,它绑定的<code>form</code>数据如下:</p> <pre><code>form: { name: '', // 活动名称 region: '', // 活动区域 date1: '', // 活动时间-日期 date2: '', // 活动时间-时间 delivery: false, // 即时配送 type: [], // 活动性质 resource: '', // 特殊资源 desc: '' // 活动形式 } </code></pre> <p><code>form</code>数据中的每一项分别对应表单中的一个<code>el-form-item</code>项,比如<code>name</code>对应的是活动名称,那么<code>el-form-item</code>写法如下:</p> <pre><code><el-form-item label="活动名称"> <el-input v-model="form.name"></el-input> </el-form-item> </code></pre> <blockquote> <p>这里需要注意表单控件<code>el-input</code>的<code>v-model</code>并没有绑定在<code>el-form-item</code>上:<br> <code>input</code>控件对应的是<code>el-input</code>,<code>v-model</code>绑定在<code>el-input</code>上<br> <code>select</code>控件对应的是<code>el-select</code><br> <code>checkbox</code>控件对应的是<code>el-checkbox-group</code>+<code>el-checkbox</code>,<code>v-model</code>绑定在<code>el-checkbox-group</code>上<br> <code>radio</code>控件对应的是<code>el-radio-group</code>+<code>el-radio</code>,<code>v-model</code>绑定在<code>el-radio=group</code>上<br> <code>switch</code>切换控件对应的是<code>el-switch</code>,<code>v-model</code>绑定在<code>el-switch</code>上</p> </blockquote> <h5>model绑定的form数据</h5> <p>接下来我们在探究一下这个<code>form</code>数据。</p> <p>为了探究这个<code>form</code>数据,需要做下面的三件事:</p> <pre><code>01:在"立即创建"按钮绑定的onSubmit函数中打印form数据 02:填写表单信息 03:点击"立即创建"按钮,查看form数据打印结果 </code></pre> <p>第一步:在<code>立即创建</code>按钮绑定的<code>onSubmit</code>函数中打印<code>form</code>数据。</p> <pre><code>methods: { onSubmit() { console.log(this.form); } } </code></pre> <p>第二步:填写表单信息。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/7/171eeb4cf42ebe0f?w=735&h=642&f=png&s=20588" class="aligncenter"></p> <p>第三步:点击<code>立即创建</code>按钮,查看<code>form</code>数据打印结果。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/7/171eeb58eb66c989?w=560&h=296&f=png&s=16333" class="aligncenter"></p> <p>可以看到<code>form</code>数据包含了我们表单填写的内容,我将<code>form</code>中的字段、字段的值和表单控件的关系梳理一下。</p> <table> <thead> <tr> <th style="text-align:left">属性/字段</th> <th style="text-align:left">描述</th> <th style="text-align:left">控件类型</th> <th style="text-align:left">值</th> <th style="text-align:left">值的来源</th> <th style="text-align:left">类型</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">name</td> <td style="text-align:left">活动名称</td> <td style="text-align:left"><code>input</code></td> <td style="text-align:left">"element form表单实践"</td> <td style="text-align:left"><code>input</code>输入框的内容</td> <td style="text-align:left">String</td> </tr> <tr> <td style="text-align:left">region</td> <td style="text-align:left">活动区域</td> <td style="text-align:left"><code>select</code></td> <td style="text-align:left">"shanghai"</td> <td style="text-align:left">选中的<code>select</code>的value值</td> <td style="text-align:left">String</td> </tr> <tr> <td style="text-align:left">date1</td> <td style="text-align:left">活动时间-日期</td> <td style="text-align:left"><code>el-time-picker</code></td> <td style="text-align:left">Thu May 07 2020 00:00:00 GMT+0800 (中国标准时间)</td> <td style="text-align:left">日期控件选择的内容</td> <td style="text-align:left">Date</td> </tr> <tr> <td style="text-align:left">date2</td> <td style="text-align:left">活动时间-时间</td> <td style="text-align:left"><code>el-time-picker</code></td> <td style="text-align:left">Thu May 07 2020 18:24:39 GMT+0800 (中国标准时间)</td> <td style="text-align:left">时间控件选择的内容</td> <td style="text-align:left">Date</td> </tr> <tr> <td style="text-align:left">delivery</td> <td style="text-align:left">即时配送</td> <td style="text-align:left"><code>el-switch</code></td> <td style="text-align:left">true</td> <td style="text-align:left">switch的选择结果</td> <td style="text-align:left">Boolean</td> </tr> <tr> <td style="text-align:left">type</td> <td style="text-align:left">活动性质</td> <td style="text-align:left"><code>checkbox</code></td> <td style="text-align:left">["美食/餐厅线上活动","地推活动"]</td> <td style="text-align:left">选中的<code>checkbox</code>的label值</td> <td style="text-align:left">Boolean</td> </tr> <tr> <td style="text-align:left">resource</td> <td style="text-align:left">特殊资源</td> <td style="text-align:left"><code>radio</code></td> <td style="text-align:left">"线上品牌商赞助"</td> <td style="text-align:left">选中的<code>radio</code>的label值</td> <td style="text-align:left">String</td> </tr> <tr> <td style="text-align:left">desc</td> <td style="text-align:left">活动形式</td> <td style="text-align:left"><code>input</code></td> <td style="text-align:left">"其他"</td> <td style="text-align:left"><code>input</code>输入框内容</td> <td style="text-align:left">String</td> </tr> </tbody> </table> <p>可以看到,表单<code>el-form</code>的<code>model</code>属性绑定的<code>form</code>数据和表单中的内容是一致的,因此在日常项目开发中,表单信息填写完成,点击提交按钮,可以直接将<code>this.form</code>作为请求的参数直接发送给后端。</p> <p>不过这里很有必要对<code>this.form</code>这个数据进行一些完善。</p> <p>在前面的代码中,最终<code>form</code>中的<code>type</code>值和<code>resource</code>值都是中文的结果,这样的中文数据传递到后端,对后端的逻辑处理是很不友好的。</p> <p>所以在日常的项目开发中,前后端会对这样的数据有一个默认的约定关系:</p> <pre><code>// 活动性质 { 'foodOnlineActivities': '美食/餐厅线上活动', 'earthPushingActivity': '地推活动', 'offlineThemeActivities': '下线主题活动', 'brandExposure': '单纯品牌曝光', } // 活动形式 { 'online': '美食/餐厅线上活动', 'offline': '地推活动' } </code></pre> <p>或者在简单一些的约定:</p> <pre><code>// 活动性质 { 'foodOnlineActivities': '1', 'earthPushingActivity': '2', 'offlineThemeActivities': '3', 'brandExposure': '4', } // 活动形式 { 'online': '1', 'offline': '2' } </code></pre> <p>对应的我们的前端代码需要修改成下面这样:</p> <pre><code><el-form-item label="活动性质" prop="type"> <el-checkbox-group v-model="form.type"> <el-checkbox label="1" name="type">美食/餐厅线上活动</el-checkbox> <el-checkbox label="2" name="type">地推活动</el-checkbox> <el-checkbox label="3" name="type">线下主题活动</el-checkbox> <el-checkbox label="4" name="type">单纯品牌曝光</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊资源" prop="resource"> <el-radio-group v-model="form.resource"> <el-radio label="1">线上品牌商赞助</el-radio> <el-radio label="2">线下场地免费</el-radio> </el-radio-group> </el-form-item> </code></pre> <p>接着在选择对应的选项,查看<code>form</code>数据的结果:</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/20/1723104f2169ec70?w=1280&h=666&f=jpeg&s=107928" class="aligncenter"></p> <p>修改之后的<code>form</code>数据传递到后端以后,不管是对数据进行保存或者判断等逻辑,都比较简单,而且不会因为中文的编码而出现问题。</p> <p>关于<code>form</code>数据最后的一点就是<code>form</code>的初始值。</p> <p>我们看到<code>form</code>数据默认都是空值(<code>form</code>字段的类型大多都不相同,这里将上面的初始值统称为空值),实际上我们可以为其指定<code>默认值</code>:即直接在<code>data</code>中给<code>form.xx</code>设置默认值。</p> <blockquote> <p>这里将上面<code>type</code>和<code>resource</code>设置的值恢复成了中文,项目开发中记得设置成上面的那种形式。</p> </blockquote> <pre><code> form: { name: '我是初始化设置的活动名称', // 活动名称 region: 'beijing', // 活动区域 date1: new Date(), // 活动时间-日期 date2: new Date(), // 活动时间-时间 delivery: true, // 即时配送 type: ['单纯品牌曝光'], // 活动性质 resource: '线上品牌商赞助', // 特殊资源 desc: '我是初始化设置的活动形式' // 活动形式 } </code></pre> <p>设置了<code>默认值</code>后,我们刷新页面,表单中的内容就是我们设置的值。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/8/171f3226fa27fa5d?w=672&h=614&f=png&s=18743" class="aligncenter"></p> <blockquote> <p>注意:对于<code>select</code>、<code>checkbox</code>和<code>radio</code>这几个控件,<code>form</code>字段中的值必须要和对应控件的<code>label</code>值一致,否则控件匹配不到,对应的内容也就无法反填到表单中。</p> </blockquote> <h3>rules</h3> <p>表单属性<code>rules</code>是用于设置表单的验证规则,我们来实践一下。</p> <pre><code><!-- index.html --> <el-form ref="form" :model="form" :rules="addFormRules" label-width="80px"> <!-- 中间未修改的代码省略--> </el-form> </code></pre> <p>可以看到<code>:rule</code>作用在<code>el-form</code>上,并且绑定了一个变量<code>addFormRules</code>。</p> <p>接着我们就在<code>addFormRules</code>中编写活动名称<code>name</code>的验证规则。</p> <pre><code>// 有部分未修改的代码省略 var vm = new Vue({ el: '#box', data: { addFormRules: { name: [{ required: true, // name字段是否必填,true:必填 false:非必填 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "请输入活动名称", // 如果没有填写时的错误提示语 },{ min: 5, // 字段最小长度 max: 10, // 字段最大长度 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "活动名称长度在5-10个字符", // 不满足规则时显示的错误提示语 }] } } }) </code></pre> <p>在<code>addFormRules</code>里面我们定义了<code>name</code>字段,该字段是一个数组,数组的每一项又是一个<code>json</code>。<br> 就我们编写的这个验证规则,数组中的第一个<code>json</code>元素编写的是活动名称字段的<code>必填验证规则</code>,<code>json</code>中的每一个键值对的含义注释中都有写到;数组中的第二个<code>json</code>元素编写的是活动名称字段的<code>长度验证规则</code>。</p> <p>那么到这里还有最重要的一步,我们的这个规则才能生效:在<code>el-form-item</code>上设置<code>prop</code>属性。</p> <pre><code><!-- index.html --> <el-form ref="form" :model="form" :rules="addFormRules" label-width="80px"> <el-form-item label="活动名称" prop="name"> <el-input v-model="form.name"></el-input> </el-form-item> <!-- 中间未修改的代码省略--> </el-form> </code></pre> <p>可以看到<code>prop</code>属性的值就是<code>form</code>中定义的<code>name</code>字段,只有这样<code>addFormRules</code>中定义的对<code>name</code>的校验规则才能和对应的表单关联起来,否则验证规则是不会生效的。</p> <blockquote> <p>这里需要注意的是,表单<code>el-form</code>上绑定的<code>form</code>数据中的字段、<code>prop</code>设置的值以及<code>rule</code>绑定的<code>addFormRules</code>数据中的字段,这三个必须都要一致,否则校验会出现问题。</p> </blockquote> <h3>label-position、label-width、label-suffix</h3> <p>这三个表单属性都是用于设置表单域的标签。<br> <img src="https://user-gold-cdn.xitu.io/2020/5/14/17210d912f3a841d?w=713&h=200&f=png&s=7956" class="aligncenter"></p> <p><code>label-position</code>用于设置标签域的对齐方式(默认右对齐);<code>label-width</code>用于设置标签域的宽度;<code>label-suffix</code>用于设置标签域的后缀。</p> <pre><code> <el-form ref="form" :model="form" :rules="addFormRules" label-position="left" label-width="120px" label-suffix=":"> <!-- 中间未修改的代码省略--> </el-form> </code></pre> <p><img src="https://user-gold-cdn.xitu.io/2020/5/14/17210e8a23c2fd80?w=3840&h=3840&f=jpeg&s=1093072" class="aligncenter"></p> <h3>status-icon</h3> <pre><code> <el-form ref="form" :model="form" :rules="addFormRules" label-width="120px" status-icon="true"> <!-- 中间未修改的代码省略--> </el-form> </code></pre> <p><img src="https://user-gold-cdn.xitu.io/2020/5/14/17210f78db40a631?w=496&h=88&f=png&s=3759" class="aligncenter"></p> <h1>表单方法</h1> <h3>validate</h3> <p>表单方法<code>validate</code>是对整个表单进行校验的方法,参数为一个<code>回调函数</code>。</p> <p>该<code>回调函数</code>会在校验结束后被调用,并传入两个参数:<code>是否校验成功</code>和<code>未通过校验的字段</code>。若不传入回调函数,则会返回一个<code>promise</code>。</p> <p>下面我们就来实践一下这个表单方法。</p> <blockquote> <p>主要的改动就是在提交表单的时候调用<code>validate</code>方法,打印出回调函数中的两个参数。</p> </blockquote> <pre><code><el-form ref="form" :model="form" :rules="addFormRules" label-width="120px" label-suffix=":" :status-icon="statusIcon"> <!-- 中间未修改的代码省略--> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button>取消</el-button> </el-form-item> </el-form> <script> var vm = new Vue({ el: '#box', data: { message: "Element Form表单实践", statusIcon: true, form: { name: '我是初始化设置的活动名称', // 活动名称 region: 'beijing', // 活动区域 date1: new Date(), // 活动时间-日期 date2: new Date(), // 活动时间-时间 delivery: true, // 即时配送 type: ['单纯品牌曝光'], // 活动性质 resource: '线上品牌商赞助', // 特殊资源 desc: '我是初始化设置的活动形式' // 活动形式 }, addFormRules: { name: [{ required: true, // name字段是否必填,true:必填 false:非必填 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "请输入活动名称", // 如果没有填写时的错误提示语 },{ min: 5, // 字段最小长度 max: 10, // 字段最大长度 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "活动名称长度在5-10个字符", // 不满足规则时显示的错误提示语 }] } }, methods: { onSubmit() { this.$refs['form'].validate((validate,failedInfo) => { console.log('validate:') console.log(validate); console.log('failedInfo:') console.log(failedInfo); }) } } }) </script> </code></pre> <p>表单验证成功时<code>validate</code>和<code>failedInfo</code>的打印结果:</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/14/172111d5281efafc?w=497&h=317&f=png&s=16460" class="aligncenter"></p> <p>表单验证失败时<code>validate</code>和<code>failedInfo</code>的打印结果:</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/14/172111f122a5d444?w=492&h=442&f=png&s=21876" class="aligncenter"></p> <blockquote> <p>前面我们只编写了<code>name</code>字段的验证规则,因此在表单提交调用<code>validate</code>方法时,只会对<code>name</code>字段进行验证。</p> </blockquote> <p>其实对于我们日常的开发来说会比较关注第一个参数,当回调函数中的第一个参数为<code>true</code>时,表示表单<code>验证成功</code>,就可以将表单数据传递到后端;相反的当第一个参数为<code>falses</code>时,表示表单<code>验证失败</code>,我们就可以给用户一个错误提示。</p> <pre><code>methods: { onSubmit() { this.$refs['form'].validate((validate,failedInfo) => { if(validate){ // 将表单数据发送到后端 // 发送 POST 请求 axios.post(url, this.form).then(function (response) { // 处理后端返回的响应数据 }); }else{ // 提示用户 this.$message({ message: '表单数据格式有误,请检查后重新提交.', type: "error", center: true }); } }) } } </code></pre> <blockquote> <p>这里有一定需要注意,回调函数最好写成箭头函数的形式,这样在回调函数内部的<code>this</code>表示的是<code>Vue</code>实例对象。如果使用普通的函数声明<code>function</code>,则回调函数内部的<code>this</code>指向的是<code>windows</code>对象。</p> </blockquote> <h3>resetFields</h3> <p>表单属性<code>resetFields</code>对整个表单进行重置,<code>将所有字段值重置为初始值</code>并且<code>移除校验结果</code>。</p> <blockquote> <p>本次改动就是将之前的<code>取消</code>按钮改为<code>重置</code>按钮,并且在点击<code>重置</code>按钮的时候调用<code>resetFields</code>方法。</p> </blockquote> <pre><code><el-form ref="form" :model="form" :rules="addFormRules" label-width="120px" label-suffix=":" :status-icon="statusIcon"> <!-- 中间未修改的代码省略--> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button type="primary" @click="resetForm">重置</el-button> </el-form-item> </el-form> <script> var vm = new Vue({ el: '#box', data: { message: "Element Form表单实践", statusIcon: true, form: { name: '我是初始化设置的活动名称', // 活动名称 region: 'beijing', // 活动区域 date1: new Date(), // 活动时间-日期 date2: new Date(), // 活动时间-时间 delivery: true, // 即时配送 type: ['单纯品牌曝光'], // 活动性质 resource: '线上品牌商赞助', // 特殊资源 desc: '我是初始化设置的活动形式' // 活动形式 }, addFormRules: { name: [{ required: true, // name字段是否必填,true:必填 false:非必填 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "请输入活动名称", // 如果没有填写时的错误提示语 },{ min: 5, // 字段最小长度 max: 10, // 字段最大长度 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "活动名称长度在5-10个字符", // 不满足规则时显示的错误提示语 }] } }, methods: { onSubmit() { this.$refs['form'].validate((validate,failedInfo) => { console.log('validate:') console.log(validate); console.log('failedInfo:') console.log(failedInfo); }) }, resetForm(){ this.$refs['form'].resetFileds(); } } }) </script> </code></pre> <p><img src="https://user-gold-cdn.xitu.io/2020/5/18/17226d288f186810?w=495&h=647&f=gif&s=499988" class="aligncenter"></p> <p>仔细查看重置以后的结果,会发现只有活动名称字段的值恢复了初始值,而其余我们修改了表单信息的空间均没有重置为初始值。</p> <blockquote> <p>这里需要注意<code>resetFileds</code>方法是将表单的值设置为<code>初始值</code>,而不是<code>空值</code>。<code>初始值</code>就是在组件的<code>data</code>中设置的值,所以我们点击重置的时候活动名称这个空间的值变回了<code>我是初始化设置的活动名称</code>。</p> </blockquote> <p>这样的效果显然是不对的。</p> <p>不过原因也很简单,就是我们没有给其他的表单项设置<code>prop</code>属性。所以我们要注意,在使用<code>resetFileds</code>时,必须给表单项<code>el-form-item</code>设置<code>prop</code>值,否则无法进行重置。</p> <pre><code><el-form ref="form" :model="form" :rules="addFormRules" label-width="120px" label-suffix=":" :status-icon="statusIcon" > <el-form-item label="活动名称" prop="name"> <el-input v-model="form.name"></el-input> </el-form-item> <el-form-item label="活动区域" prop="region"> <el-select v-model="form.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活动时间" > <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> <el-form-item label="即时配送" prop="delivery"> <el-switch v-model="form.delivery"></el-switch> </el-form-item> <el-form-item label="活动性质" prop="type"> <el-checkbox-group v-model="form.type"> <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox> <el-checkbox label="地推活动" name="type"></el-checkbox> <el-checkbox label="线下主题活动" name="type"></el-checkbox> <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊资源" prop="resource"> <el-radio-group v-model="form.resource"> <el-radio label="线上品牌商赞助"></el-radio> <el-radio label="线下场地免费"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="活动形式" prop="desc"> <el-input type="textarea" v-model="form.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button type="primary" @click="resetForm">重置</el-button> </el-form-item> </el-form> </code></pre> <p>这里需要特意说明的是为<code>活动时间</code>这个表单项设置<code>prop</code>属性。</p> <pre><code><el-form-item label="活动时间" > <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> </code></pre> <p>那对比之前没有设置<code>prop</code>的代码,还给<code>el-date-picker</code>外层多加了一个<code>el-form-item</code>元素。那也很好理解,因为活动时间这个包含了两个<code>el-time-picker</code>,并且绑定的不同的<code>form</code>数据:<code>date1</code>和<code>date2</code>。而之前的写法两个<code>el-time-picker</code>都同在一个<code>el-form-item</code>元素中,那设置<code>prop</code>时只能设置一个值,所以<code>element</code>提供的解决方案就是分别给两个<code>el-time-picker</code>在嵌套一层<code>el-form-item</code>元素,这样就能分别设置<code>prop</code>属性了。</p> <p>现在我们在看一下重置按钮的效果。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/14/1721251e7e2dbc7e?w=495&h=647&f=gif&s=816782" class="aligncenter"></p> <p>可以看到所有的表单项都重置成功。</p> <h1>表单项属性</h1> <blockquote> <p>表单项属性是指设置在<code>el-form-item</code>上的属性<br> 这里在声明一下一些叫法,以免产生疑惑<br> 当描述<code>表单</code>时,对应的元素为<code>el-form</code><br> 当描述<code>表单项</code>对应的元素为<code>el-form-item</code></p> </blockquote> <h3>prop</h3> <p>这个属性在前面实践<code>表单验证</code>、<code>表单重置</code>的时候用过。</p> <p>那在日常开发中,<code>表单验证</code>和<code>表单重置</code>是一个很常用的功能,因此很有必要在编写代码的时候给表单项设置<code>prop</code>属性,以免出现一些让人疑惑的错误。</p> <blockquote> <p>一定要注意<code>prop</code>属性值的设置一定要和<code>form</code>表单绑定的字段名称一致</p> </blockquote> <h3>label</h3> <p>label属性设置的是表单标签域的文本描述。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/18/17227431f8bce32d?w=713&h=200&f=png&s=7956" class="aligncenter"></p> <h3>size</h3> <p>表单组件的尺寸,共有三个可选值:medium / small / mini。<br> <img src="https://user-gold-cdn.xitu.io/2020/5/18/1722748c9b865136?w=727&h=75&f=png&s=5516" class="aligncenter"></p> <h3>rules</h3> <p>这里的<code>rules</code>是<code>表单项</code>的验证规则,下面我们就<code>活动名称</code>这个字段进行验证。</p> <blockquote> <p>主要改动为将表单属性<code>el-form</code>上的<code>rules</code>移除,在<code>活动名称</code>对应的<code>el-form-item</code>上添加<code>rules</code>规则验证。</p> </blockquote> <pre><code><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Element Form表单实践</title> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> </head> <body> <div id="box"> <span> {{message}} </span> <el-divider></el-divider> <!-- 典型表单 --> <el-form ref="form" :model="form" label-width="120px" label-suffix=":" :status-icon="statusIcon"> <el-form-item label="活动名称" prop="name" :rules="[{required: true,trigger: 'blur',message: '请输入活动名称'}]"> <el-input v-model="form.name" ></el-input> </el-form-item> <el-form-item label="活动区域" prop="region"> <el-select v-model="form.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活动时间" > <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> <el-form-item label="即时配送" prop="delivery"> <el-switch v-model="form.delivery"></el-switch> </el-form-item> <el-form-item label="活动性质" prop="type"> <el-checkbox-group v-model="form.type"> <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox> <el-checkbox label="地推活动" name="type"></el-checkbox> <el-checkbox label="线下主题活动" name="type"></el-checkbox> <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊资源" prop="resource"> <el-radio-group v-model="form.resource"> <el-radio label="线上品牌商赞助"></el-radio> <el-radio label="线下场地免费"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="活动形式" prop="desc"> <el-input type="textarea" v-model="form.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button type="primary" @click="resetForm">重置</el-button> </el-form-item> </el-form> </div> <script> var vm = new Vue({ el: '#box', data: { message: "Element Form表单实践", statusIcon: true, form: { name: '我是初始化设置的活动名称', // 活动名称 region: 'beijing', // 活动区域 date1: new Date(), // 活动时间-日期 date2: new Date(), // 活动时间-时间 delivery: true, // 即时配送 type: ['单纯品牌曝光'], // 活动性质 resource: '线上品牌商赞助', // 特殊资源 desc: '我是初始化设置的活动形式' // 活动形式 }, addFormRules: { name: [{ required: true, // name字段是否必填,true:必填 false:非必填 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "请输入活动名称", // 如果没有填写时的错误提示语 },{ min: 5, // 字段最小长度 max: 10, // 字段最大长度 trigger: 'blur', // 在什么时候触发验证,blur:在元素失去焦点的时候验证规则 message: "活动名称长度在5-10个字符", // 不满足规则时显示的错误提示语 }] } }, methods: { onSubmit() { this.$refs['form'].validate((validate,failedInfo) => { if(validate){ // 将表单数据发送到后端 // 发送 POST 请求 axios.post(url, this.form).then(function (response) { // 处理后端返回的响应数据 }); }else{ // 提示用户 this.$message({ message: '表单数据格式有误,请检查后重新提交.', type: "error", center: true }); } }) }, resetForm(){ this.$refs['form'].resetFields(); } } }) </script> </body> </html> </code></pre> <p>主要的代码如下:</p> <pre><code><el-form-item label="活动名称" prop="name" :rules="[{required: true,trigger: 'blur',message: '请输入活动名称'}]"> <el-input v-model="form.name" ></el-input> </el-form-item> </code></pre> <p>可以看到验证规则添加到表单项<code>el-form-item</code>上和添加到表单<code>el-form</code>上的语法基本上是一致的。</p> <p>接着看下验证的结果。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/5/18/172275da47d5fa40?w=495&h=647&f=gif&s=131461" class="aligncenter"></p> <p>可以看到验证规则已经生效了。</p> <p>最后呢,还有一个操作想进行验证一下,就是同时设置<code>el-form</code>和<code>el-form-item</code>上的<code>rules</code>。</p> <pre><code><el-form ref="form" :model="form" label-width="120px" label-suffix=":" :status-icon="statusIcon" :rules="addFormRules"> <el-form-item label="活动名称" prop="name" :rules="[{required: true,trigger: 'blur',message: '请输入活动名称'}]"> <el-input v-model="form.name" ></el-input> </el-form-item> </el-form> </code></pre> <p>可以看到我将<code>el-form</code>上的<code>rules</code>又添加了回来。</p> <p><code>el-form</code>对活动名称字段的验证规则是<code>不能为空</code>且<code>长度在5-10个字符</code>,而<code>el-item-form</code>上设置的规则只有<code>内容不能为空</code>。</p> <p>我们再来看一下结果。<br> <img src="https://user-gold-cdn.xitu.io/2020/5/18/172276a28a0366c6?w=495&h=647&f=gif&s=185523" class="aligncenter"></p> <p>可以发现只有<code>不为空</code>的验证规则生效了,而长度验证规则并没有生效。所以结论就是<code>el-form</code>上的<code>rules</code>优先级小于<code>el-item-form</code>上的<code>rules</code>规则验证,当<code>el-form-item</code>上有定义字段的验证规则时,就会忽略对应的<code>el-form</code>上定义的字段的验证规则。</p> <h1>结束语</h1> <p>到这里本篇文章就结束了,内容非常的简单。</p> <p>下一篇将会分享项目开发中的一个表单实践,记录在这个过程中遇到的一些问题。</p> <h1>关于</h1> <h3>作者</h3> <p>小土豆biubiubiu</p> <blockquote> <p>一个努力学习的前端小菜鸟,知识是无限的。坚信只要不停下学习的脚步,总能到达自己期望的地方</p> <p>同时还是一个喜欢小猫咪的人,家里有一只美短小母猫,名叫土豆</p> </blockquote> <h3>博客园</h3> <p><a href="https://www.cnblogs.com/HouJiao/" target="_blank">https://www.cnblogs.com/HouJiao/</a></p> <h3>掘金</h3> <p><a href="https://juejin.im/user/58c61b4361ff4b005d9e894d" target="_blank">https://juejin.im/user/58c61b4361ff4b005d9e894d</a></p> <h3>微信公众号</h3> <p>土豆妈的碎碎念</p> <blockquote> <p>微信公众号的初衷是记录自己和身边的一些故事,同时会不定期更新一些技术文章</p> <p>欢迎大家扫码关注,一起吸猫,一起听故事,一起学习前端技术</p> </blockquote> <h3>作者寄语</h3> <p>小小总结,欢迎大家指导~</p><hr class="content-copyright" style="margin-top:50px" /><blockquote class="content-copyright" style="font-style:normal"><p class="content-copyright">版权属于:撩人的无眠兔</p><p class="content-copyright">本文链接:<a class="content-copyright" href="https://www.wumiantu.com/technology/NYuK8Q.html">https://www.wumiantu.com/technology/NYuK8Q.html</a></p><p class="content-copyright">转载时须注明出处及本声明</p></blockquote> © 允许规范转载 赞赏 看了文章不打款? ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付