Vue中父组件向子组件通信普遍采用props传值通信的方式:
-子组件(准备接收父组件的数据)
<script>
// 步骤1. 子组件 - props - 变量 (准备接收数据)
export default {
props: ['title', 'price', 'intro']
}
</script>
- 父组件 (App.vue中使用并传入数据)
<template>
<div>
<!-- 步骤: 2. 父组件 - 引入注册 - 在标签中传值进去-->
<Product title="道口烧鸡" price="29" :intro="str"></Product>
</div>
</template>
但是props值在vue中遵循单向数据流原则,除非是引用值,否则子组件是不能直接对props变量作修改的。所以我们一般用自定义事件来修改父组件的props值,以此达到子->父组件通信的目的。
子向父通信
1.自定义事件方式:
父组件 (自定义子组件事件 回调函数在自己身上)
<my-component @changeShow="toggleShow" />
子组件 (触发自定义事件并传递参数)
this.$emit('changeShow', false)
这种方法可以让子组件调用父组件的函数,并传递子组件的参数到父组件中。但略显繁琐,所以vue为开发者提供了 .sync修饰符,便于我们更快捷地修改子组件的props值,完成子向父组件通信:
2. .sync修饰符
// .sync修饰符其实本质上是一个对 this.$emit('自定义事件',参数) 的语法糖
父组件:
<my-component :show.sync="isShow" />
子组件:
props:{
show:Boolean
}
methods:{
showDialog(){
// update:props名称 即可完成对父组件中isShow数据的修改
this.$emit('update:show', false)
}
}
其他父子组件通信方式还有很多,只是限于格式与用途不太常见:
通过ref来给标签打标识,然后在父组件中直接使用this.$refs.xxx 来获取子组件中的标签,然后在子组件中为标签绑定相应事件,通过在父组件中执行标签事件(如:this.$refs.inputDom.focus()),并传递相应参数,便可以实现父向子传值。同理,用返回值接受函数执行的结果,也是可以实现子向父传值的。
$parent 属性:在子组件中可以直接访问该组件的父实例或组件。 (特别注意:第三方组件库中的$parent可能仍然是一个第三方组件!可以通过 $parent的$el属性在控制台中看到 )
$root 属性:获取根组件对象,一般都是App.vue。
$children 属性:获取所有子组件的数组,注意:子组件消失与出现可能会改变其他子组件的下标!
通过这3个属性,可以很方便的进行父子间通信,同时也可以实现子组件对父组件数据的修改,但是这样做可能会引起后续维护上的困难,一般不推荐使用。
provide/inject : 依赖注入,对于祖先组件对子组件传值,可以使用 provide 和 inject,正常inject是无法修改的,但是我们可以把传递的数据改为引用值,或把祖先组件的vc对象(即this指向的对象)直接传给子组件。
这个方法对于多个子组件控制祖先组件弹出层的开启/关闭、传递标题信息十分方便。
v-model实现父子通信:
//---父组件
<template>
<div>
<!-- 在父组件中用v-model相当于,v-bind绑定了value,以及执行了v-on:input事件 -->
<child v-model="flag"></child>
<div>{
{flag}}</div>
</div>
</template>
//---子组件
<script>
export default {
// 用props接收父组件传递的value值,从而实现双向数据绑定
props: ["value"],
methods: {
// 通过$emit触发父组件的input事件,并将第二个参数作为值传递给父组件
confirm () {
this.$emit('input', false)
}
}
}
</script>