一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語言 - JavaScript - vue.js - vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

2022-02-21 16:55Kay_ vue.js

這篇文章主要給大家介紹了關(guān)于vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

近期開發(fā)的移動(dòng)端項(xiàng)目直接上了 vue3 ,新特性 composition api 確實(shí)帶來了全新的開發(fā)體驗(yàn).開發(fā)者在使用這些特性時(shí)可以將高耦合的狀態(tài)和方法放在一起統(tǒng)一管理,并能視具體情況將高度復(fù)用的邏輯代碼單獨(dú)封裝起來,這對(duì)提升整體代碼架構(gòu)的健壯性很有幫助.

如今新啟動(dòng)的每個(gè)移動(dòng)端項(xiàng)目基本上都包含注冊(cè)登錄模塊,本次實(shí)踐過程中針對(duì)登錄注冊(cè)中的表單控件做了一些經(jīng)驗(yàn)上的總結(jié),通過抽離提取共性代碼來提升代碼的可維護(hù)性和開發(fā)效率.

接下來觀察一下美工同學(xué)提供的圖片.

注冊(cè)頁面

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

登錄頁面

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

忘記密碼頁面

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

修改密碼頁面

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

通過觀察上面幾張產(chǎn)品圖片,可以清晰看出構(gòu)成整個(gè)登錄注冊(cè)模塊的核心組件就是 input 輸入框.只要把輸入框組件開發(fā)完備,其他頁面直接引用就行了.

輸入框開發(fā)完了只實(shí)現(xiàn)了靜態(tài)頁面的展示,另外我們還要設(shè)計(jì)一套通用的數(shù)據(jù)校驗(yàn)方案應(yīng)用到各個(gè)頁面中的表單控件.

輸入框組件

從上面分析可知,輸入框組件是整個(gè)登錄注冊(cè)模塊的核心內(nèi)容.我們先看一下輸入框組件有哪幾種 UI 形態(tài).

形態(tài)一

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

左側(cè)有文字 +86 ,中間是輸入框,右側(cè)如果檢測(cè)到輸入框有數(shù)據(jù)輸入顯示叉叉圖標(biāo),如果沒有數(shù)據(jù)為空隱藏圖標(biāo).

形態(tài)二

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

左側(cè)只有一個(gè)輸入框,右側(cè)是文案.文案的內(nèi)容可能是驗(yàn)證碼,也可能是點(diǎn)擊驗(yàn)證碼后顯示的倒計(jì)時(shí)文案.

形態(tài)三

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

左側(cè)依舊只有一個(gè)輸入框,右側(cè)如果檢測(cè)到輸入框有內(nèi)容顯示叉叉圖標(biāo),如果內(nèi)容為空隱藏圖標(biāo).

布局

依據(jù)上面觀察而來的現(xiàn)象分析,我們?cè)O(shè)計(jì)這款 input 組件時(shí)可以將其分為左中右三部分.左側(cè)可能是文案,也可能是空.中間是一個(gè)輸入框.右側(cè)可能是文案也可能是叉叉圖標(biāo).

模板內(nèi)容如下:

<template>
 <div class="input">
  <!--左側(cè),lt是左側(cè)內(nèi)容-->
   <span class="left-text">
   {{ lt }}
   </span>
  
  <!--中間-->
  <input class="content" v-bind="$attrs" :value="value" @input="onChange" /> 
  
  <!--右側(cè),rt判端是驗(yàn)證碼還是叉叉圖標(biāo)-->
   <div v-if="rt == "timer"" class="right-section">
    {{ timerData.content }} <!--可能是"驗(yàn)證碼",也可能是倒計(jì)時(shí) -->
   </div>
   <div
   v-else-if="rt == "close""
   class="right-section"
   >
   <van-icon name="close" /> <!--叉叉圖標(biāo)-->
   </div>
 </div> 
</template>

布局上將左中右的父級(jí)設(shè)置為 display:flex ,子級(jí)的三個(gè)元素全部設(shè)置成 display:inline-block 行內(nèi)塊模式,目的是為了讓左側(cè)和右側(cè)依據(jù)自身內(nèi)容自適應(yīng)寬度,而中間的 input 設(shè)置成 flex:1 充滿剩余的寬度.

理論上這樣的布局是可行的,但實(shí)踐中發(fā)現(xiàn)了問題.

Demo 效果圖如下:

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

右側(cè)持續(xù)增加寬度時(shí),中間 input 由于默認(rèn)寬度的影響導(dǎo)致讓右側(cè)向外溢出了,這并不是我們想要的.

解決這個(gè)問題的辦法很簡(jiǎn)單,只需要將中間 input 的 width 設(shè)置為 0 即可,如下便達(dá)到了我們想要的效果.

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

v-model

外部頁面引用上述封裝的組件結(jié)構(gòu)如下:

 <InputForm
  lt="+86" <!--左側(cè)顯示+86--> 
  rt="close" <!--右側(cè)顯示叉叉圖標(biāo)-->
  placeholder="請(qǐng)輸入手機(jī)號(hào)碼"
 />

外部頁面創(chuàng)建了一個(gè)表單數(shù)據(jù) form_data 如下,但希望能通過 v-model 的形式將 form_data 的數(shù)據(jù)與子組件輸入框的值建立雙向數(shù)據(jù)綁定.

 const form_data = reactive({
  number_number: "", //用戶名
  password: "", //密碼
  ppassword: "", //重復(fù)密碼
  captcha: "", //驗(yàn)證碼
 })

在 vue3 實(shí)現(xiàn) v-model 非常簡(jiǎn)便,在父組件中使用 v-model:xx 完成綁定,這里的 xx 對(duì)應(yīng)著子組件要綁定的狀態(tài)名稱,如下所示.

 <InputForm
    lt="+86"  <!--左側(cè)顯示+86--> 
    rt="close" <!--右側(cè)顯示叉叉圖標(biāo)-->
    placeholder="請(qǐng)輸入手機(jī)號(hào)碼"
    v-model:value="form_data.password"
 />

接下來子組件里首先聲明要綁定的屬性 value ,并監(jiān)聽輸入框的 oninput事件 .代碼如下:

<template>
  <div class="input">
    ...
      <input class="content" v-bind="$attrs" :value="value" @input="onChange" /> 
    ...
  </div> 
</template>
export default defineComponent({
 props: {
  lt:String,
  rt: String,
  value: String
 },
 setup(props, context) {
  const onChange = (e:KeyboardEvent) => {
   const value = (e.target as HTMLInputElement).value;
    context.emit("update:value",value);
  };
  return {
    onChange
  }
 }
 })

oninput事件 的回調(diào)函數(shù)將獲取到的值使用 context.emit("update:value",value) 返回回去.

其中 update:value 里前面部分 update: 為固定寫法,后面填寫要建立雙向綁定的狀態(tài)名稱.如此一來就輕易的完成了 v-model 的綁定.

數(shù)據(jù)校驗(yàn)

一般來說只要頁面上涉及到表單控件(比如輸入框),那么就要針對(duì)相應(yīng)的值做數(shù)據(jù)校驗(yàn).如果按照原始的方法,當(dāng)用戶點(diǎn)擊按鈕, js 接受響應(yīng)依次獲取每個(gè)表單項(xiàng)的值一一校驗(yàn).

這樣的做法當(dāng)然可以實(shí)現(xiàn)功能,但并不高效和精簡(jiǎn).因?yàn)楹芏囗撁娑家鲂r?yàn),大量的校驗(yàn)邏輯是重復(fù)書寫的.

我們接下來設(shè)計(jì)一套通用的校驗(yàn)方案,將那些可以復(fù)用的邏輯代碼都封裝起來,并且能夠快速的應(yīng)用到每個(gè)頁面上,提升開發(fā)效率.

依注冊(cè)頁面為例,模板代碼如下.創(chuàng)建四個(gè)輸入框組件:手機(jī)號(hào),手機(jī)驗(yàn)證碼,密碼和確認(rèn)密碼.最后面再放置一個(gè)注冊(cè)按鈕.(為了看起來更清晰,下面的代碼將所有 ts 類型刪除)

 <Form ref="form" :rules="rules">
 
   <InputForm
    lt="+86"
    rt="close"
    v-model:value="form_data.number_number"
    placeholder="請(qǐng)輸入手機(jī)號(hào)碼"
    propName="number_number"
   />
   
   <InputForm
    rt="timer"
    v-model:value="form_data.captcha"
    placeholder="請(qǐng)輸入手機(jī)驗(yàn)證碼"
    propName="captcha"
   />

   <InputForm
    rt="close"
    v-model:value="form_data.password"
    placeholder="請(qǐng)輸入密碼"
    type="password"
    propName="password"
   />

   <InputForm
    rt="close"
    v-model:value="form_data.ppassword"
    placeholder="請(qǐng)輸入確認(rèn)密碼"
    type="password"
    propName="ppassword"
   />

   <Button text="注 冊(cè)" @sub="onSubmmit" /> <!--注冊(cè)按鈕-->

  </Form>

在借鑒了一些其他優(yōu)秀框架的表單實(shí)踐后,我們首先是在最外層增加了一個(gè)組件 Form ,其次給每個(gè)輸入框組件增加了一個(gè)屬性 propName .這個(gè)屬性是配合 rules 一起使用的, rules 是手動(dòng)定義的校驗(yàn)規(guī)則,當(dāng)它傳遞給 Form 組件后,子組件(輸入框組件)就能通過 propName 屬性拿到屬于它的校驗(yàn)規(guī)則.

整體的實(shí)現(xiàn)思路可以從頭串聯(lián)一遍.首先是前端開發(fā)者定義好當(dāng)前頁面的校驗(yàn)規(guī)則 rules ,并將它傳遞給 Form 組件. Form 組件接受到后會(huì)將校驗(yàn)規(guī)則分發(fā)給它的每個(gè)子組件(輸入框組件).子組件拿到校驗(yàn)規(guī)則后就能夠針對(duì)輸入框的值做相應(yīng)的數(shù)據(jù)校驗(yàn).

當(dāng)用戶點(diǎn)擊注冊(cè)按鈕時(shí),點(diǎn)擊事件會(huì)獲取 Form 組件的實(shí)例,并運(yùn)行它的 validate 方法,此時(shí) Form 組件就會(huì)對(duì)它旗下的每個(gè)子組件做一輪數(shù)據(jù)校驗(yàn).一旦所有校驗(yàn)成功了, validate 方法返回 true .存在一個(gè)校驗(yàn)沒通過, validate 方法就返回 false ,并彈出錯(cuò)誤信息.

注冊(cè)頁面邏輯如下:

export default defineComponent({
 components: {
  InputForm, //輸入框
  Button, //注冊(cè)按鈕
  Form, //Form組件
 },
 setup(props) {
 
  const form_data = ...; //省略
  
  const rules = ...;
  
  //獲取最外層Form組件的實(shí)例
  const form = ref(null);
  
  const onSubmmit = ()=>{
   if (!form.value || !form.value.validate()) {
     return false;
   }
   //校驗(yàn)通過了,可以請(qǐng)求注冊(cè)接口了
  }

  return {
   form,
   rules,
   onSubmmit,
   form_data
  };
 },
});

定義一個(gè)變量 form ,用它來獲取 Form 表單的實(shí)例.模板上 <Form ref="form" :rules="rules"> 只需要加上一個(gè) ref 屬性就可以了.

用戶點(diǎn)擊注冊(cè)按鈕觸發(fā) onSubmmit 函數(shù),因?yàn)?form 是使用 ref 創(chuàng)建的變量,獲取值要調(diào)用 .value .運(yùn)行 form.value.validate() 函數(shù),就能讓 Form 表單下面的每一個(gè)子組件開始執(zhí)行校驗(yàn)邏輯,如果全部通過就會(huì)返回 true ,存在一個(gè)沒通過返回 false .

從上面分析可知, Form 控件只對(duì)外暴露一個(gè) validate 函數(shù),通過調(diào)用該函數(shù)就能知道校驗(yàn)是否通過.那么 validate 如何知道該采用什么規(guī)則來校驗(yàn)?zāi)?所以我們要先設(shè)計(jì)一套校驗(yàn)的規(guī)則 rules ,把它傳給 Form 組件,那么它內(nèi)部的 validate 函數(shù)就能采用規(guī)則來執(zhí)行校驗(yàn).

rules設(shè)計(jì)

rules 是一個(gè)對(duì)象,例如上述注冊(cè)頁面的 rules 定義如下:

const rules = {
   number_number:[{
        type: "required",
        msg:"請(qǐng)輸入正確的手機(jī)號(hào)" 
      }
        "phone"
      ],
   captcha:[
    {
     type: "required",
     msg: "驗(yàn)證碼不能為空"
    }
   ],
   password: [
    {
     type: "required",
     msg: "請(qǐng)輸入密碼",
    },
    {
     type: "minLength",
     params: 6,
     msg: "密碼長(zhǎng)度不能小于6位",
    },
   ],
   ppassword:[
    {
     type: "custome",
     callback() {
      if (form_data.password !== form_data.ppassword) {
       return {
        flag: false,
        msg: "兩次輸入的密碼不一致",
       };
      }
      return {
       flag: true,
      };
     },
    },
   ]
  }

我們定義的 rules 是一個(gè)鍵值對(duì)形式的對(duì)象. key 對(duì)應(yīng)著模板上每個(gè)輸入框組件的 propName ,值是一個(gè)數(shù)組,對(duì)應(yīng)著該輸入框組件要遵守的規(guī)則.

現(xiàn)在細(xì)致的看下每個(gè)對(duì)象下的值的構(gòu)成,值之所以組織成數(shù)組形式,是因?yàn)檫@樣可以給輸入框增加多條規(guī)則.而規(guī)則對(duì)應(yīng)著兩種形式,一種是對(duì)象,另外一種是字符串.

字符串很好理解,比如上面的 number_number 屬性,它就對(duì)應(yīng)著字符串 phone .這條規(guī)則的意義就是該輸入框的值要遵守手機(jī)號(hào)的規(guī)則.當(dāng)然字符串如果填 email ,那就要當(dāng)做郵箱來校驗(yàn).

規(guī)則如果為對(duì)象,那么它包含了以下幾個(gè)屬性:

 {
  type, // 類型
  msg, //自定義的錯(cuò)誤信息
  params, //傳過來的參數(shù)值 比如 {type:"minLength",params:6},值最小長(zhǎng)度不能低于6位
  callback //自定義校驗(yàn)函數(shù)
 }

type 是校驗(yàn)類型,它如果填 required ,表示是必填項(xiàng).如果用戶沒填,點(diǎn)擊注冊(cè)按鈕提交時(shí)就會(huì)報(bào)出 msg 定義的錯(cuò)誤信息.

另外 type 還可以填 minLength 或者 maxLength 用來限定值的長(zhǎng)度,那到底限定為幾位呢,可以通過 params 傳遞過去.

最后 type 還可以填 custome ,那么就是讓開發(fā)者自己來定義該輸入框的校驗(yàn)邏輯函數(shù) callback .該函數(shù)要求最后返回一個(gè)帶有 flag 屬性的對(duì)象,屬性 flag 為布爾值,它會(huì)告訴校驗(yàn)系統(tǒng)本次校驗(yàn)是成功還是失敗.

Form表單

rules 被定義好后傳給 Form 組件, Form 組件需要將校驗(yàn)邏輯分發(fā)給它的子組件.讓其每個(gè)子組件都負(fù)責(zé)生成自己的校驗(yàn)函數(shù).

<!-- 表單組件 -->
<template>
 <div class="form">
  <slot></slot>
 </div>
</template>

<script lang="ts">
import { ref, provide } from "vue";
export default defineComponent({
 name: "Form",
 props:{
  rules:Object
 },
 setup(props) {
  
  ...//省略

  provide("rules",props.rules); // 將校驗(yàn)規(guī)則分發(fā)下去
  
  const validate = ()=>{
   //向外暴露的校驗(yàn)函數(shù)
  }
  
  return {
   validate
  } 
 }
 }) 
</script>  

從上面結(jié)構(gòu)可以看出, Form 組件模板提供了一個(gè)插槽的作用,在邏輯代碼里利用 provide 將校驗(yàn)規(guī)則傳給后代,并向外暴露一個(gè) validate 函數(shù).

子組件生成校驗(yàn)函數(shù)

這一次又回到了登錄注冊(cè)模塊的核心組件 InputForm ,我們現(xiàn)在要給該輸入框組件添加校驗(yàn)邏輯.

import { inject,onMounted } from "vue";
...

setup(props, context) {

 const rules = inject("rules");
 
 const rule = rules[props.propName];// 通過propName拿到校驗(yàn)規(guī)則
 
 const useValidate = () => {
      const validateFn = getValidate(rule); // 獲取校驗(yàn)函數(shù)
      const execValidate = () => { 
        return validateFn(props.value); //執(zhí)行校驗(yàn)函數(shù)并返回校驗(yàn)結(jié)果    
      };
      onMounted(() => {
        const Listener = inject("collectValidate");
        if (Listener) {
         Listener(execValidate);
        }
      });  
 };
 
 useValidate(); //初始化校驗(yàn)邏輯
 ...
}

rules 結(jié)構(gòu)類似如下.通過 inject 和 propName 可以拿到 Form 分發(fā)給該輸入框要執(zhí)行的規(guī)則 rule .

{
  captcha:[{
   type: "required",
   msg: "驗(yàn)證碼不能為空"
  }],
  password:[{
   type: "required",
   msg: "請(qǐng)輸入密碼", 
  }]
}

再將規(guī)則 rule 傳遞給 getValidate 函數(shù)(后面會(huì)講)獲取校驗(yàn)函數(shù) validateFn .校驗(yàn)函數(shù) validateFn 傳入輸入框的值就能返回校驗(yàn)結(jié)果.在這里把 validateFn 封裝了一層賦予 execValidate 給外部使用.

在上面的代碼中我們還看到了 onMounted 包裹的邏輯代碼.當(dāng)組件掛載完畢后,使用 inject 拿到 Form 組件傳遞下來的一個(gè)函數(shù) Listener ,并將校驗(yàn)函數(shù) execValidate 作為參數(shù)傳遞進(jìn)去執(zhí)行.

我們?cè)倩氐较旅娲a中的 Form 組件,看一下 Listener 是一個(gè)什么樣的函數(shù).

setup(props) {

const list = ref([]);//定義一個(gè)數(shù)組

const listener = (fn) => {
 list.value.push(fn);
};

provide("collectValidate", listener); //將監(jiān)聽函數(shù)分發(fā)下去

//驗(yàn)證函數(shù)
const validate = (propName) => {
  const array = list.value.map((fn) => {
    return fn();
  });
  const one = array.find((item) => {
    return item.flag === false;
  });
  if (one && one.msg) {
    //驗(yàn)證不通過
    Alert(one.msg);//彈出錯(cuò)誤提示
    return false;
  } else {
    return true;
  }
};
...

從上面可以看出, Form 組件將 listener 函數(shù)分發(fā)了下去.而子組件在 onMounted 的生命周期鉤子里,獲取到分發(fā)下來的 listener 函數(shù),并將子組件內(nèi)部定義的校驗(yàn)函數(shù) execValidate 作為參數(shù)傳遞進(jìn)去執(zhí)行.

這樣一來就可以確保每個(gè)子組件一旦掛載完畢就會(huì)把自己的校驗(yàn)函數(shù)傳遞給 Form 組件中的 list 收集.而 Form 組件的 validate 方法只需要循環(huán)遍歷 list ,就可以依次執(zhí)行每個(gè)子組件的校驗(yàn)函數(shù).如果都校驗(yàn)通過了,給外部頁面返回 true .存在一個(gè)不通過,彈出錯(cuò)誤提示返回 false .

走到這里整個(gè)校驗(yàn)的流程已經(jīng)打通了. Form 首先向子組件分發(fā)校驗(yàn)規(guī)則,子組件獲取規(guī)則生成自己的校驗(yàn)函數(shù),并且在其掛載完畢后將校驗(yàn)函數(shù)再返回給 Form 收集起來.這個(gè)時(shí)候 Form 組件向外暴露的 validate 函數(shù)就可以實(shí)現(xiàn)針對(duì)所有表單控件的數(shù)據(jù)校驗(yàn).

接下來最后一步研究子組件如果通過規(guī)則來生成自己的校驗(yàn)函數(shù).

校驗(yàn)

首先編寫一個(gè)管理校驗(yàn)邏輯的類 Validate .代碼如下.我們可以不斷的根據(jù)新需求擴(kuò)充該類的方法,比如另外再增加 email 或者 maxLength 方法.

class Validate {

 constructor() {}

 required(data) { //校驗(yàn)是否為必填  
  const msg = "該信息為必填項(xiàng)"; //默認(rèn)錯(cuò)誤信息
  if (data == null || (typeof data === "string" && data.trim() === "")) {
   return {
    flag:false,
    msg
   }
  }
  return {
    flag:true
  }
 }
 
 //校驗(yàn)是否為手機(jī)號(hào)
 phone(data) { 
  const msg = "請(qǐng)?zhí)顚懻_的手機(jī)號(hào)碼"; //默認(rèn)錯(cuò)誤信息
  const flag = /^1[3456789]d{9}$/.test(data);
  return {
   msg,
   flag
  }
 }
 
 //校驗(yàn)數(shù)據(jù)的最小長(zhǎng)度
 minLength(data, { params }) {
  
    let minLength = params; //最小為幾位
    
    if (data == null) {
     return {
      flag:false,
      msg:"數(shù)據(jù)不能為空"
     }
    }

    if (data.trim().length >= minLength) {
     return {flag:true};
    } else {
     return {
      flag:false,
      msg:`數(shù)據(jù)最小長(zhǎng)度不能小于${minLength}位`
     }
    } 
  }

}

Validate 類定義的所有方法中,第一個(gè)參數(shù) data 是被校驗(yàn)的值,第二個(gè)參數(shù)是在頁面定義每條 rule 中的規(guī)則.形如 {type: "minLength", params: 6, msg: "密碼長(zhǎng)度不能小于6位"} .

Validate 類中每個(gè)方法最終的返回的數(shù)據(jù)結(jié)構(gòu)形如 {flag:true,msg:""} .結(jié)果中 flag 就來標(biāo)識(shí)校驗(yàn)是否通過, msg 為錯(cuò)誤信息.

校驗(yàn)類 Validate 提供了各種各樣的校驗(yàn)方法,接下來運(yùn)用一個(gè)單例模式生成該類的一個(gè)實(shí)例,將實(shí)例對(duì)象應(yīng)用到真實(shí)的校驗(yàn)場(chǎng)景中.

 const getInstance = (function(){
  let _instance;
  return function(){
     if(_instance == null){
      _instance = new Validate();
     }
     return _instance;
   }
 })()

通過調(diào)用 getInstance 函數(shù)就可以得到單例的 Validate 實(shí)例對(duì)象.

輸入框組件通過給 getValidate 函數(shù)傳入一條 rule ,就能返回該組件需要的校驗(yàn)函數(shù).接下來看一下 getValidate 函數(shù)是如何通過 rule 來生成校驗(yàn)函數(shù)的,代碼如下:

/**
 * 生成校驗(yàn)函數(shù)
 */
export const getValidate = (rule) => {
  const ob = getInstance();//獲取 Validate類 實(shí)例對(duì)象
  const fn_list = []; //將所有的驗(yàn)證函數(shù)收集起來
  //遍歷rule數(shù)組,根據(jù)其類型獲取Validate類中的校驗(yàn)方法放到fn_list中收集起來
  rule.forEach((item) => {
   if (typeof item === "string") { // 字符串類型 
    fn_list.push({
     fn: ob[item], 
    });
   } else if (isRuleType(item)) { // 對(duì)象類型
    fn_list.push({
     //如果item.type為custome自定義類型,校驗(yàn)函數(shù)直接使用callback.否則從ob實(shí)例獲取 
     ...item, 
     fn: item.type === "custome" ? item.callback : ob[item.type],
    });
   }
  });
  //需要返回的校驗(yàn)函數(shù)
  const execuate = (value) => {
   let flag = true,
    msg = "";
   for (let i = 0; i < fn_list.length; i++) {
    const item = fn_list[i];
    const result = item.fn.apply(ob, [value, item]);//item.fn對(duì)應(yīng)著Validate類定義的的校驗(yàn)方法
    if (!result.flag) {
     //驗(yàn)證沒有通過
     flag = false;
     msg = item.msg ? item.msg : result.msg;//是使用默認(rèn)的報(bào)錯(cuò)信息還是用戶自定義信息 
     break;
    }
   }
   return {
    flag,
    msg,
   };
  };
  return execuate;
};

rule 的數(shù)據(jù)結(jié)構(gòu)形類似如下代碼.當(dāng)把 rule 傳入 getValidate 函數(shù),它會(huì)判端是對(duì)象還是字符串,隨后將其類型對(duì)應(yīng)的校驗(yàn)函數(shù)從 ob 實(shí)例中獲取存儲(chǔ)到 fn_list 中.

 [
  {
   type: "required",
   msg: "請(qǐng)輸入電話號(hào)碼"
  },
  "phone"
 ]

getValidate 函數(shù)最終返回 execuate 函數(shù),此函數(shù)也正是輸入框組件得到的校驗(yàn)函數(shù).在輸入框組件里是可以拿到輸入框值的,如果將值傳給 execuate 方法調(diào)用.方法內(nèi)部就會(huì)遍歷之前緩存的校驗(yàn)函數(shù)列表 fn_list ,將值傳入每個(gè)校驗(yàn)方法運(yùn)行就能獲取該輸入框組件對(duì)當(dāng)前值的校驗(yàn)結(jié)果并返回回去.

以上校驗(yàn)的邏輯也已經(jīng)走通了.接下來不管是開發(fā)登錄頁,忘記密碼或者修改密碼的頁面,只需要使用 Form 組件和輸入框 InputForm 組件組織頁面結(jié)構(gòu),并寫一份當(dāng)前頁面的 rules 校驗(yàn)規(guī)則即可.剩下的所有校驗(yàn)細(xì)節(jié)和交互動(dòng)作全部交給了 Form 和 InputForm 內(nèi)部處理,這樣會(huì)極大的提升開發(fā)效率.

最終效果

vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊

總結(jié)

到此這篇關(guān)于vue3如何優(yōu)雅的實(shí)現(xiàn)移動(dòng)端登錄注冊(cè)模塊的文章就介紹到這了,更多相關(guān)vue3移動(dòng)端登錄注冊(cè)模塊內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6944346735540076575

延伸 · 閱讀

精彩推薦
  • vue.jsVue項(xiàng)目中實(shí)現(xiàn)帶參跳轉(zhuǎn)功能

    Vue項(xiàng)目中實(shí)現(xiàn)帶參跳轉(zhuǎn)功能

    最近做了一個(gè)手機(jī)端系統(tǒng),其中遇到了父頁面需要攜帶參數(shù)跳轉(zhuǎn)至子頁面的問題,現(xiàn)已解決,下面分享一下實(shí)現(xiàn)過程,感興趣的朋友一起看看吧...

    YiluRen丶4302022-03-03
  • vue.jsVue多選列表組件深入詳解

    Vue多選列表組件深入詳解

    這篇文章主要介紹了Vue多選列表組件深入詳解,這個(gè)是vue的基本組件,有需要的同學(xué)可以研究下...

    yukiwu6752022-01-25
  • vue.jsVue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn)

    Vue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn)

    這篇文章主要介紹了Vue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋...

    優(yōu)小U9632022-02-21
  • vue.js詳解vue 表單綁定與組件

    詳解vue 表單綁定與組件

    這篇文章主要介紹了vue 表單綁定與組件的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下...

    Latteitcjz6432022-02-12
  • vue.js梳理一下vue中的生命周期

    梳理一下vue中的生命周期

    看過很多人講vue的生命周期,但總是被繞的云里霧里,尤其是自學(xué)的同學(xué),可能js的基礎(chǔ)也不是太牢固,聽起來更是吃力,那我就已個(gè)人之淺見,以大白話...

    CRMEB技術(shù)團(tuán)隊(duì)7992021-12-22
  • vue.jsVue2.x-使用防抖以及節(jié)流的示例

    Vue2.x-使用防抖以及節(jié)流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節(jié)流的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下...

    Kyara6372022-01-25
  • vue.jsVue中引入svg圖標(biāo)的兩種方式

    Vue中引入svg圖標(biāo)的兩種方式

    這篇文章主要給大家介紹了關(guān)于Vue中引入svg圖標(biāo)的兩種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的...

    十里不故夢(mèng)10222021-12-31
  • vue.js用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法

    用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法

    這篇文章主要介紹了用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下...

    Asiter7912022-01-22
主站蜘蛛池模板: 美女奶口隐私免费视频网站 | 91素人约啪 | 91视频一区 | 放荡护士玩3p口述 | 亚洲www美色 | 四虎精品成人免费观看 | 全色黄大色黄大片爽一次 | 女同性互吃奶乳免费视频 | 亚洲欧美日韩另类在线 | 国产精品va在线观看手机版 | 日本69视频在线观看 | 激情小说欧美图片 | 亚洲天堂v | 亚洲精品福利你懂 | 3x3x3x短视频在线看 | 好大夫在线个人空间 | 九九热在线观看视频 | 日韩 欧美 国产 亚洲 中文 | 99精品久久99久久久久久 | 日韩精品成人 | 麻豆网页| 喜马拉雅听书免费版 | 欧美另类性xxoo | 亚洲男人的天堂网站 | 大东北chinesexxxx露脸 | 青草午夜精品视频在线观看 | 国产愉拍 | 亚洲精品视频免费在线观看 | 国产在线视频自拍 | 91丝袜足控免费网站xx | 91传媒制片厂果冻有限公司 | 天堂8在线天堂资源在线 | 四虎地址 | 亚洲AV 中文字幕 国产 欧美 | 经典千人斩一区二区视频 | 欧美另类z0zxi| 日本人在线看片 | 久久免费国产视频 | 亚洲国产成人久久精品hezyo | 亚洲 欧美 偷自乱 图片 | 91麻豆精品国产自产在线 |