原来的实现方式
自定义的MyInput组件
<template>
<div class="myInput">
<!-- 这里只能用 vModel 不可以使用横杠写法 -->
<input type="text" :value="vModel" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
props: {
// 这里也可以写成 'v-model': String 但是建议根据风格来,如果左边都没有引号就直接驼峰
vModel: String
},
methods: {
inputHandle (event) {
// 注意:这里使用 update:v-model 或 update:vModel 都可以
this.$emit("update:v-model", event.target.value)
}
}
}
</script>
使用方式
// 方式一
<my-input :v-model="text" @update:v-model="text = $event"></my-input>
// 方式二
<my-input :v-model.sync="text"></my-input>
可以看到,原来的方式也能实现,但是就使用来说v-model被当成属性,一定要在前面加上:才可以用动态属性,结果就变成了:v-model,然后我们为了简化写法去掉事件绑定,我们最终的效果就是 :v-model.sync这种写法总会让人觉得怪怪的,接下来我们就来解决这个问题
vue-api的方式实现
自定义的MyInput组件
<template>
<div class="myInput">
<input type="text" :value="value" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
props: {
value: String
},
methods: {
inputHandle (event) {
this.$emit("input", event.target.value)
}
}
}
</script>
使用方式
<my-input v-model="text"></my-input>
看到这里可能一部分同学会一脸懵逼,这就同步了?emm,其实还真同步了,那 value 从哪儿来的,input 事件也没绑定啊,的确这些都被我们省略掉了,其实这是 vue 的 api 带给我们的便利,在我们试图向自定义组件传入 v-model 这个特殊的属性的时候,vue 会帮我们做两件事,一件是将 v-model 中的值作为 value 的值向下传递,这是我们在内部要写 props value 的原因,另一件是在当前自定义组件上监听 input 事件,并在触发改事件的时候,将第一个参数赋值给 v-model 中的变量。你可以看到在我们肉眼不可见的地方 vue 为我们做了很多实际,但是大家要明白他为什么给你做这么多,仔细想想不难看出,这些逻辑是业务场景中重复次数很多的逻辑, vue 不给你做,你自己也要做,还会闲麻烦!当然这还没结束呢!下面更精彩!
为属性 value 和事件 input 命名
有些时候我们可能希望 value 就作为一个普通的属性往下传,而我们的业务场景里面 input 作为事件也不够形象,反正就是 value 和 input 不符合你的业务中的语义,这个时候我想改名,咋办?接下来看下面的代码:
<template>
<div class="myInput">
<input type="text" :value="text" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
model: {
prop: "text", // 该属性名
event: "update:v-model" // 改事件名
}
props: {
text: String // 即便改名了,这里也必不可少
},
methods: {
inputHandle (event) {
this.$emit("update:v-model", event.target.value)
}
}
}
</script>
深圳网站优化www.zg886.cn