Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API
组合式API
以及setup
三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。其中将要实现的通信方式如下表所示
方式 | Vue2 | Vue3 |
---|---|---|
父传子 | props | props |
子传父 | $emit | emits |
父传子 | $attrs | attrs |
子传父 | $listeners | 无(合并到 attrs方式) |
父传子 | provide/inject | provide/inject |
子组件访问父组件 | $parent | 无 |
父组件访问子组件 | $children | 无 |
父组件访问子组件 | $ref | expose&ref |
兄弟传值 | EventBus | mitt |
props
props是组件通信中最常用的通信方式之一。父组件通过v-bind传入,子组件通过props接收,下面是它的三种实现方式
- 选项式API
//父组件
<template><div><Child :msg="parentMsg" /></div>
</template>
<script> import Child from './Child'
export default {components:{Child},data() {return {parentMsg: '父组件信息'}}
} </script>
//子组件
<template><div>{
{msg}}</div>
</template>
<script> export default {props:['msg']
} </script>
- 组合式Api
//父组件
<template><div><Child :msg="parentMsg" /></div>
</template>
<script> import { ref,defineComponent } from 'vue'
import Child from './Child.vue'
export default defineComponent({components:{Child},setup() {const parentMsg = ref('父组件信息')return {parentMsg};},
}); </script>
//子组件
<template><div>{
{ parentMsg }}</div>
</template>
<script> import { defineComponent,toRef } from "vue";
export default defineComponent({props: ["msg"],// 如果这行不写,下面就接收不到setup(props) {console.log(props.msg) //父组件信息let parentMsg = toRef(props, 'msg')return {parentMsg};},
}); </script>
- setup语法糖
//父组件
<template><div><Child :msg="parentMsg" /></div>
</template>
<script setup> import { ref } from 'vue'
import Child from './Child.vue'
const parentMsg = ref('父组件信息') </script>
//子组件
<template><div>{
{ parentMsg }}</div>
</template>
<script setup> import { toRef, defineProps } from "vue";
const props = defineProps(["msg"]);
console.log(props.msg) //父组件信息
let parentMsg = toRef(props, 'msg') </script>
注意
props中数据流是单项的,即子组件不可改变父组件传来的值
在组合式API中,如果想在子组件中用其它变量接收props的值时需要使用toRef将props中的属性转为响应式。
emit
子组件可以通过emit发布一个事件并传递一些参数,父组件通过v-on进行这个事件的监听
- 选项式API
//父组件
<template><div><Child @sendMsg="getFromChild" /></div>
</template>
<script> import Child from './Child'
export default {components:{Child},methods: {getFromChild(val) {console.log(val) //我是子组件数据}}
} </script>
// 子组件
<template><div><button @click="sendFun">se