VueUse createInjectionState 组件传值

VueUse createInjectionState 是对Vue3 Provide/Inject的封装实现组件传值,它可把数据穿透组件传给子组件使用,解决了Provide/Inject 无法追踪数据源的问题。

在线例子

例子

与createGlobalState区别

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
]