书写形式:我们推荐你始终使用 kebab-case 的事件名,即my-event形式。
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
`
})
现在在这个组件上使用 v-model 的时候:
<base-checkbox v-model="lovingVue">base-checkbox>
这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的 property 将会被更新。
注意你仍然需要在组件的 props 选项里声明 checked 这个 prop。
官网的解释:你可能想在某个组件的根元素上监听一个原生事件。可以使用 v-on 的修饰符.native 。
通俗点讲:就是在父组件中给子组件绑定一个原生的事件,就将子组件变成了普通的HTML标签,不加’. native’事件是无法触发的。
<template>
<div>
<h1>自定义事件.native的Demoh1>
<my-component @click="outClick">不会弹窗my-component>
<my-component @click.native="outClick">会弹窗my-component>
div>
template>
<script>
import myComponent from "./native_demo_child.vue";
export default {
components: {
myComponent
},
methods: {
outClick() {
alert("this is outer");
}
}
};
script>
子组件
<template>
<el-button type="primary">
<slot>slot>
el-button>
template>
<script>
export default {};
script>
在Vue中,子父组件最常用的通信方式就是通过props进行数据传递,props值只能在父组件中更新并传递给子组件,在子组件内部,是不允许改变传递进来的props值,这样做是为了保证数据单向流通。但有时候,我们会遇到一些场景,需要在子组件内部改变props属性值并更新到父组件中,这时就需要用到.sync修饰符。
在下面demo中,通过定义一个Child子组件并设置name属性来显示一句欢迎语,当点击按钮时,通过在父组件中来改变name属性的值;当点击欢迎语时,则通过在Child子组件中改变name属性值。
没有.sync修饰符时:
<template>
<div>
<child :name="name">child>
<el-button type="primary" @click="changePropsInFather">在父组件中将props值改变为'props'el-button>
div>
template>
<script>
import child from "./sync_demo_child.vue";
export default {
data() {
return {
name: "Hello!"
};
},
components: {
child
},
methods: {
changePropsInFather() {
this.name = "点击我,看一下是否会改变";
}
}
};
script>
子组件:
<template>
<h1 @click="changePropsInChild">{{name}}h1>
template>
<script>
export default {
props: {
name: String
},
methods: {
changePropsInChild() {
//虽然也有效果,但是控制台会报错
this.name = "I am from child";
}
};
script>
没有.sync修饰符时,点击欢迎语,虽然子组件中确实将name属性修改了,但是在控制台中报错了,如图所示,大致意思就是在子组件中不要直接修改属性值。
有.sync修饰符时,可以发现通过.sync修饰符可以很好地解决子组件中修改属性并传递给父组件。
<template>
<div>
<child :name.sync="name">child>
<el-button type="primary" @click="changePropsInFather">在父组件中将props值改变为'props'el-button>
div>
template>
<script>
import child from "./sync_demo_child.vue";
export default {
data() {
return {
name: "Hello!"
};
},
components: {
child
},
methods: {
changePropsInFather() {
this.name = "点击我,看一下是否会改变";
}
}
};
script>
子组件:
<template>
<h1 @click="changePropsInChild">{{name}}</h1>
</template>
<script>
export default {
props: {
name: String
},
methods: {
changePropsInChild() {
//正确的做法
this.$emit("update:name", "I am from child");
}
}
};
</script>
Vue官网上对.sync也有解释,简言之,:name.sync就是:name=“name” @update:name="name = $event"的缩写。
即上面代码中的
<child :name.sync="name">child>
等同于
<child :name="name" @update:name="name = $event">child>