Vue父子组件通讯的四种方法详解

 更新时间:2024年07月03日 08:39:59   作者:睡着学  
父子组件通讯是指在前端开发的组件化架构中,父组件与子组件之间互相传递数据和触发功能的一种机制,这种机制使得组件能够保持独立性的同时,也能协同工作,本文给大家介绍了Vue父子组件通讯的四种方法,需要的朋友可以参考下

父子组件通讯

父子组件通讯是指在前端开发的组件化架构中,父组件与子组件之间互相传递数据和触发功能的一种机制。这种机制使得组件能够保持独立性的同时,也能协同工作,完成复杂的界面逻辑和数据交互。

通过一个用vue实现的demo为例:

在这个demo中:

  • 需要使用v-model指令将文本框内的内容与变量进行双向绑定,用于获取文本框内的内容。
  • 通过一个数组存储需要展示的内容,并且使用v-for遍历数组内的内容然后渲染。
  • 通过@click='add'为按钮添加一个点击事件将文本框的输入内容添加到数组上。
//组件一
<div class="input-group">
    <input type="text" v-model="item">
    <button @click="add">添加</button>
</div>
//组件二(需要数据)
<div class="child">
    <ul>
        <li v-for="item in list">{{ item }}</li>
    </ul>
</div>

如果我们将组件一放在父组件内,将组件二放在子组件,那我们要怎么将父组件中数据传递给子组件进行渲染呢?(组件二需要数据

这个时候就需要进行父子组件的通讯。

父向子通讯

父组件向子组件传递信息非常方便,通过子组件的属性传递数据就好了。

组件一放在父组件,组件二放在子组件中。父组件将值v-bind绑定传给子组件,子组件使用defineProps接受。

父组件:在<Child :toChild="toChild"></Child>中用v-bind绑定toChild变量传递给子组件。

<template>
<div class="input-group">
    <input type="text" v-model="item">
    <button @click="add">添加</button>
    </div>
//将数据传递给子组件
<Child :toChild="toChild"></Child>
</template>
<script setup>
    import Child from '@/components/child1.vue'
    import { ref } from "vue";
    const item = ref('')
    const toChild = ref('')
    const add = () => {
        toChild.value = item.value
        item.value = ''
    }
</script>

子组件:子组件用defineProps接受父组件传递的数据并且通过设置一个watch监听器,当父组件通过toChild属性传递一个新的值,这个值就会被添加到子组件的列表中。

<template>
<div class="child">
    <ul>
        <li v-for="item in list">{{ item }}</li>
    </ul>
    </div>
</template>
<script setup>
    import { defineProps } from 'vue'
    import { reactive, watch } from "vue";
    const list = reactive(['html', 'css', 'javascript'])
    //接收父组件的数据
    const props = defineProps({
        toChild: ''
    })
    //监听数据的改变动态添加到数组里
    watch(() => props.toChild, (newVal, oldVal) => {
        list.push(newVal)
    })
</script>

子向父通讯

子组件向父组件传递数据较为麻烦一点,常见的方法是通过自定义事件实现数据的传递。

将组件二放在父组件,将组件一放在子组件里。

方法一

借助发布订阅机制,子组件负责发布事件携带参数,父组件订阅该事件通过事件参数获取子组件提供的值。

子组件:通过defineEmits定义并创建一个add事件,再通过触发点击事件的处理函数用emits发布add事件,并且携带数据。

<template>
<div class="input-group">
    <input type="text" v-model="item">
    <button @click="add">添加</button>
    </div>
</template>
<script setup>
    import { ref } from "vue";
    const item = ref('')
    const emits = defineEmits(['add'])//创建一个add事件
    const add = () => {
        //将item变量给到父组件
        emits('add', item.value)//发布add事件
        item.value = ''
    }
</script>

父组件:通过<child @add="handle"></child>给子组件绑定自定义的add事件并且以handle函数作为处理函数。当add事件发布时,就会触发执行handle函数并且通过handle函数的参数接收子组件传递的数据。

<template>
<!-- 订阅add事件,子组件什么时候发布add事件,父组件就会执行handle函数,从而实现数据的共享 -->
<child @add="handle"></child>
<div class="child">
    <ul>
        <li v-for="item in list">{{ item }}</li>
    </ul>
    </div>
</template>
<script setup>
    import child from '@/components/child2.vue'
    import { reactive } from "vue";
    const list = reactive(['html', 'css', 'javascript'])
    const handle = (value) => {
        list.push(value)
    }
</script>

这种方法中子组件只需要发布自定义事件并且携带数据,父组件只需要监听自定义事件并且接受数据。

方法二

父组件借助v-model将数据绑定给子组件,子组件创建update:xxx事件,并接收到该数据将修改后的数据emits(发布)出来让父组件接收修改后的数据。

父组件:在<child v-model:list="list"></child>中,使用v-model:list 将父组件中的 list 数据(渲染数组)传递给子组件并且进行绑定,当子组件发布 update:list 事件后,父组件将接收到修改后的渲染数组并且进行重新渲染。

<template>
<div>
    <child v-model:list="list"></child>
    <div class="child">
        <ul>
            <li v-for="item in list">{{ item }}</li>
    </ul>
    </div>
    </div>
</template>
<script setup>
    import child from '@/components/child3.vue'
    import {reactive } from "vue";
    const list = reactive(['html', 'css', 'javascript'])
</script>

子组件:子组件通过defineProps接收父组件发送的list,并且自定义一个Update:list事件。当点击按钮后触发add函数,将文本框数据放入list中,然后发布Update:list事件并且携带着修改后的list。随着Update:list事件的发布,父组件就可以接收到修改后的list

<template>
<div>
    <div class="input-group">
        <input type="text" v-model="item">
        <button @click="add">添加</button>
    </div>
    </div>
</template>
<script setup>
    import { ref } from "vue";
    const item = ref('')
    const props = defineProps({
        list: {
            type: Array,
            default: () => []
        }
    })
    const emits = defineEmits(['Update:list'])
    const add = () => {
        const arr = props.list
        arr.push(item.value)
        emits('Update:list', arr)
        item.value = ''
    }
</script>

这种方法使父组件的操作变得简洁,但将子组件的操作变得复杂了。父组件只需要和子组件进行双向绑定数据就行了,子组件则需要接收数据再发布自定义的Update:xxx事件将修改后的数据传递给父组件。

方法三

父组件通过ref获取子组件中defineExprose()暴露出来的数据。

子组件:使用 defineExpose 暴露数据,子组件通过defineExpose({ list })将更新后的渲染数组暴露给父组件。

<template>
<div class="input-group">
    <input type="text" v-model="item">
    <button @click="add">添加</button>
    </div>
</template>
<script setup>
    import { ref, reactive } from "vue";
    const item = ref('')
    const list = reactive(['html', 'css', 'javascript'])
    const add = () => {
        list.push(item.value)
        item.value = ''
    }
    defineExpose({ list })
</script>

父组件:获取子组件的数据,使用 ref 定义一个引用变量来引用子组件,并在适当的时机获取子组件暴露的渲染数组。将子组件暴露的渲染数组作为v-for的循环对象进行渲染。

<template>
//获取子组件的引用
<child ref="childRef"></child>
<div class="child">
    <ul>
        //childRef?.list表示只有在在子组件已经挂载完成后才能访问子组件暴露的list数据
        <li v-for="item in childRef?.list">{{ item }}</li>
    </ul>
    </div>
</template>
<script setup>
    import child from '@/components/child4.vue'
    import { ref, reactive, onMounted } from "vue";
    //用ref定义一个引用变量
    const childRef = ref(null);
</script>

这种方法十分简便,子组件只需要暴露数据给父组件,然后父组件引用子组件暴露的数据,但是需要注意生命周期,需要在组件挂载完成后父组件才能成功获取子组件的数据。

以上就是Vue父子组件通讯的四种方法详解的详细内容,更多关于Vue父子组件通讯的资料请关注脚本之家其它相关文章!

相关文章

  • 一文详解如何在Vue网站中实现多语言支持

    一文详解如何在Vue网站中实现多语言支持

    在当今全球化的互联网环境中,为网站提供多语言支持已成为提升用户体验和扩大受众范围的关键策略,本文为大家介绍了如何在Vue网站中实现多语种支持功能,有需要的可以了解下
    2025-03-03
  • Vite创建项目的实现步骤

    Vite创建项目的实现步骤

    随着 Vite2 的发布并日趋稳定,现在越来越多的项目开始尝试使用它。本文我们就介绍了Vite创建项目的实现步骤,感兴趣的可以了解一下
    2021-07-07
  • vue对枚举值转换方式

    vue对枚举值转换方式

    这篇文章主要介绍了vue对枚举值转换方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Vue中如何实现动态路由的示例代码

    Vue中如何实现动态路由的示例代码

    本文主要介绍了Vue中如何实现动态路由的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Vue3在jsx下父子组件实现使用插槽方式

    Vue3在jsx下父子组件实现使用插槽方式

    这篇文章主要介绍了Vue3在jsx下父子组件实现使用插槽方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 详解vue.js下引入百度地图jsApi的两种方法

    详解vue.js下引入百度地图jsApi的两种方法

    这篇文章主要介绍了详解vue.js下引入百度地图jsApi的两种方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • Vue+Ant Design开发简单表格组件的实战指南

    Vue+Ant Design开发简单表格组件的实战指南

    在现代前端开发中,数据表格是展示信息最常用的组件之一,本文主要为大家介绍了一个基于Vue和Ant Design的表格组件开发过程,感兴趣的可以了解下
    2025-06-06
  • Webpack打包图片-js-vue 案例解析

    Webpack打包图片-js-vue 案例解析

    在开发中我们会有各种各样的模块依赖,这些模块可能来自于自己编写的代码,也可能来自第三方库,本文给大家介绍Webpack打包图片-js-vue的相关知识,感兴趣的朋友跟随小编一起看看吧
    2023-11-11
  • 配置一个vue3.0项目的完整步骤

    配置一个vue3.0项目的完整步骤

    这篇文章主要介绍了配置一个vue3.0项目的完整步骤,从0开始配置一个vue项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Vue获取路由信息的8种方法详解

    Vue获取路由信息的8种方法详解

    本文详细介绍了在Vue应用中获取路由信息的8种方法,包括$route对象、useRouteHook、路由守卫等,并提供了不同场景下的推荐方案和实战案例,需要的朋友可以参考下
    2026-01-01

最新评论