Vue3组件通信小结

Posted by LeaonY on 2021-10-29

前言

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) //"lalal"
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() {
//已经把数据注入到fromFather里面去了
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>