Skip to content

createInjectionState

Category
Export Size
132 B
Last Changed
15 minutes ago

创建可注入到组件中的全局状态。

Demo

  • count: 0
  • double: 0

用法

ts
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'

const [useProvideCounterStore, useCounterStore] = createInjectionState((initialValue: number) => {
  // 状态
  const count = ref(initialValue)

  // 计算属性
  const double = computed(() => count.value * 2)

  // 动作
  function increment() {
    count.value++
  }

  return { count, double, increment }
})

export { useProvideCounterStore }
// 如果想隐藏 `useCounterStore` 并将其包装在默认值逻辑或抛出错误逻辑中,请不要导出 `useCounterStore`
export { useCounterStore }

export function useCounterStoreWithDefaultValue() {
  return useCounterStore() ?? {
    count: ref(0),
    double: ref(0),
    increment: () => {},
  }
}

export function useCounterStoreOrThrow() {
  const counterStore = useCounterStore()
  if (counterStore == null)
    throw new Error('请在适当的父组件上调用 `useProvideCounterStore`')
  return counterStore
}
js
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'
const [useProvideCounterStore, useCounterStore] = createInjectionState(
  (initialValue) => {
    // 状态
    const count = ref(initialValue)
    // 计算属性
    const double = computed(() => count.value * 2)
    // 动作
    function increment() {
      count.value++
    }
    return { count, double, increment }
  },
)
export { useProvideCounterStore }
// 如果想隐藏 `useCounterStore` 并将其包装在默认值逻辑或抛出错误逻辑中,请不要导出 `useCounterStore`
export { useCounterStore }
export function useCounterStoreWithDefaultValue() {
  return (
    useCounterStore() ?? {
      count: ref(0),
      double: ref(0),
      increment: () => {},
    }
  )
}
export function useCounterStoreOrThrow() {
  const counterStore = useCounterStore()
  if (counterStore == null)
    throw new Error('请在适当的父组件上调用 `useProvideCounterStore`')
  return counterStore
}
vue
<!-- RootComponent.vue -->
<script setup lang="ts">
import { useProvideCounterStore } from './useCounterStore'

useProvideCounterStore(0)
</script>

<template>
  <div>
    <slot />
  </div>
</template>
vue
<!-- CountComponent.vue -->
<script setup lang="ts">
import { useCounterStore } from './useCounterStore'

// 使用非空断言操作符来忽略未提供存储的情况。
const { count, double } = useCounterStore()!
// 如果要允许组件在未提供存储的情况下工作,可以改用以下代码:
// const { count, double } = useCounterStore() ?? { count: ref(0), double: ref(0) }
// 同样,您可以使用另一个钩子来提供默认值
// const { count, double } = useCounterStoreWithDefaultValue()
// 或者抛出错误
// const { count, double } = useCounterStoreOrThrow()
</script>

<template>
  <ul>
    <li>
      计数: {{ count }}
    </li>
    <li>
      两倍: {{ double }}
    </li>
  </ul>
</template>
vue
<!-- ButtonComponent.vue -->
<script setup lang="ts">
import { useCounterStore } from './useCounterStore'

// 使用非空断言操作符来忽略未提供存储的情况。
const { increment } = useCounterStore()!
</script>

<template>
  <button @click="increment">
    +
  </button>
</template>

提供自定义的 InjectionKey

ts
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'

// 自定义 injectionKey
const CounterStoreKey = 'counter-store'

const [useProvideCounterStore, useCounterStore] = createInjectionState((initialValue: number) => {
  // 状态
  const count = ref(initialValue)

  // 计算属性
  const double = computed(() => count.value * 2)

  // 动作
  function increment() {
    count.value++
  }

  return { count, double, increment }
}, { injectionKey: CounterStoreKey })
js
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'
// 自定义 injectionKey
const CounterStoreKey = 'counter-store'
const [useProvideCounterStore, useCounterStore] = createInjectionState(
  (initialValue) => {
    // 状态
    const count = ref(initialValue)
    // 计算属性
    const double = computed(() => count.value * 2)
    // 动作
    function increment() {
      count.value++
    }
    return { count, double, increment }
  },
  { injectionKey: CounterStoreKey },
)

Provide a custom default value

ts
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'

const [useProvideCounterStore, useCounterStore] = createInjectionState((initialValue: number) => {
  // state
  const count = ref(initialValue)

  // getters
  const double = computed(() => count.value * 2)

  // actions
  function increment() {
    count.value++
  }

  return { count, double, increment }
}, { defaultValue: 0 })
js
import { createInjectionState } from '@vueuse/core'
// useCounterStore.ts
import { computed, ref } from 'vue'
const [useProvideCounterStore, useCounterStore] = createInjectionState(
  (initialValue) => {
    // state
    const count = ref(initialValue)
    // getters
    const double = computed(() => count.value * 2)
    // actions
    function increment() {
      count.value++
    }
    return { count, double, increment }
  },
  { defaultValue: 0 },
)

类型声明

typescript
export interface CreateInjectionStateOptions<Return> {
  /**
   * 自定义注入状态的 injectionKey
   */
  injectionKey?: string | InjectionKey<Return>
  /**
   * Default value for the InjectionState
   */
  defaultValue?: Return
}
/**
 * 创建可以注入到组件中的全局状态。
 *
 * @see https://vueuse.org/createInjectionState
 *
 */
export declare function createInjectionState<
  Arguments extends Array<any>,
  Return,
>(
  composable: (...args: Arguments) => Return,
  options?: CreateInjectionStateOptions<Return>,
): readonly [
  useProvidingState: (...args: Arguments) => Return,
  useInjectedState: () => Return | undefined,
]

Source

SourceDemoDocs

贡献者

丶远方
Anthony Fu
ZHAO Jin-Xiang
Anthony Fu
Matvey Melishev
Hoang Do
zhangxuyang
Peter Petau
Tanimodori

变更日志

v10.10.0 on 5/27/2024
fb468 - feat: add defaultValue option (#3902)
v10.8.0 on 2/20/2024
c2cfd - feat: injectionKey use composable name (#3788)
v10.5.0 on 10/7/2023
90d34 - feat: add injectionKey option (#3404)
5d948 - feat: allow provide and inject in same component (#3387)
v9.11.0 on 1/17/2023
f7ce6 - feat: return state when providing injection state (#2309)

Released under the MIT License.