14、Vue 3 (2024 版)基础笔记 - 通过事件实现子组件传递数据给父组件
通常,只能是父组件传递数据给子组件,若子组件想要传递数据给父组件,就需要通过 事件
。
这里我们使用上篇文章的组件
进行演示。为了于便独立演示,这里还是把完整的代码写出来。
准备工作
1、创建父组件
src/components/comp/MainComp.vue
<template>
<main>
<h3>主体部分</h3>
<!-- 传递对象给子组件 -->
<ArticleComp
v-for="article in articles" :key="article.id"
:article="article"
/>
</main>
</template>
<script setup lang="ts">
import ArticleComp from "@/components/comp/article/ArticleComp.vue";
// 从服务端请求的数据
const articles = [
{id:1, title:"坚持的意义是什么?"},
{id:2, title:"什么是放下?"}
];
</script>
<style scoped>
main {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin-top: 10px;
background: lightblue;
width: 100%;
height: 100%;
border-radius: 10px;
}
</style>
2、创建子组件
src/components/comp/article/ArticleComp.vue
<template>
<article>
<h3>文章组件</h3>
<div>
<p>{{ article.id }}:{{ article.title }}</p>
</div>
</article>
</template>
<script setup lang="ts">
const props = defineProps(['article', 'userinfo'])
</script>
<style scoped>
article {
margin-bottom: 5px;
width: 100%;
text-align: center;
color: white;
background: lightsteelblue;
}
</style>
3、使用组件
src/App.vue
<template>
<MainComp/>
</template>
<script setup lang="ts">
import MainComp from "@/components/comp/MainComp.vue";
</script>
演示说明:MainComp
组件是 ArticleComp
的父组件,这里已经完成了父组件传递数据给子组件。
接下来,就演示子组件通过事件传递数据给父组件。
父组件监听子组件自定义事件
方式一:无参数传递
1、通过 $emit
发送自定义事件
src/components/comp/article/ArticleComp.vue
<template>
<article>
<h3>文章组件</h3>
<div>
<!-- 1、 子组件中,通过 $emit 自定义了一个 articleEvent 事件 -->
<p @click="$emit('articleEvent')">{{ article.id }}:{{ article.title }}</p>
</div>
</article>
</template>
...
2、父组件监听子组件自定义事件
父组件中,可以通过 @
或者 v-on
监听子组件的自定义事件名
来监听事件。
src/components/comp/MainComp.vue
<template>
<main>
<h3>主体部分</h3>
<!-- 父组件使用 @articleEvent 监听子组件的事件 -->
<!-- articleEvent 必须是子组件发送的事件名 -->
<!-- 父组件中定义一个方法来响应子组件 -->
<ArticleComp
v-for="article in articles" :key="article.id"
:article="article"
@article-event="getArticleInfo"
/>
</main>
</template>
<script setup lang="ts">
import ArticleComp from "@/components/comp/article/ArticleComp.vue";
const articles = [
{id:1, title:"坚持的意义是什么?"},
{id:2, title:"什么是放下?"}
];
const getArticleInfo = () => {
alert(1)
}
</script>
...
如此,就完成了子组件通过自定义事件向父组件传递数据。
方式二:无参数传递
src/components/comp/article/ArticleComp.vue
<template>
<article>
<h3>文章组件</h3>
<div>
<!-- 2、使用 emit 触发自定义事件 -->
<p @click="emit('articleEvent')">{{ article.id }}:{{ article.title }}</p>
</div>
</article>
</template>
<script setup lang="ts">
const props = defineProps(['article'])
// 1、使用 defineEmits 函数进行自定义事件
const emit = defineEmits(['articleEvent'])
// 注意:当使用 emit 进行触发自定义事件时,
// 此时,想在哪触发都可以
setInterval(() => {
emit('articleEvent')
}, 3000)
</script>
...
子组件传递数据给父组件
方式一:使用 $emit
1、通过 $emit
发送自定义事件
src/components/comp/article/ArticleComp.vue
<template>
<article>
<h3>文章组件</h3>
<div>
<!-- 把 article 对象数据传递给父组件 -->
<p @click="$emit('articleEvent', article)">{{ article.id }}:{{ article.title }}</p>
</div>
</article>
</template>
<script setup lang="ts">
const props = defineProps(['article'])
</script>
...
2、父组件接收子组件数据
src/components/comp/MainComp.vue
<template>
<main>
<h3>主体部分</h3>
<ArticleComp
v-for="article in articles" :key="article.id"
:article="article"
@article-event="getArticleInfo(article)"
/>
<p>来自子组件的文档:{{ art.title }}</p>
</main>
</template>
<script setup lang="ts">
import {ref} from 'vue'
import ArticleComp from "@/components/comp/article/ArticleComp.vue";
const articles = [
{id:1, title:"坚持的意义是什么?"},
{id:2, title:"什么是放下?"}
];
interface Article {
id: number;
title: string;
}
const art = ref<Article>({});
const getArticleInfo = (article:Article) => {
art.value = article
console.log(article)
}
</script>
...
控制台输出
{id: 2, title: '什么是放下?'}
{id: 1, title: '坚持的意义是什么?'}
方式二:使用 emit
函数
src/components/comp/article/ArticleComp.vue
<template>
<article>
<h3>文章组件</h3>
<div>
<p @click="emit('articleEvent', article)">{{ article.id }}:{{ article.title }}</p>
</div>
</article>
</template>
<script setup lang="ts">
const props = defineProps(['article'])
const emit = defineEmits(['articleEvent'])
</script>
...
组件事件与数据绑定
子组件中,如何实时把数据传递给父组件?在子组件中可以通过 v-model
与 watch
配合实现。
1、定义一个 search 子组件
src/components/comp/SearchComp.vue
<template></template>
<script setup lang="ts"></script>
2、引入组件
src/App.vue
<template>
<SearchComp/>
</template>
<script setup lang="ts">
import SearchComp from "./components/comp/SearchComp.vue";
</script>
3、子组件实时传递数据给父组件
src/components/comp/SearchComp.vue
<template>
<p>子组件中的搜索内容:{{ content }}</p>
<SearchComp @send-search="getSearch"/>
</template>
<script setup lang="ts">
import SearchComp from "./components/comp/SearchComp.vue";
import { ref } from "vue";
const content = ref('')
const getSearch = (data:string) => {
content.value = data
}
</script>
4、父组件实现输出
src/App.vue
<template>
<p>子组件中的搜索内容:{{ content }}</p>
<SearchComp @send-search="getSearch"/>
</template>
<script setup lang="ts">
import SearchComp from "./components/comp/SearchComp.vue";
import { ref } from "vue";
const content = ref('')
const getSearch = (data:string) => {
content.value = data
}
</script>
请登录后再评论