Vue 自定义组件的 v-model
Vue 组件的提供 model 选项自定义组件的 v-model 属性。
model 选项的值是一个对象,包含两个参数:
- prop - [String] 一个属性名
- 这个属性需要在 props 中声明
- v-model 会传入这个属性
- event - [String] 一个当前组件的自定义事件名
- model 可以监听这个事件
- 当事件触发($emit)时,将 v-model 的属性值修改为事件传入的值
- 相当于父级使用组件时默认绑定了事件处理函数修改v-model传入的属性:
@myModuleEvent="(val) => { vModelProp = val}"
表单示例
// comp.vue
<template>
<div>
<input
type="checkbox"
:checked="mychecked"
@change="$emit('mychange', $event.target.checked)"
/>
</div>
</template>
<script>
export default {
model: {
prop: 'mychecked', // 需要在props中声明
event: 'mychange' // 自定义事件名
},
props: {
mychecked: Boolean
}
}
</script>
// About.vue
<template>
<div>
<Comp v-model="checked" />
checked: {{ checked }}
</div>
</template>
<script>
import Comp from '@/components/Comp'
export default {
components: { Comp },
data() {
return {
checked: false
}
}
}
</script>
效果:

它类似这样实现:
// Comp.vue
<template>
<div>
<input
type="checkbox"
:checked="mychecked"
@change="$emit('mychange', $event.target.checked)"
/>
</div>
</template>
<script>
export default {
props: {
mychecked: Boolean
}
}
</script>
// About.vue
<template>
<div>
<Comp :mychecked="checked" @mychange="checked = $event" />
checked: {{ checked }}
</div>
</template>
<script>
import Comp from '@/components/Comp'
export default {
components: { Comp },
data() {
return {
checked: false
}
}
}
</script>
$event 是事件处理函数接收的参数。
mychange事件处理函数的传参,也就是$emit传入的参数。
它也可以写成:
<Comp :mychecked="checked" @mychange="
val => {
checked = val
}
" />
.sync 修饰符
自定义 v-model 实现了子组件修改父组件数据,也就是父子组件数据双向绑定。
它实现的方式是:
- 通过 prop 接收父组件的数据,用于展示
- 而不是直接绑定到某个元素的 v-model上,这样会报错
- 通过 $emit 提交事件,传入新的值
- 父组件执行事件处理函数更新数据
- 自定义 v-model 默认会指定父组件的事件处理函数为
val => {property=val}
- 自定义 v-model 默认会指定父组件的事件处理函数为
Vue 的事件名可以定义为这样 updata:prop 以表达对prop赋新值的意图。
例如:v-on:update:mytitle="title"
组件内部将通过$emit('update:mytitle', value)触发事件,修改title的值为value。
虽然 eslint-plugin-vue 不认同 xxx:yyy这样的事件名风格,但update:yyy这种是例外,因为它是为了支持.sync修饰符。
示例:
// About.vue
<template>
<div>
<!-- v-on: 可以简写为@ -->
<Comp :mytitle="title" @update:mytitle="title = $event" />
title: {{ title }}
</div>
</template>
<script>
export default {
data() {
return {
title: 'About'
}
}
}
</script>
// Comp.vue
<template>
<div>
<input
placeholder="请输入内容"
:value="mytitle"
@input="$emit('update:mytitle', $event.target.value)"
/>
</div>
</template>
<script>
export default {
props: ['mytitle']
}
</script>
Vue 的.sync修饰符可以简化这种方式。
它直接通过v-bind:prop.sync 的方式,简化了两件事情:
- 绑定 prop
- 绑定
update:prop事件- 处理函数为
val => {property=val}
- 处理函数为
// About.vue
<Comp :mytitle.sync="title" />
title: {{ title }}
注意:
- 组件内部需要
$emit触发的事件名,格式为update:prop - 使用
.sync修饰符 同 v-model 一样,必须绑定一个 property 名,不能是一个表达式 或 字面量
Vue自定义v-model详解
本文深入解析Vue自定义组件的v-model用法,包括如何通过model选项指定prop和event,实现子组件与父组件之间的数据双向绑定。同时,探讨.sync修饰符的使用,简化父组件对子组件属性及事件的绑定。
1万+

被折叠的 条评论
为什么被折叠?



