VueUse createInjectionState 是对Vue3 Provide/Inject的封装实现组件传值,它可把数据穿透组件传给子组件使用,解决了Provide/Inject 无法追踪数据源的问题。
例子
createGlobalState 也可以组件间共享数据,但是它的生命周期是整个APP,当你关闭网页它才会销毁。
createInjectionState 的生命周期是当使用它的相关组件被销毁,它就会被销毁。
useCounterStore.ts 会被根组件和B组件引用,根组件引用了A组件(子组件),A组件引用了B组件(孙组件),根组件直接跳过子组件把值传给孙组件。
// useCounterStore.ts
import { computed, reactive, ref } from 'vue'
import { createInjectionState } from '@vueuse/shared'
//定义SKU类型
interface Sku{
count:number,
id:number,
name:string
}
const [useProvideCounterStore, useCounterStore] = createInjectionState((initialValue: Sku) => {
// state 状态
const sku = reactive(initialValue)
// getters 属性
const double = computed(() => sku.count * 2)
// actions 方法
function increment() {
sku.count++
}
return { sku, double, increment }
})
export { useProvideCounterStore }
// If you want to hide `useCounterStore` and wrap it in default value logic or throw error logic, please don't export `useCounterStore`
export { useCounterStore }
createInjectionState.vue 根组件,引用了A组件。
<template>
<div>
<div>
我是根组件, 我传入了sku对象并不停的修改ID的值
<br>{{ sku }}
<CompA/>
</div>
</div>
</template>
<script setup lang="ts">
/*
vueuse 中文文档
https://www.itxst.com/vueuse/tutorial.html
*/
import { computed, onMounted, reactive } from 'vue';
import { createGlobalState, useStorage } from '@vueuse/core'
import CompA from './createInjectionState_A.vue'
import { useProvideCounterStore } from './useCounterStore'
const sku=reactive({id:1,count:99,name:'香蕉'});
//在根组件传入对象
useProvideCounterStore(sku);
onMounted(() => {
setInterval(()=>{
sku.id++;
},1000)
});
</script>
createInjectionState_A.vue A组件(子组件),A组件啥也没干。
<template>
<div>
<div>
我是A组件, 我使用了B组件
<br>
<CompB/>
</div>
</div>
</template>
<script setup lang="ts">
/*
vueuse 中文文档
https://www.itxst.com/vueuse/tutorial.html
*/
import { computed, onMounted, reactive } from 'vue';
import { createGlobalState, useStorage } from '@vueuse/core'
import CompB from './createInjectionState_B.vue'
</script>
createInjectionState_B.vue B组件(孙组件)接收了根组件传入的数据。
<template>
<div>
<div>
我是B组件{{sku}},我获取到了根组件传入的值<br> <button @click="increment">点修改Count值</button>
</div>
</div>
</template>
<script setup lang="ts">
/*
vueuse 中文文档
https://www.itxst.com/vueuse/tutorial.html
*/
import { computed, onMounted, reactive } from 'vue';
import { createGlobalState, useStorage } from '@vueuse/core'
import { useCounterStore } from './useCounterStore'
// 获取根组件传入的数据
const { sku, double,increment } = useCounterStore();
onMounted(() => {
});
</script>
/**
* Create global state that can be injected into components.
*
* @see https://vueuse.org/createInjectionState
*
*/
export declare function createInjectionState<
Arguments extends Array<any>,
Return
>(
composable: (...args: Arguments) => Return
): readonly [
useProvidingState: (...args: Arguments) => Return,
useInjectedState: () => Return | undefined
]