👉👉项目预览地址,能够直接设置为浏览器主页或者桌面快捷方式进行使用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