无论是vue还是react,在父子组件通讯的时候,子组件都禁止直接修改父级传过来的prop,父组件总需要在子组件身上监听一个事件,然后由子组件去触发它,好让父组件来接收到payload去改变state。幸运的是,vue为我们准备了两个语法糖,让我们减少了一点写大量模板代码的痛苦。它们就是自定义组件上的v-model
指令以及.sync
修饰符。
假如我们有如下的一个父组件,想为子组件传递一个名为val的prop,并且期待有双向绑定的效果:
<template>
<child-component :val="val" />
</template>
<script>
export default {
data() {
return {
val: 100
}
}
}
</script>
而子组件负责接收val,并且每click一次button,则让val+2:
<template>
<div>
<div>{{val}}</div>
<button @click="handleClick">click</button>
</div>
</template>
一个组件上的 v-model 默认会利用名为 value
的 prop 和名为 input
的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute
用于不同的目的。利用model
选项可以用来避免这样的冲突。换句话说,你可以将v-model
的prop以任意名称来接收,不一定要使用value
, 事件名称也可以是任意的,不一定非要写成input
。如下例:
父组件通过v-model传递val值:
<template>
<child-component v-model="val" />
</template>
而子组件内通过model
选项去绑定这个prop:
export default {
model: {
prop: ‘anyKey‘, // 不一定非要是value
event: ‘anyEventName‘ // 不一定非要是input
},
props: {
anyKey: {
type: Number
}
},
methods: {
handleClick() {
this.$emit(‘anyEventName‘, this.anyKey+2)
}
}
}
父组件通过.sync修饰符传递val值:
<template>
<child-component :val.sync="val" />
</template>
子组件内接收更简单,因为vue内部帮我们绑定了update:myPropName
这样一个事件:
export default {
props: {
val: {
type: Number
}
},
methods: {
handleClick() {
this.$emit(‘update:val‘, this.val+2)
}
}
}
.sync
修饰符写起来更简便一些,双向绑定爽歪歪。不过有一点要注意,像v-bind.sync=”{ title: doc.title }”
这种绑定字面量对象,修饰符是无法正常工作的。
原文:https://www.cnblogs.com/zoujiyun/p/13682290.html