前言
vue3在组件通信上与vue2并没有很大的不同,更多是写法的不同。
Vue3组件通信小结
1.props和emit
setup函数可以接受两个参数, prop 和 context ,其中context可以得到emit实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <el-button @click="handle">运行</el-button> <div>父组件传过来的数据:{{name}}</div> </template>
<script> export default { name:"Son", props: { name: { type: String, default: '' } }, setup(props,{ emit }) { console.log(props.name) function handle() { emit('handleClick', 'Vue3真的好用(吗)') } return { handle } } } </script>
|
Vue3中没有this的概念了,所以就不会有this.$emit存在,所以可以从setup传入的context结构出emit实例,从而派发事件给父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <Test name="lalal" @handleClick="myClick">点击</Test> </template>
<script> import Test from './index.vue' export default { name:"father", components: { Test }, setup() { function myClick(name) { console.log(name) } return { myClick } } } </script>
|
2.ref
Vue3可以从Vue中导出 ref 方法,得到子组件的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <template> <Test ref="btnRef"> <el-button @click="click">我是插槽</el-button> </Test> </template> <script> import { ref } from "vue" import Test from './index.vue' export default { components: {Test}, setup() { const btnRef = ref(null) function click() { btnRef.value?.sendParent() } return { btnRef, click } } } </script>
|
在子组件声明ref属性,属性值必须和const btnRef = ref(null)这里声明的变量名一致,否则会报错,拿到子组件实例后就可以直接调用组件的sendParent方法了
这里使用的btnRef.value?.是可选链操作符语法,代表‘?’前面的值为true才继续执行后面的语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <slot></slot> </template> <script> export default { setup() { function sendParent() { console.log("我是给父组件调用的方法") } return { sendParent } } } </script>
|
子组件只提供一个方法,供父组件获取实例后执行,也可以执行更为复杂的数据通信
3.provide/inject
用法与Vue2类似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <template> <Test></Test> </template> <script> import { provide } from "vue" import Test from './index.vue' export default { components: {Test}, setup() { provide('fromFather', 'hello world!') return {} } } </script>
|
直接用provide将需要传递的数据注入,不需要考虑谁去获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <slot></slot> <div>我是父组件注入的数据:{{fatherData}}</div> </template> <script> import { inject } from "vue" export default { setup() { let fatherData = inject('fromFather') return { fatherData } } } </script>
|