首页IT科技vue组件之间调用(vue3 组件间互相通信(包括父子、爷孙、兄弟、全局))

vue组件之间调用(vue3 组件间互相通信(包括父子、爷孙、兄弟、全局))

时间2025-05-05 01:36:15分类IT科技浏览4596
导读:目录...

目录

父子互相通信

proprs / emits

使用 props(父传子), 使用emit(子传父)

v-model / emits(父子互相通信))

仅父传子通信

ref方式

仅父传更深的后代(仅爷传孙通信)

provide / inject(组件内api)

provide / inject响应性数据的传递与接收

兄弟组件通信

全局组件通信

EventBus(通常被称之为 “全局事件总线           ”)

Vuex(后续文章详解)

父子互相通信

proprs / emits

Father.vue 通过 prop 向 Child.vue 传值(可包含父级定义好的函数) Child.vue 通过 emit 向 Father.vue 触发父组件的事件执行

使用 props(父传子), 使用emit(子传父)

父组件:

<template> // 通过v-bind将数据想子组件传递 // 动态绑定 props 是用 :           ,绑定 emit 是用 @ <VChild :value="valueData" @update-age="updateAge" /> </template> const valueData = type

子组件:

export default defineComponent({ props: { value: String, }, // 在 2.x                   ,只需要通过 this.uid           、this.userName 就可以使用父组件传下来的 prop            。 // 但是 3.x 没有了 this      , 需要给 setup 添加一个入参才可以去操作                  。 setup (props, ctx) { // 该入参包含了我们定义的所有props console.log(props); // 调用 emits ctx.emit(update-age, value) } })

TIP:

prop 是只读     ,不允许修改 setup 的第一个入参                  ,包含了我们定义的所有props(如果在 Child.vue 里未定义            ,但 父组件 Father.vue 那边非要传过来的     ,不会拿到                 ,且控制台会有警告信息) 该入参可以随意命名            ,比如你可以写成一个下划线 _,通过 _.uid 也可以拿到数据                 ,但是语义化命名                  ,是一个良好的编程习惯      。

v-model / emits(父子互相通信))

通过Vue3的文档可以发现,这个指令的用法发生了一定的变化     。在之前           ,我们要想实现一个自定义的非表单组件的双向绑定                  ,需要通过xxxx.sync的这种语法来实现      ,如今这个指令已经被废除了           ,而是统一使用v-model这个指令                  。

父组件:支持多个数据的双向绑定

<template> <VChild v-model:value="valueData" v-model:keyword="keywordData" /> </template>

子组件:

<template> <button @click="clickHandle">click</button> </template> export default defineComponent({ name: child, props: { value: String, keyword: String }, setup(props, ctx) { // 用户点击按钮 const clickHandle = (e: any) => { // 修改对应的props的数据                  ,直接通过 “update:属性名                  ” 的格式      ,直接定义一个更新事件 ctx.emit(update:value, value) ctx.emit(update:keyword, value + 123) } } })

TIP:

虽然 v-model 的配置和 prop 相似     ,但是为什么出这么两个相似的东西?自然是为了简化一些开发上的操作            。

使用 props / emits                  ,如果要更新父组件的数据            ,还需要在父组件定义好方法     ,然后 return 给 template 去绑定事件给子组件                 ,才能够更新     。

而使用 v-model / emits             ,无需如此,可以在 Child.vue 直接通过 “update:属性名      ” 的格式                 ,直接定义一个更新事件                 。

仅父传子通信

父组件向子组件传递一个数据                  ,可以用这两种方式:

v-bind (上面父子通信中得prop) refs获取子组件内部某个函数,直接调用传参(这里简称refs方式)

ref方式

父组件:

<template> <div>sonRef</div> <button @click="sendValue">send</button> // 这里ref接受的字符串           ,要setup返回的ref类型的变量同名 <Son ref="sonRef" /> </template> <script lang="ts"> import { defineComponent, ref } from vue import Son from @/components/Son.vue export default defineComponent({ name: Demo, components: { Son }, setup() { // 如果ref初始值是一个空                  ,可以用于接受一个实例 // vue3中获取实例的方式和vue2略有不同 const sonRef: any = ref(null) // 请保证视图渲染完毕后再执行操作 onMounted( () => { // 可以拿到son组件实例      ,并调用其setup返回的所有信息 console.log(sonRef.value) // 通过调用子组件实例的方法           ,向其传递数据 sonRef.value.acceptValue(123456) // 也可以去操作子组件的数据 sonRef.value.valueRef = 8888; }); // 必须return出去才可以给到template使用 return { sonRef, } } }) </script>

子组件:

<template> // 渲染从父级接受到的值 <div>Son: {{ valueRef }}</div> </template> <script lang="ts"> import { defineComponent, ref } from vue export default defineComponent({ name: Son, setup() { const valueRef = ref() // 该函数可以接受父级传递一个参数                  ,并修改valueRef的值 const acceptValue = (value: string) => (valueRef.value = value) return { acceptValue, valueRef } } }) </script>

TIP:

这种方式跟Vue2中使用this.$refs      ,this.$children的方式很相似     ,都是通过拿到子组件实例                  ,直接调用子组件身上的函数            。方法千篇一律            ,不过在Vue3中没有了this这个黑盒。

仅父传更深的后代(仅爷传孙通信)

provide / inject(组件内api)

这个特性有两个部分:Grandfather.vue 有一个 provide 选项来提供数据     ,Grandson.vue 有一个 inject 选项来开始使用这些数据                 。

Grandfather.vue 通过 provide 向 Grandson.vue 传值(可包含定义好的函数) Grandson.vue 通过 inject 向 Grandfather.vue 触发爷爷组件的事件执行

无论组件层次结构有多深                 ,发起 provide 的组件都可以作为其所有下级组件的依赖提供者                  。

爷组件:

<template> <Grandfather> <father></father> </Grandfather> </template> <script lang="ts"> // 记得导入provide import { defineComponent, provide } from vue export default defineComponent({ name: Grandfather, setup(props) { // 定义好数据 const msgData: string = Hello World!; // 向后代provide出去数据 provide(msg, msgData) return {} } }) </script>

TIP:

在 3.x            ,provide需要导入并在setup里启用,并且现在是一个全新的方法。

每次要provide一个数据的时候                 ,就要单独调用一次           。

孙组件:

<script lang="ts"> // 记得导入inject import { defineComponent, reactive, inject } from vue export default defineComponent({ name: Grandson, setup () { const msg: string = inject(msg) || ; } }) </script>

provide / inject响应性数据的传递与接收

provide 和 inject 本身不可响应                  ,但是并非完全不能够拿到响应的结果,只需要我们传入的数据具备响应性           ,它依然能够提供响应支持                  。

我们以 ref 和 reactive 为例                  ,来看看应该怎么发起 provide 和接收 inject      。

对这 2 个 API 还不熟悉的同学      ,建议先阅读一下 响应式性基础            。

爷组件:

export default defineComponent({ // ... setup () { // provide一个ref const msg = ref<string>(Hello World!); provide(msg, msg); // provide一个reactive const userInfo: Member = reactive({ id: 1, name: Petter }); provide(userInfo, userInfo); // 2s 后更新数据 setTimeout(() => { // 修改消息内容 msg.value = Hi World!; // 修改用户名 userInfo.name = Tom; }, 2000); } })

孙组件:

export default defineComponent({ setup () { // 获取数据 const msg = inject(msg); const userInfo = inject(userInfo); // 打印刚刚拿到的数据 console.log(msg); console.log(userInfo); // 因为 2s 后数据会变           ,我们 3s 后再看下                  ,可以争取拿到新的数据 setTimeout(() => { console.log(msg); console.log(userInfo); }, 3000); // 响应式数据还可以直接给 template 使用      ,会实时更新 return { msg, userInfo } } })

provide / inject引用类型的传递与接收

TIP:

组件内的provide / inject 区分于应用配置内的应用API——provide                  。(以后文章详细讲解)

兄弟组件通信

兄弟组件是指两个组件都挂载在同一个 Father.vue 下     ,但两个组件之间并没有什么直接的关联      。如果想要交流:

先把数据传给共同的Father.vue                  ,再通过父子组件通信去交流;(难用            ,不推荐) 使用下面的全局组件通信     。(√)

全局组件通信

全局组件通信是指     ,两个任意的组件                 ,不管是否有关联(父子                  、爷孙      、兄弟)的组件            ,都可以直接进行交流的通信方案                  。

EventBus(通常被称之为 “全局事件总线     ”)

Vue 3.x 移除了 $on      、 $off 和 $once 这几个事件 API,使得vue3.x不能像2.x一样                 ,不能直接使用EventBus            。

Vuex(后续文章详解)

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库     。它采用集中式存储管理应用的所有组件的状态                  ,并以相应的规则保证状态以一种可预测的方式发生变化                 。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
差评事件是怎么回事(差评率高)