自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何手寫(xiě)El-Form表單組件

開(kāi)發(fā) 前端
最近又個(gè)項(xiàng)目讓我有開(kāi)始接觸element-ui,想到當(dāng)初對(duì)el-form表單有一些困惑,查看一下源碼和一些技術(shù)文章,對(duì)el-form有一些新的認(rèn)識(shí)。

[[415219]]

本文轉(zhuǎn)載自微信公眾號(hào)「前端有道」,作者星野。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端有道公眾號(hào)。

前言

在剛?cè)胄袝r(shí)候,只會(huì)知道如何使用表單組件,在后面一兩年工作中也沒(méi)有什么技術(shù)積累成為一個(gè)工具人,操作最多的就是ctrl+c和ctrl+v,在去年進(jìn)了一家新公司,這家公司以前舊項(xiàng)目代碼經(jīng)過(guò)太多人的手,代碼已經(jīng)快不成人樣了,難以維護(hù),技術(shù)人員已經(jīng)跑的差不多了,我進(jìn)去好在讓我們負(fù)責(zé)新的項(xiàng)目開(kāi)發(fā),要不然可能第二天就看不到我了,哈哈。項(xiàng)目主要面向于小程序和H5端,網(wǎng)上的UI庫(kù)很難滿足產(chǎn)品后續(xù)規(guī)劃需求開(kāi)發(fā),只好開(kāi)始研究組件原理及封裝組件。

最近又個(gè)項(xiàng)目讓我有開(kāi)始接觸element-ui,想到當(dāng)初對(duì)el-form表單有一些困惑,查看一下源碼和一些技術(shù)文章,對(duì)el-form有一些新的認(rèn)識(shí)。

Form 表單

下面是一份el-form示例代碼

  1. <template> 
  2.   <el-form :model="ruleForm" :rules="rules" ref="ruleForm"
  3.     <el-form-item label="名字" prop="pass"
  4.       <el-input type="password" v-model="ruleForm.pass"></el-input> 
  5.     </el-form-item> 
  6.     <el-form-item label="年齡" prop="age"
  7.       <el-input v-model.number="ruleForm.age"></el-input> 
  8.     </el-form-item> 
  9.     <el-form-item> 
  10.       <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> 
  11.       <el-button @click="resetForm('ruleForm')">重置</el-button> 
  12.     </el-form-item> 
  13.   </el-form> 
  14. </template> 
  15.  
  16. <script> 
  17. export default { 
  18.   data() { 
  19.     return { 
  20.       ruleForm: { 
  21.         pass: ''
  22.         checkPass: ''
  23.         age: ''
  24.       }, 
  25.       rules: { 
  26.         pass: [{ required: true, message: '請(qǐng)輸入名字'trigger'blur' }], 
  27.         age: [{ required: true, message: '請(qǐng)輸入年齡'trigger'blur' }], 
  28.       }, 
  29.     } 
  30.   }, 
  31.   methods: { 
  32.     submitForm(formName) { 
  33.       this.$refs[formName].validate(valid => { 
  34.         if (valid) { 
  35.           alert('submit!'
  36.         } else { 
  37.           console.log('error submit!!'
  38.           return false 
  39.         } 
  40.       }) 
  41.     }, 
  42.     resetForm(formName) { 
  43.       this.$refs[formName].resetFields() 
  44.     }, 
  45.   }, 
  46. </script> 

首先要清楚一下組件的使用方式

1.el-form接收model和rule兩個(gè)prop

  • model表示表單綁定的數(shù)據(jù)對(duì)象
  • rule表示驗(yàn)證規(guī)則策略,表單驗(yàn)證

2.el-form-item接收的prop屬性,對(duì)應(yīng)form組件的model數(shù)據(jù)中某個(gè)key值,如果rule剛好有key,給定的條件下去如失去焦點(diǎn)驗(yàn)證規(guī)則匹不匹配。

最終得到類(lèi)似這樣代碼結(jié)構(gòu)

  1. <template> 
  2.   <div> 
  3.     <form @submit.prevent> 
  4.       <div> 
  5.         姓名<input v-model="form.name" /> 
  6.       </div> 
  7.       <div> 
  8.         年齡<input v-model="form.age" /> 
  9.       </div> 
  10.       <div> 
  11.         <button @click="submit">提交</button> 
  12.       </div> 
  13.     </form> 
  14.   </div> 
  15. </template> 

手寫(xiě)表單組件

組件中嵌套組件,主要是通過(guò)slot插槽,可以將組件拼接成上面代碼結(jié)構(gòu)。代碼如下

el-form

  1. <template> 
  2.     <form> 
  3.         <slot></slot> 
  4.     </form> 
  5. </template> 
  6. <script> 
  7. export default { 
  8.     name:'elForm' 
  9. </script> 

 

el-form-item

  1. <template> 
  2.     <div> 
  3.         <slot></slot> 
  4.     </div> 
  5. </template> 
  6. <script> 
  7. export default { 
  8.     name:'elFormItem' 
  9. </script> 

el-input

  1. <template> 
  2.     <input type="text"
  3. </template> 
  4. <script> 
  5. export default { 
  6.     name:'elInput' 
  7. </script> 

 接下來(lái)就要考慮到組件中的通訊。由于組件中有可能嵌套很多的組件,如果單純通過(guò)$parent和$children查找出來(lái)的父級(jí)組件,不一定是el-form組件。

兩個(gè)問(wèn)題:

  • el-form-item組件如何得到el-form的數(shù)據(jù)
  • el-form組件如何和el-form-item進(jìn)行交互

解決第一問(wèn)題,可以通過(guò)provide與inject實(shí)現(xiàn)。解決第二問(wèn)題,就要講到dispatch派發(fā)和broadcast廣播

provide與inject

通過(guò)provide將當(dāng)前表單實(shí)例傳遞到所有后代組件中,后代通過(guò)inject接受傳遞的值。

el-form

  1. <template> 
  2.     <form><slot></slot></form> 
  3. </template> 
  4. <script> 
  5. export default { 
  6.     name:'elForm'
  7.     provide(){ 
  8.         return { 
  9.             elForm: this 
  10.         }   
  11.     }, 
  12.     props:{ 
  13.         model:{ 
  14.             type:Object, 
  15.             default:()=>({}) 
  16.         }, 
  17.         rules:Object 
  18.     } 
  19. </script> 

el-form-item

  1. <template> 
  2.     <div><slot></slot></div> 
  3. </template> 
  4. <script> 
  5. export default { 
  6.     name:'elFormItem'
  7.     inject:['elForm'], 
  8.     props:{ 
  9.         label:{  
  10.             type:String, 
  11.             default:'' 
  12.         }, 
  13.         prop:String  
  14.     }, 
  15.     mounted(){ 
  16.        console.log(this.elForm) 
  17.     } 
  18. </script> 

provide中this指el-form組件,this.elForm就能得到el-form組件中的數(shù)據(jù)和方法。

dispatch和broadcast廣播

$dispatch與$broadcast是一種有歷史的組件通信方式,因?yàn)樗麄兪荲ue1.0提供的一種方式,在Vue2.0中廢棄了。

$dispatch: $dispatch會(huì)向上觸發(fā)一個(gè)事件,同時(shí)傳遞要觸發(fā)的祖先組件的名稱與參數(shù),當(dāng)事件向上傳遞到對(duì)應(yīng)的組件上時(shí)會(huì)觸發(fā)組件上的事件偵聽(tīng)器,同時(shí)傳播會(huì)停止。

$broadcast: $broadcast會(huì)向所有的后代組件傳播一個(gè)事件,同時(shí)傳遞要觸發(fā)的后代組件的名稱與參數(shù),當(dāng)事件傳遞到對(duì)應(yīng)的后代組件時(shí),會(huì)觸發(fā)組件上的事件偵聽(tīng)器,同時(shí)傳播會(huì)停止(因?yàn)橄蛳聜鬟f是樹(shù)形的,所以只會(huì)停止其中一個(gè)葉子分支的傳遞)

$dispatch

  1. /** 
  2.  * 派發(fā) (向上查找) (一個(gè)) 
  3.  * @param componentName // 需要找的組件的名稱 
  4.  * @param eventName // 事件名稱 
  5.  * @param params // 需要傳遞的參數(shù) 
  6.  */ 
  7.     dispatch(componentName, eventName, params) { 
  8.         let parent = this.$parent || this.$root;//$parent 找到最近的父節(jié)點(diǎn) $root 根節(jié)點(diǎn) 
  9.         let name = parent.$options.name; // 獲取當(dāng)前組件實(shí)例的name 
  10.         // 如果當(dāng)前有節(jié)點(diǎn) && 當(dāng)前沒(méi)名稱 且 當(dāng)前名稱等于需要傳進(jìn)來(lái)的名稱的時(shí)候就去查找當(dāng)前的節(jié)點(diǎn) 
  11.         // 循環(huán)出當(dāng)前名稱的一樣的組件實(shí)例 
  12.         while (parent && (!name||name!==componentName)) { 
  13.             parent = parent.$parent; 
  14.             if (parent) { 
  15.                 name = parent.$options.name
  16.             } 
  17.         } 
  18.         // 有節(jié)點(diǎn)表示當(dāng)前找到了name一樣的實(shí)例 
  19.         if (parent) { 
  20.             parent.$emit.apply(parent,[eventName].concat(params)) 
  21.         } 
  22.     }, 

$broadcast

  1. /** 
  2.  * 派發(fā) (向上查找) (一個(gè)) 
  3.  * @param componentName // 需要找的組件的名稱 
  4.  * @param eventName // 事件名稱 
  5.  * @param params // 需要傳遞的參數(shù) 
  6.  */ 
  7. broadcast(componentName, eventName, params) { 
  8. // 循環(huán)子節(jié)點(diǎn)找到名稱一樣的子節(jié)點(diǎn) 否則 遞歸 當(dāng)前子節(jié)點(diǎn) 
  9. this.$children.map(child=>{ 
  10.     if (componentName===child.$options.name) { 
  11.         child.$emit.apply(child,[eventName].concat(params)) 
  12.     }else { 
  13.         broadcast.apply(child,[componentName,eventName].concat(params)) 
  14.     } 
  15. }) 

驗(yàn)證表單

async-validator是一個(gè)表單的異步驗(yàn)證的第三方庫(kù),也是element-ui 中的form組件所使用的驗(yàn)證方式。 

el-form-item

  1. <template> 
  2.   <div> 
  3.     <label v-if="label">{{label}}</label> 
  4.     <slot></slot> 
  5.     {{errorMessage}} 
  6.   </div> 
  7. </template> 
  8. <script> 
  9. import Schema from "async-validator"
  10. export default { 
  11.   name"elFormItem"
  12.   inject: ["elForm"], 
  13.   props: { 
  14.     label: { 
  15.       type: String, 
  16.       default"" 
  17.     }, 
  18.     prop: String 
  19.   }, 
  20.   data(){ 
  21.       return {errorMessage:''
  22.   }, 
  23.   mounted() { 
  24.     this.$on("validate", () => { 
  25.       if (this.prop) { 
  26.         let rule = this.elForm.rules[this.prop]; 
  27.         let newValue = this.elForm.model[this.prop]; 
  28.  
  29.         let descriptor = { 
  30.           [this.prop]: rule 
  31.         }; 
  32.         let schema = new Schema(descriptor); 
  33.          
  34.         return schema.validate({[this.prop]:newValue},(err,res)=>{ 
  35.             if(err){ 
  36.                 this.errorMessage = err[0].message; 
  37.             }else
  38.                 this.errorMessage = '' 
  39.             } 
  40.         }) 
  41.       } 
  42.     }); 
  43.   } 
  44. }; 
  45. </script> 

 

責(zé)任編輯:武曉燕 來(lái)源: 前端有道
相關(guān)推薦

2011-07-18 09:48:10

jQuery

2016-12-13 13:54:10

EasyUI form數(shù)據(jù)加載

2023-03-15 08:42:06

form表單設(shè)計(jì)接口

2009-07-23 16:59:31

ASP.NET認(rèn)證Form表單

2009-07-03 13:24:56

JSP表單

2021-01-12 09:04:12

Django FormForm組件開(kāi)發(fā)

2009-07-29 16:40:50

Ajax提交asp.n

2009-06-30 15:19:55

Form表單JSP入門(mén)

2022-01-25 18:11:55

vdomclassfunction

2021-02-20 12:34:53

鴻蒙HarmonyOS應(yīng)用開(kāi)發(fā)

2024-10-05 00:00:05

高性能分布式IM

2025-01-13 07:05:00

精簡(jiǎn)表單移動(dòng)端設(shè)計(jì)表單長(zhǎng)表單設(shè)計(jì)

2021-01-14 09:04:27

Django FormForm組件開(kāi)發(fā)

2022-03-09 09:43:01

工具類(lèi)線程項(xiàng)目

2016-09-27 19:28:37

2023-11-27 08:24:57

FormikReact

2020-11-02 08:19:18

RPC框架Java

2022-09-22 12:38:46

antd form組件代碼

2021-03-18 08:04:54

AQS工具CAS

2022-09-27 08:01:48

遞歸函數(shù)GScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)