父组件可以使用props
把数据传给子组件。
子组件可以使用 $emit
触发父组件的自定义事件
而vue中对$emit
的定义如下:
触发当前实例上的事件。附加参数都会传给监听器回调。
vm.$emit( eventName, […args] )
参数:
{string} eventName
[...args]
components
├── Grandson1.vue // 孙子1
├── Grandson2.vue // 孙子2
├── Parent.vue // 父亲
├── Son1.vue // 儿子1
└── Son2.vue // 儿子2
在父组件中使用儿子组件,并且传递数据给儿子组件
<template>
<div>
父组件钱数:{{money}}
<Son1 :value="money"></Son1>
</div>
</template>
<script>
import Son1 from './Son1'
export default {
name: 'Parent',
//必须是函数,防止被别人引用
data() {
return {
money:1000
}
},
components:{Son1}
}
</script>
子组件接受父组件的属性:
<template>
<div>
儿子1:{{value}}
</div>
</template>
<script>
export default {
name: 'Son1',
//使用props时,获取想要的数据
props:{
value:{type:Number,default:0}
}
}
</script>
如果子组件要改变父组件传递过来的数据,子组件不能直接去改变数据,props默认不是响应式的,哪怕子组件修改了props的数据,但是父组件仍然不会改变
那怎么办呢??
当子组件需要修改父组件的数据时,可以通过$emit
,子组件会触发父组件方法,通过回调的方式将修改的内容传递给父组件
当点击修改按钮时,图片显示的两个一千会同时改变,如下图:
父组件:
<template>
<div>
父组件钱数:{{money}}
//绑定了change方法
<Son1 :value="money" @input="change"></Son1>
</div>
</template>
<script>
import Son1 from './Son1'
export default {
name: 'Parent',
//必须是函数,防止被别人引用
data() {
return {
money:1000
}
},
components:{Son1},
methods:{
change(value){
this.money = value
}
}
}
</script>
子组件:
<template>
<div>
儿子1:{{value}}
<button @click="change">点击修改</button>
</div>
</template>
<script>
export default {
name: 'Son1',
props:{
value:{type:Number,default:0}
},
methods:{
change(){
//发射事件,并传递参数
this.$emit("input",20000)
}
}
}
</script>
咦惹,父组件传递数据的时候写的代码有点长,我们可以简写一点:
<template>
<div>
父组件钱数:{{money}}
//绑定了change方法
//
//第一次修改:
<Son1 :value="money" @update:value="(value)=>this.money=value"></Son1>
</div>
</template>
是不是觉得修改过后的代码更加复杂了,没关系,Vue给我们提供了一个语法糖.
Parent.vue
<template>
<div>
父组件钱数:{{money}}
//第一次修改:
//this.money=value">
//第二次修改:这和第一次修改的用法是一样的
<Son1 :value.sync="money"></Son1>
</div>
</template>
son1.vue:当子组件需要更新 money 的值时,它需要显式地触发一个更新事件:
<script>
//只列出了修改的部分,其余的与上面相同
export default {
methods:{
change(){
this.$emit("update:value",20000)
}
}
}
</script>
.sync
是一个修饰符,是2.3.0+ 新增的,官网的解释:在有些情况下,我们可能需要对一个 prop 进行"双向绑定"。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源。这也是为什么我们推荐以 update:myPropName
的模式触发事件取而代之。
简单来说.sync
的意思是当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定,其实这个用法跟某个指令很相似,v-model?对,就是v-model在组件上使用的时候。
而什么时候使用.sync
和v-model
??
v-model
比较有局限性,绑定的属性名只能叫value
,而.sync
可以任意取名,如果你希望只传value
值的话,可以使用v-model
,反之,使用.sync