v-model语法糖
原理:
v-model是value+input的语法糖,是v-band和v-on的简洁写法。v-model就实现了双向数据绑定,实际上它就是通过Vue提供的事件机制。即在子组件通过$emit()触发一个事件,在父组件使用v-model即可
详细解释
单向数据绑定:
在Vue中,我们可以使用v-bind实现单项的数据绑定,也就是通过父组件向子组件传入数据 ,但是反过来,子组件不可以修改父组件传递过来的数据 ,这也就是所谓的单向数据绑定。
双向数据绑定
v-bind和v-on实现了双向绑定实现了双向数据绑定。
<input type="text" v-bind:value="value" v-on:input="value = $event.target.value" />
或
<input type="text" :value="value" @input="value = $event.target.value" />
v-model是v-bind和v-on的语法糖,即,v-model算是v-band和v-on的简洁写法。
<input type="text" v-model="value" />
一般使用都使用第二种而不使用第一种方式
<input type="text" v-model="name">
本质上是Vue内部的v-model是完成事件绑定 和事件监听 的语法糖
<input type="text" :value="name" @input="name = $event.target.value">
在组件中使用v-model
父组件
<template>
<div class="container">
<!-- v-bind和v-on实现了双向绑定 -->
<!-- <input
type="text"
v-bind:value="value"
v-on:input="value = $event.target.value"
/> -->
<!-- 等同于 -->
<!-- <input type="text" :value="value" @input="value = $event.target.value" /> -->
<!-- v-model是v-bind和v-on的语法糖,即,v-model算是v-band和v-on的简洁写法。 -->
<!-- <input type="text" v-model="value" /> -->
<!-- 在使用中组件 -->
<Child v-model="value"></Child>
<!-- 等同于 -->
<!-- <Child v-bind:value="value" v-on:input="input"></Child> -->
<!-- 等同于 -->
<!-- <Child :value="value" @input="input"></Child> -->
{{ value }}
</div>
</template>
<script>
// 引入组件
import Child from "./components/child";
export default {
// 注册组件
components: {
Child
},
data() {
return {
value: "22"
};
},
methods: {
input(data) {
console.log(data);
this.value = data;
}
}
};
</script>
<style></style>
子组件
<template>
<!-- 2. 监听 input 事件的出发 -->
<input type="text" :value="value" @input="input" />
</template>
<script>
export default {
// 1. 接受父级传递的值
props: {
value: {
type: String,
default: ""
}
},
methods: {
input(event) {
this.$emit("input", event.target.value);
}
}
};
</script>
v-model就实现了双向数据绑定,实际上它就是通过Vue提供的事件机制。即在子组件通过$emit()触发一个事件,在父组件使用v-model即可
这里有两点值得注意。
- 注意:
1.一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件;
比如上面的代码中,如果子组件中props接收的值不为value而使用inputValue,那这里的双向绑定可能会有点问题的。(待验证,从别的博主那看到的,但是我没有试出来,但是还是标注了,万一使用有问题的,可以从这里思考思考)
2.一般的input输入框可以遵循第一点,但通过测试可以发现单选框、复选框这类的输入控件利用value和input并不能实现双向绑定,那么应该怎么办呢?
vue提供了model选项可以用来避免这样的冲突: