👉👉項目預覽地址,能夠直接設置爲瀏覽器主頁或者桌面快捷方式進行使用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
......
複製代碼
先來看效果服務器
🌝padding
和width
屬性主要是爲了樣式,其實也能夠在組件引用的時候經過類名去修改,至於哪一種更好用就仁者見仁,智者見智了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>
複製代碼
🌝經過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