例一:登录框的实现
目标:
-
需要实现的效果:
- 默认:显示灰色的字体和边框
- 失去焦点:当表单元素失去焦点时,对内容进行校验,校验通过显示“绿色”的字体和边框
- 失去焦点:当表单元素失去焦点时,对内容进行校验,校验不通过显示“红色”的字体和边框
-
实现功能
-
在封装的组件上可以直接使用v-model进行数据的双向绑定
-
实现
先根据api在登录页声明username和password
-
父传子value,输入框双向绑定输入的value值,失焦触发函数blurFn验证规则
-
设置样式success,err,动态绑定类名,当校验为true时触发绿色success,校验为false时触发红色err
- 设置isOk为true表示校验通过,false表示校验不通过;
- attr设置一个动态属性名,:[atrr]="{success: isOk , err: isOk == false}",动态设置属性名刚开始为空(样式仍为灰色),触发失焦后才开始校验变色,在失焦函数中this.attr="class"
-
v-model会报错,因为props接收的value是只读的,不能够进行修改,所以要将v-model改为v-bind:value="value"
-
但是改完后value的值为空,接收不到,需要监听输入框中的内容或者用imput事件,结合event.targrt实时接收到数据,并子传父传递给父组件
-
登录页接收不用,因为 v-model的作用: 1.把表单元素的value属性和变量双向绑定 2.能够自动监听该事件传递过来的值,赋值给v-model绑定的变量
-
要定义reg正则默认校验
- 在失焦触发函数blurFn中进行if判断, 根据正则表达式提供的test方法来校验输入的值,符合条件返回true 否则返回false,校验通过给输入框和字体添加绿色样式(this.isOk= true),否则校验失败给输入框添加红色的样式(this.isOk = false)
- 根据v-model作用在登录页拿到输入框的校验规则,分别给用户名和密码绑定新的校验规则
具体代码如下:
登录页面中 ...
<!-- 自定义组件 封装输入框 -->
<div class="inputs">
<hmInput v-model="user.username"
placeholder="请输入手机号"
:reg="/^1[3,4,5,6,7,8,9]\d{9}$/"></hmInput>
<hmInput v-model="user.password"
placeholder="请输入密码"
:reg="/^.{3,16}$/"
></hmInput>
</div>
...
export default {
data() {
return {
user: {
username: "",
password: "",
},
};
},
};
自定义组件输入框中
<input type="text"
class="hmInput"
v-bind:value="value"
@blur="blurFn"
:[attr]="{success: isOk , err: isOk == false}"
@input="inputFn"
/>
export default {
props: {
value: {
type: Number,
String,
},
reg:{
type:RegExp, //正则表达式类型
default:()=>{
//默认校验规则不能为空
return /^.{1,}$/
}
}
},
data(){
return{
isOk:true, //isOk为true表示校验通过,false表示校验不通过
attr:'' //设置一个动态属性名
}
},
methods: {
blurFn() {
//动态设置属性名刚开始为空,触发失焦后才开始校验变色
this.attr="class"
// 手机号码的正则校验
// let reg = /^1[3,4,5,6,7,8,9]\d{9}$/;
// 正则表达式提供的test方法来校验
// 符合条件返回true 否则返回false
let bool = this.reg.test(this.value);
if (bool) {
//校验通过 给输入框和字体添加绿色样式
this.isOk= true
} else {
// 校验失败 给输入框添加红色的样式
this.isOk = false
}
},
inputFn(event){
// console.log(event.target.value);
this.$emit('input',event.target.value)
}
},
};
例二:商品列表中的标签
目标:
- 点击+tag按钮变为输入框
- 输入框失焦又变回按钮
- 输入内容聚焦enter键可以实现添加新标签
- 添加后输入框的内容清空,并失焦变为按钮
- 对输入框中的内容校验,不能为空且不能和已有标签重复
- 输入过程中按年esc可以清空内容退出
实现:
-
- v-if/v-else控制input框和按钮的显示隐藏,其中input框默认识隐藏的 按钮默认显示
-
- 给按钮绑定点击事件 ,当点击按钮的时候输入框的inputVisible 显示为true ,输入框展示出来
-
- 当点击输入框的时候触发自自定义指令focus,此时v-model聚焦输入框中的内容,输入框首尾去除空格
-
- 当input框按下enter键的时候触发add添加函数,函数要穿参对象
-
- 在函数中先对输入的内容进行判断,第一内容不能为空标签,第二不能和已存在的标签重复
-
- 再将判断通过的tags添加push到已有的数组里,然后请空输入框中的内容
-
- 最后加一个输入框在输入是esc的功能,和失焦退出输入框
//在插槽中
<input
type="text"
class="tag-input form-control"
style="width: 100px"
v-if="scope.item.inputVisible "
v-focus
v-model.trim="scope.item.inputValue"
@keyup.enter="add(scope.item)"
@blur="scope.item.inputVisible =false"
@keydown.esc="scope.item.inputValue=''"
/>
<button
style="display: block"
class="btn btn-primary btn-sm add-tag"
v-else
@click="scope.item.inputVisible =true"
>
methods:{
add(item){
if(item.inputValue.length === 0){
alert('标签名不能为空哦')
return
}
if(item.tags.includes(item.inputValue)){
alert('标签名已存在')
return
}
item.tags.push(item.inputValue)
item.inputValue = ""
}
}