前两天尝试了一下自己对element-plus进行二次封装, 发现对ts的写法极度不习惯导致不停冒红线,恰巧昨天看到了一个比较有意思的input封装的文,所以来尝试一下用ts写法进行封装.
有热心大佬有更好的方法或者有趣的奇怪的需求也希望能够指点一二 万分感谢!!!
本次封装想要实现的效果:
1.调用时能够方便的获取input输入的内容,并且如果在一个页面中多次调用这个input组件能够把数据组合在一起成一个对象.
2.能够方便的传入校验方法以及提示信息,完成输入框的校验提示
----------------------------------------------------------分割线--------------------------------------------------------------
开始封装第一步永远是上element-plus复制粘贴.
父组件获取封装组件input的值非常简单:
父组件中v-bind绑定数据,v-on绑定emit方法. 子组件通过defineProps接收属性,defineEmits注册方法,把el-input组件绑定的input值默认设置为传入的属性
给组件绑定input事件,输入东西时用emit通知父组件更改属性就好
我这里想要把多个input数据在父组件中汇总在一个对象中,所以在父组件调用时需要额外传入一个name用来对数据进行区分,在通知父组件更改时自然也要把name传回
父组件中:
数据传递搞定了接下来就到新鲜玩意了:校验
首先确定需要做哪些校验:我这里做了非空校验,网上随便找了个正则用来模拟密码格式校验
所以类型文件就可以这样写
三种类型:密码 飞空 用户名
以及一个确定规则传值的接口ruleProp,其中type使用定义好的三种,错误提示信息就定为字符串了
子组件中接收,表示他是一个由ruleProp类型组成的数组
校验方法:
思路是定义三个方法,最终都返回一个布尔值. 把他们按照上面规定的类型命名且放入一个对象中, 在使用时就可以通过属性名来调用进行检测
引入到子组件后就可以在输入框失焦时进行校验了
其中allpass是最终校验的总结果,传入的集中校验有一个false就返回false. errorMessage是传入的校验失败提示信息. props.rules就是下图传入的校验方式
代码
组件本体 MyEInput.vue
<template>
<el-input
v-model="input"
@input="elInputChange"
style="width: 240px"
:placeholder="placeholder"
@blur="inputBlur"
/>
<div v-if="!allpass">
{{errorMessage}}
</div>
</template>
<script setup lang="ts" >
import { PropType, ref } from 'vue'
import * as EInputTypes from "./EInputTypes"
import {ruleMethods} from './TestMethods'
const props = defineProps({
inputValue:{
type:String
},
name:{
type:String
},
placeholder:{
type:String
},
rules:{
type:Array as PropType<EInputTypes.ruleProp[]>
}
})
const input = ref(props.inputValue)
const emit = defineEmits(['inputUpdate'])
let allpass = ref(false)
let errorMessage = ref('')
const inputBlur = ()=>{
allpass.value = props.rules?.every(item=>{
let ispass = ruleMethods[item.type](input.value as string)
errorMessage.value = item.message
return ispass
}) as boolean
console.log(allpass)
}
const elInputChange = ()=>{
let inputval = input.value
emit('inputUpdate',{name:props.name,value:inputval})
console.log(ruleMethods)
}
</script>
类型文件EInputTypes.ts
export type ruleKeys = "password" | "require" | "username"
export interface ruleProp{
type:ruleKeys,
message:string
}
校验方法文件TestMethods.ts
const isRequired = (val:string):boolean=>{
return val!==''
}
const isUsername = (val:string):boolean=>{
let rep = /^(?=.*[a-zA-Z])(?=.*\d).{1,9}$/
return rep.test(val)
}
const isPassword = (val:string):boolean=>{
let rep = /^(?=.*[a-zA-Z])(?=.*\d).{1,9}$/
return rep.test(val)
}
export const ruleMethods={
"require":isRequired,
"username":isUsername,
"password":isPassword
}
遗留问题和总结
在使用形参中的name对对象属性进行操作时会出现上图的问题, 想了解出现这个问题的原因以及解决方法
本次封装组建的尝试虽然有了定义类型的意识但是ts使用的实在不堪入目, 出现类型问题还是一脸懵, 道阻且长啊.