概要
此处分享一种vue3中组件传值的方法
vue3中组件的传值和vue2中差不多,父传子和子传父都可以用之前的,详情见
https://blog.youkuaiyun.com/m0_49744220/article/details/132226413
此处介绍一种vue3中的万能的传值方法,兼容父传子,子传父,非父子,Vue3InjectionKey 是 Vue3 中引入的用于依赖注入的特殊函数。它是一个用于创建和访问全局唯一标识符的工具,用于在 Vue 组件树中传递依赖关系。
使用 Vue3InjectionKey 可以帮助我们在需要的组件中获取全局的依赖项,而不需要通过层层传递 props 或事件来实现。
废话不多说了,上代码
1. 传递值
A组件中
使用 provide 来提供依赖项
import { provide, inject,InjectionKey } from 'vue';
const shopText = ref<any>('123')
// 在父组件中提供依赖项
provide('shopText',shopText);
B组件中
使用 inject 来获取依赖项
import { inject } from 'vue';
// 在子组件中获取依赖项
const injectedValue:any = inject('shopText');
console.log(injectedValue); // 输出: 123
2. 传递方法
A组件中
A组件传递(目标组件传递)
import { provide,InjectionKey } from 'vue';
let closeCouponPopup = (v: any) => {
console.log('v',v)
}
let getMyCouponList = () => {
console.log('hello')
}
// 定义一个注入key的类型(建议将注入 key 的类型放在一个单独的文件中,这样它就可以被多个组件导入)
interface ProvideType {
closeCouponPopup: () => void
getMyCouponList: () => void
}
// 为注入值标记类型
const toValue = Symbol() as InjectionKey<ProvideType>
// 将toChildValue和changeValue注入到所有子组件中
provide(
/* 注入名 */ 'toValue',
/* 值 */ {
closeCouponPopup,
getMyCouponList,
}
)
B组件中
B组件或者任意引用A组件的页面内都可获取
import { inject} from 'vue';
// 使用
let clickChange = () => {
closeCouponPopup()
getMyCouponList()
}
// 定义注入值的类型
interface ProvideType {
closeCouponPopup: () => void
getMyCouponList: () => void
}
// 解构获取父组件传的值,需要进行强制类型转换
const { closeCouponPopup,getMyCouponList } = inject(/* 注入名 */ 'toValue') as ProvideType
举个栗子(🌰皮一下*-*): index.vue为父组件,home.vue为子组件
index.vue
<template>
<div>
<Home></Home>
</div>
</template>
<script lang="ts" setup>
import { provide, InjectionKey,ref } from 'vue'
import Home from './home.vue'
let str = ref<any>("hello")
//传递单个值
provide('str', str)
let closeCouponPopup = (v: any) => {
console.log('v', 1111)
}
let getMyCouponList = () => {
console.log('hello')
}
//传递方法 (单个/多个)
// 定义一个注入key的类型(建议将注入 key 的类型放在一个单独的文件中,这样它就可以被多个组件导入)
interface ProvideType {
closeCouponPopup: () => void
getMyCouponList: () => void
}
// 为注入值标记类型
const toValue = Symbol() as InjectionKey<ProvideType>
// 将toChildValue和changeValue注入到所有子组件中
provide(
/* 注入名 */ 'toValue',
/* 值 */ {
closeCouponPopup,
getMyCouponList,
}
)
</script>
<style></style>
home.vue
<template>
<div>
<div @click="clickChange">点击测试</div>
</div>
</template>
<script lang="ts" setup>
import { inject } from 'vue'
// 使用
let clickChange = () => {
closeCouponPopup()
getMyCouponList()
}
//接收方法(单个/多个,需要什么接受什么)
// 定义注入值的类型
interface ProvideType {
closeCouponPopup: () => void
getMyCouponList: () => void
}
// 解构获取父组件传的值,需要进行强制类型转换 ---- 方法
const { closeCouponPopup, getMyCouponList } = inject(/* 注入名 */ 'toValue') as ProvideType
//获取单个值
const str: any = inject('str')
console.log('接受的值‘,str)
</script>
<style lang="scss" scoped></style>
注意:当 提供的数据为 响应式的数据 时,建议尽可能将任何对 响应式状态 的变更都保持在供给方(provide)组件中。这样可以确保所提供状态的声明和变更操作都内聚在同一个组件内,使其 更容易维护。