背景
随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。
简介
本文介绍 Vue3 中如何通过自定义事件实现子组件向父组件传数据。
Vue3 中组件间通信包括:
- 父组件向子组件传数据,实现方案有:
props
v-model
$refs
- 默认插槽 / 具名插槽
- 子组件向父组件传数据
props
v-model
$parent
- 自定义事件
- 作用域插槽
- 父组件与子组件的子组件互传数据,即与孙子组件互传数据
$attrs
provider
&inject
- 任意组件间传数据
mitt
Pinia
开发环境
分类 | 名称 | 版本 |
---|---|---|
操作系统 | Windows | Windows 11 |
IDE | Visual Studio Code | 1.91.1 |
开发步骤及源码
1> 在 【Vue3】组件通信之props 基础上修改 Vue 根组件 src/App.vue
,在子组件标签上添加一个自定义事件 sync-read-times
。
<template>
<div class="parent">
<h1>父组件</h1>
<h2>Blog数量:{{ blogs.length }}</h2>
<h2>浏览数量:{{ readTimes }}</h2>
<!-- 给子组件绑定了一个 sync-read-times 事件,只要 sync-read-times 被触发,其指向的 syncReadTimes 函数就会被调用 -->
<Blog :blogs="blogs" :author="author" @sync-read-times="syncReadTimes" />
</div>
</template>
<script setup lang="ts">
import Blog from './components/Blog.vue'
import { reactive, ref } from 'vue'
const author = ref('Nick')
const blogs = reactive([
{ id: '001', title: '美国大选', content: '美国大选将于...' },
{ id: '002', title: '奥运奖牌', content: '截止今日奥运奖牌榜...' },
{ id: '003', title: '俄乌战争', content: '乌克兰单方面提出希望和谈...' },
{ id: '004', title: '巴以冲突', content: '巴以冲突最新战况...' },
])
const readTimes = ref(0)
function syncReadTimes(value) {
readTimes.value += value
}
</script>
<style scoped lang="scss">
.parent {
background-color: orange;
padding: 20px;
}
</style>
2> 修改子组件,使用 defineEmits
函数声明接收的父组件自定义事件 sync-read-times
,然后修改 <button>
点击事件为触发自定义事件 sync-read-times
。
<template>
<div class="content">
<h1>子组件</h1>
<div class="blog" v-for="blog in blogs" :key="blog.id">
<div class="blog-title">标题:{{ blog.title }}</div>
<div class="blog-author">作者:{{ author }}</div>
<div class="blog-content">{{ blog.content }}</div>
<button @click="emits('sync-read-times', 1)">浏览量+1</button>
</div>
</div>
</template>
<script setup lang="ts">
const data = defineProps(['author', 'blogs'])
// 声明事件
const emits= defineEmits(['sync-read-times'])
</script>
<style scoped lang="scss">
.content {
background-color: aquamarine;
padding: 20px;
.blog {
border: 1px solid gray;
border-radius: 5px;
padding: 0 10px;
margin-top: 5px;
div {
padding: 10px 5px;
}
.blog-title {
font-weight: bold;
}
.blog-author {
font-size: small;
font-style: italic;
}
.blog-content {
font-size: small;
}
button {
margin: 10px 0;
}
}
}
</style>
3> 执行命令 npm run dev
启动应用,浏览器访问:http://localhost:5173/
。点击子组件中按钮,父组件中的 浏览数量
随按钮点击次数增加。
总结
使用自定义事件实现子组件向父组件传数据:
- 父组件需要在子组件标签上自定义事件,格式:
@事件名="函数名"
,如本例中的@sync-read-times="syncReadTimes"
,当子组件触发自定义事件sync-read-times
时,父组件的函数syncReadTimes
就会被调用; - 子组件使用
defineEmits
声明接收的父组件自定义事件,defineEmits
函数参数为自定义事件名称数组; - 子组件根据实际需求触发自定义事件,触发自定义事件函数(本例中的
emits('sync-read-times', 1)
)的第一个参数为自定义事件名,后面跟随自定义事件对应的父组件中函数的参数(参数数量不定),即向父组件传的数据。