1. v-model 的原理
我们在 vue 项目中主要使用 v-model指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定,我们知道 v-model本质上不过是语法糖,v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:
-
<text>和<textarea>元素使用value属性和input事件; -
checkbox和radio使用checked属性和change事件; -
select字段将value作为prop并将change作为事件。
2. 在组件上使用 v-model
使用v-model,可以很方便地在子组件中同步父组件的数据
一个组件上的 v-model 默认会利用名为 value 的 prop和名为 input的事件。也就是说组件只要提供一个名为 value 的 prop,以及名为 input的自定义事件,满足这两个条件,使用者就能在自定义组件上使用v-model
- 简单使用,父子组件相互传值
// 子组件 C.vue
<template>
<div>
<button @click="change">click</button>
{{ value }}---->父组件传过来的值
</div>
</template>
<script>
export default {
props: {
value: String //定义value属性
}
methods:{
change(){
this.$emit('input','change--from son')
}
}
};
</script>
// 父组件 App.vue
<template>
<div id="app">
<C v-model="msg"></C>
<div> {{ msg }} </div>
</template>
- 接受并改变父组件传递过来的
value初始值,实现功能,每点击click +100按钮一次,父组件中的total加100
// 子组件 C.vue
<template>
<div>
<button @click="change">click +100</button>
</template>
<script>
export default {
props:{
value: Number
},
data(){
return {
count:this.value // copy 父组件传来的 value 值
}
},
methods:{
change(){
this.count += 100
this.$emit('input',this.count)
}
}
};
</script>
//App.vue 父组件
<template>
<div id="app">
<C v-model="total"></C>
<div>{{total}}</div>
</div>
</template>
<script>
import C from './components/C'
export default {
components: {C},
data(){
return {
total: 0 , // 可以给 total 设置一个初始值,三个 total 都为同一个
}
},
}
</script>
- 定制
v-model指令的prop和event名称
一个组件上的v-model默认会利用名为value的 prop 和名为input的事件,但是像单选框、复选框等类型的输入控件可能会将value特性用于不同的目的。model选项可以用来避免这样的冲突:
export default {
model: {
prop: 'value',
event: 'input'
},
// ...
}
// 定制 v-model , 改写 2 中的子组件
// C.vue
<template>
<div>
<button @click="change">click +100</button>
</template>
<script>
export default {
model: {
prop: "msg", //这个字段,是指父组件设置 v-model 时,将变量值传给子组件的 msg
event: "changing" //这个字段,是指父组件监听 parent-event 事件
},
props:{
msg: Number // 此处必须定义和 model 的 prop 相同的 props,因为 v-model 会传值给子组件
},
data(){
return {
count:this.msg // value 变成 msg
}
},
methods:{
change(){
this.count += 100
this.$emit('changing',this.count)
}
}
};
</script>










网友评论