v-model的用法都知道,表单控件使用v-model绑定一个data中的值即可实现双向绑定:
<input type="text" v-model="val" />
data(){
return {
val: 0
}
}
它其实就是一个语法糖
,这个在vue官网也明确说明了。
以<input type="text"/>
为例,它其实就是:value
(v-bind:value)和@input
(v-on:input)的简写。以下两个<input />
组件的双向绑定功能是一样的:
<input v-model="value" />
<input v-on:input="value = $event.target.value" v-bind:value="value" />
<script>
...
data(){
return {
value: ''
}
}
</script>
只不过下面那个input控件是在input事件中将当前input元素绑定的value赋给了data中value这个变量;
表单有各种不同的类型,如<input>
、<textarea>
、<select>
等类型。v-model指令所绑定的属性及事件也不尽相同。
比如<input>
的text和textarea这样的元素使用的是value
属性和input
事件;
<checkbox>
和<radio/>
这样的复选/单选类的元素使用的是checked
属性和change
事件;
<select />
用的是value
和change事件
;
其实知道了v-model是:value
和@input
事件的简写,基本就可以实现在自定义组件上使用v-model指令了。现在看看如何实现的,以一个简单的自定义input输入框为例:
先看代码:
<template>
<div class="my-input">
<!-- 其他html代码。。。 -->
<input type="text" v-bind:value="value" v-on:input="inputFn" />
</div>
</template>
<script>
export default {
props: ["value"],
data() {
return {
v: "",
};
},
methods: {
inputFn(e) {
this.$emit("input", e.target.value);
},
},
};
</script>
<template>
<div class="home">
<MyInput v-model="tv" />
<!-- <MyInput :value="tv" @input="tv = $event.target.value" /> -->
</div>
</template>
<script>
import MyInput from "../components/MyInput.vue";
export default {
name: "HomeView",
components: { MyInput },
data() {
return {
tv: 0,
};
},
};
</script>
可以看到,子组件的input元素绑定了:value
和@input
,在@input
时将当前<input />
输入框的target.value
通过$emit
将这个输入框的value值传给了父组件的@input
事件,父组件的@input
事件再把传过来的value赋值给当前自定义组件绑定的tv变量。
所以父组件使用v-model
指令绑定的tv变量也可以写成上面注释的那一行的写法:使用@input
和:value
分开绑定事件及变量。
同理,由于v-model的会根据当前表单的类型会自动绑定不同的属性和事件的特性,就可以实现自定义复选、单选、选择器等组件了