【流鶯書籤】基礎組件(Form,Input)

寫在前面

項目地址

👉👉項目預覽地址,能夠直接設置爲瀏覽器主頁或者桌面快捷方式進行使用javascript

源碼地址

徹底開源,你們能夠隨意研究,二次開發。固然仍是十分歡迎你們點個Star⭐⭐⭐
👉👉源碼連接(gitee)       👉👉源碼連接(github)vue

簡介

本文記錄了流鶯書籤封裝的部分基礎組件,包括java

Inputreact

Formgit

因爲本項目是爲了練手,因此在某些組件中可能也添加了一些實際並無用到的功能,接下來將逐個介紹這些組件的屬性,方法,以及一些設計思路.github

除了一些特殊的樣式,文章不會大量貼出CSS代碼,因爲我SASS功底不是很好,CSS代碼看起來也是比較臃腫😣😣😣,感興趣的同窗能夠自行查看源碼數組

目錄結構

基本就是一個組件的.vue文件和一個對應的index.ts,index.ts存放一些基礎數據,類型聲明等瀏覽器

├── src 
     ├── assets      // 存放靜態資源
     ├── baseComponents  // 基礎組件
         └──Form    // 表單組件
         │    ├──Form.vue
              └──index.ts
         └── Input    // 輸入框組件
              ├──Input.vue
              └──index.ts
         ......
複製代碼

Input

展現

先來看效果服務器

16.gif

屬性

  • rules 驗證規則
  • width 寬度
  • padding 內邊距
  • modelValue 輸入框的綁定值

設計思路/亮點

🌝paddingwidth屬性主要是爲了樣式,其實也能夠在組件引用的時候經過類名去修改,至於哪一種更好用就仁者見仁,智者見智了markdown

🌝vue3中給組件綁定值使用的是modelValue,具體的用法請看代碼或者移步vue3官網

🌝比較複雜的就是內容校驗,我使用的是策略模式進行封裝,易於擴展.驗證的時候只須要調用handlerValidateInput函數,傳入值和驗證規則便可,返回一個boolen值,若是有多條規則,只需循環調用handlerValidateInput,並結合every方法,當有一個驗證沒有經過的時候即返回false,那麼組件中就能夠根據這個返回值去作一些事情了

🌝我這裏是結合message組件,當驗證不經過的時候就提示錯誤信息,也能夠在組件中加一個標籤結合v-show在輸入框下方進行錯誤提示,就如同一些大型的組件庫那樣,可是我試了不是很好看,就沒有采用這種方式

🌝因爲vue3中的$on,$off等指令的移除,爲了能結合Form組件進行總體驗證,我使用了mitt這個插件,它的做用和$on,$off是同樣的,只不過不內置在vue3中了.具體的使用方法請查看mitt.js官網,超級簡單就不講了.在Input組件初始化的時候觸發一個方法,向Form組件添加驗證函數,Form組件有一個對應的方法收集全部的驗證函數,用於統一驗證

🌝能夠看到我這裏是套了一層div的,因此爲了讓我在使用組件時綁定的屬性(例如placeholder)不繼承在這一層div上,使用v-bind="$attrs"inheritAttrs: false來讓input繼承屬性

所有代碼

//Input.vue
<template>
  <div class="wh-input-box" :style='{width:width,padding:padding}'> <input class="wh-input" v-model="value" @change='validateInput' v-bind='$attrs'> </div> </template>

<script lang='ts'> //此處省略文件引用,詳情請查看源碼 export default defineComponent({ name: 'Wh-input', inheritAttrs: false, // 根元素不繼承$attrs props: { rules: { type: Array as PropType<RulesProp>, default: () => [], }, modelValue: String, width: { type: String, default: '100%', }, padding: { type: String, default: '30px', }, }, emits: ['update:modelValue'], setup(props, { emit }) { // 定義一個數據類型 包括值 是否錯誤 錯誤信息 const inputRef = reactive({ // 使用計算屬性的get,set方法來實現修改input值 value: computed({ get: () => props.modelValue || '', set: (val) => { emit('update:modelValue', val); }, }), error: false, message: '', }); // 驗證函數 const validateInput = () => { // 循環rules數組 返回結果 every如有一個沒經過返回false 全經過返回true const isAllPass = props.rules?.every((rule) => { // 賦值錯誤信息 inputRef.message = rule.message; // 執行驗證函數 return handlerValidateInput(inputRef.value, rule); }); // 若是有沒經過的驗證,則激活error錯誤開關 inputRef.error = !isAllPass; if (!isAllPass) { createMessage(inputRef.message); } return isAllPass; }; // 初始化的時候執行form-item-created,向form組件添加驗證函數 onMounted(() => { emitter.emit('form-item-created', validateInput); }); return { ...toRefs(inputRef), validateInput, }; }, }); </script> //此處省略部分CSS代碼,詳情請查看源碼 複製代碼
//index.ts
// 單個驗證規則
export type RuleType = 'required' | 'maxlength' | 'custom';
export interface RuleProp {
  type: RuleType;
  message: string;
  maxlength?: number;
  validator?: (value: string) => boolean;
}

// 驗證規則組合
export type RulesProp = RuleProp[];

// 單個input的驗證器
export const validateInput = {
  // 是否必填
  required: (value: string, rule?: RuleProp) => {
    return value.trim() !== '';
  },
  // 最大長度
  maxlength: (value: string, rule: RuleProp) => {
    if (rule.maxlength) {
      return value.length <= rule.maxlength;
    }
    return true;
  },
  // 自定義驗證器
  custom: (value: string, rule: RuleProp) => {
    if (rule.validator) {
      return rule.validator(value);
    }
    return true;
  },
};

// 驗證器處理程序
export const handlerValidateInput = (value: string, rule: RuleProp) => {
  return validateInput[rule.type](value, rule);
};
複製代碼

組件中使用

正常引入傳參便可使用

<wh-input :rules='rules' type="text" v-model="labelTitle" placeholder="請輸入標籤名稱" padding='50px 30px' maxlength='10'></wh-input>
複製代碼

Form

設計思路/亮點

🌝經過mitt插件使用一個數組來接受全部Input組件的驗證函數,就能夠在表單提交的時候進行總體的驗證了,由於每個驗證函數返回一個boolen值,因此結合every函數就很容易作到當某一條沒有經過的時候進行錯誤提示

🌝由於流鶯書籤暫時用到的表單組件幾乎都是Input,樣式比較容易管理,因此就沒有設計form-item,之後隨着功能的擴展可能會考慮這樣作

代碼

//Form.vue
<template>
  <form class='valid-form-container'> <slot name='default'></slot> </form>
</template>

<script lang='ts'> import { defineComponent, onUnmounted } from 'vue'; import { emitter, ValidateFunc } from 'base/Form/index'; export default defineComponent({ name: 'ValidateForm', setup() { // 聲明一個空數組 用來存放全部的驗證函數 let funcArr: ValidateFunc[] = []; // 驗證函數 const submitForm = () => { // 獲取全部item的驗證結果,有一個沒有經過返回false 不然返回true const result = funcArr.every((func) => func()); return result; }; // 把item的驗證函數添加到數組中 const addValidater = (func: ValidateFunc | undefined) => { funcArr.push(func as ValidateFunc); }; // 監聽form-item-created事件,當有item觸發的時候把驗證函數添加到數組中 emitter.on('form-item-created', addValidater); // 組件卸載的時候移除監聽事件,數組重置爲空 onUnmounted(() => { emitter.off('form-item-created', addValidater); funcArr = []; }); return { submitForm, }; }, }); </script>
複製代碼
//index.ts
import mitt, { Emitter } from 'mitt';
export const emitter: Emitter = mitt();
export type ValidateFunc = () => boolean;
複製代碼

組件中使用

須要在組件中綁定ref屬性,而後調用form.value.submitForm()來進行驗證,這個ref屬性必定要在return中返回,否則不會生效,這裏也是栽過一個跟頭

<wh-from ref='form'>
  <wh-input :rules='rules' type="text" v-model="labelTitle" placeholder="請輸入標籤名稱" ></wh-input>
</wh-from>

<script lang='ts'> //此處省略文件引用,詳情請查看源碼 export default defineComponent({ components: { WhInput, WhFrom, }, setup(props, { emit }) { const form = ref<any>(null); const submitAll = () => { const result = form.value.submitForm(); if (result) { createMessage({ type: 'success', message: '驗證經過!' }); } }; return { form, submitAll }; }, }); </script> 複製代碼

寫在最後

請你們不吝賜教,在下方評論或者私信我,十分感謝🙏🙏🙏.

✅認爲我某個部分的設計過於繁瑣,有更加簡單或者更高逼格的封裝方式

✅認爲我部分代碼過於老舊,能夠提供新的API或最新語法

✅對於文章中部份內容不理解

✅解答我文章中一些疑問

✅認爲某些交互,功能須要優化,發現BUG

✅想要添加新功能,對於總體的設計,外觀有更好的建議

最後感謝各位的耐心觀看,既然都到這了,點個 👍贊再走吧

連接整合

🔊項目預覽地址(GitHub Pages):👉👉alanhzw.github.io

🔊項目預覽備用地址(本身的服務器):👉👉warbler.duwanyu.com

🔊源碼地址(gitee):👉👉gitee.com/hzw_0174/Wa…

🔊源碼地址(github):👉👉github.com/alanhzw/War…

🔊流鶯書籤-從零搭建一個Vite+Vue3+Ts項目:👉👉juejin.cn/post/695130…

🔊流鶯書籤-基礎組件介紹(Form,Input):👉👉juejin.cn/post/696393…

🔊流鶯書籤-基礎組件(Button,Overlay,Dialog,Message):👉👉juejin.cn/post/696394…

🔊流鶯書籤-業務組件介紹:👉👉暫無

🔊個人博客:👉👉www.duwanyu.com

相關文章
相關標籤/搜索