开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情
说点题外话
上几篇说了父子组件通信:包括props传参和非props传参:
也说了选项式中子组件向父组件传参,传参的类型等等:
这一篇说说在组合式setup函数和setup语法糖下父子组件中的子组件给父组件传参,
说正文
子组件向父组件传参在setup函数中的写法
在选项式中子组件通过 this.$emit
向父组件传递方法和参数,但是在vue3的组合式中有一个问题:vue3组合式取消绑定了 this
, 那也就意味着我们无论是在在setup函数中还是setup语法糖中都无法使用 this.$emit
这种方式。
那么在组合式中提供了一个新的思路,之前我们知道 setup
接收的第一个参数是 props
setup 接收的第二个参数就是context, context是一个对象,里面包含了emit, 我们就是利用这个参数进行子组件向父组件传参
1.1 基本使用
- 父组件Father
<template>
<div>
<son :counter="counter" @addCouter="addCouter"></son>
</div>
</template>
<script>
import { ref } from 'vue';
import Son from './Son.vue';
export default {
components: { Son },
setup() {
const counter = ref(10)
const addCouter = () => {
counter.value++
}
return {
counter,
addCouter
}
}
}
</script>
- 子组件
<template>
<h2>{{ counter }}</h2>
<button @click="addCouter">+1</button>
</template>
<script>
export default {
props: ["counter"],
emits: ['addCouter'],
setup(props, context) {
const addCouter = () => {
context.emit('addCouter')
}
return {
addCouter
}
}
}
</script>
这里要注意的一点就是在vue3的组合式中需要我们额外将需要传递的方法定义在emits数组中。上面也说过context是一个对象,我们也可以采用解构的写法来写emit传参
<script>
export default {
props: ["counter"],
emits: ['addCouter'],
setup(props, { emit }) {
const addCouter = () => {
emit('addCouter')
}
return {
addCouter
}
}
}
</script>
这里也有一个需要注意的点,因为我们对context采用了解构的写法,所以在方法中传递方法和参数的时候,直接emit()即可。
1.2 传递参数
这里我就省去上文重复代码了,只留下addCounter这个方法用来传递参数
- Father.vue
const addCouter = params => {
counter.value++
console.log(params);
}
- Son.vue
const addCouter = () => {
emit('addCouter', 10)
emit('addCouter', "string")
emit('addCouter', ["小白"])
emit('addCouter', {name: "小白"})
}
这里和选项式中的结果是相同的, 后面的传参并不会覆盖前面传递的参数,但是并不建议这样做
二、子组件向父组件传参:setup语法糖
- 父组件Father.vue
<template>
<div>
<son :counter="counter" @addCounter="addCounter"></son>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Son from './Son.vue';
const counter = ref(10)
const addCounter = () => {
counter.value++
}
</script>
在父组件中引用调用子组件的方法和变量和之前是没有变化的,但是子组件会有引入新的官方提供的新方法
- 子组件Son.vue
<template>
<h2>{{ counter }}</h2>
<button @click="addCouterClick">+1</button>
</template>
<script setup>
// const props = defineProps(["counter"])
const props = defineProps({
counter: Number
})
const emits = defineEmits(["addCounter"])
const addCouterClick = () => {
emits("addCounter")
}
</script>
-
这里新增了一个新的方法
defineEmits
,和defineProps
差不多一个意思,用来“收纳”我们需要传递的方法。之后再调用的方法中使用我们自定义的“收纳”方法传递即可,也就是上文的emits()
。(之前是需要进行引用的,但是现在官方已经取消了引用直接使用即可) -
补充一点上一篇漏掉的知识点:
defineProps
有两种方式定义,参数可以是数组也可以是对象,上面代码中注释掉的就就是。
说再见
关于父子组件通信的:父组件向子组件传参和子组件向父组件传参就说到这里,下一篇我将开始说非父子组件通信。
难忘今宵
从前有一只北极熊买了一副墨镜,他戴了墨镜之后沉思一会儿,说到:突然好想吃竹子哦。