createInjectionState
Create global state that can be injected into components.
Demo
- count: 0
- double: 0
Usage
ts
// useCounterStore.ts
import { computed, ref } from 'vue-demi'
import { createInjectionState } from '@vueuse/shared'
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 }
})
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 }
export function useCounterStoreWithDefaultValue() {
return useCounterStore() ?? {
count: ref(0),
double: ref(0),
increment: () => {},
}
}
export function useCounterStoreOrThrow() {
const counterStore = useCounterStore()
if (counterStore == null)
throw new Error('Please call `useProvideCounterStore` on the appropriate parent component')
return counterStore
}
// useCounterStore.ts
import { computed, ref } from 'vue-demi'
import { createInjectionState } from '@vueuse/shared'
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 }
})
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 }
export function useCounterStoreWithDefaultValue() {
return useCounterStore() ?? {
count: ref(0),
double: ref(0),
increment: () => {},
}
}
export function useCounterStoreOrThrow() {
const counterStore = useCounterStore()
if (counterStore == null)
throw new Error('Please call `useProvideCounterStore` on the appropriate parent component')
return counterStore
}
vue
<!-- RootComponent.vue -->
<script setup lang="ts">
import { useProvideCounterStore } from './useCounterStore'
useProvideCounterStore(0)
</script>
<template>
<div>
<slot />
</div>
</template>
<!-- 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'
// use non-null assertion operator to ignore the case that store is not provided.
const { count, double } = useCounterStore()!
// if you want to allow component to working without providing store, you can use follow code instead:
// const { count, double } = useCounterStore() ?? { count: ref(0), double: ref(0) }
// also, you can use another hook to provide default value
// const { count, double } = useCounterStoreWithDefaultValue()
// or throw error
// const { count, double } = useCounterStoreOrThrow()
</script>
<template>
<ul>
<li>
count: {{ count }}
</li>
<li>
double: {{ double }}
</li>
</ul>
</template>
<!-- CountComponent.vue -->
<script setup lang="ts">
import { useCounterStore } from './useCounterStore'
// use non-null assertion operator to ignore the case that store is not provided.
const { count, double } = useCounterStore()!
// if you want to allow component to working without providing store, you can use follow code instead:
// const { count, double } = useCounterStore() ?? { count: ref(0), double: ref(0) }
// also, you can use another hook to provide default value
// const { count, double } = useCounterStoreWithDefaultValue()
// or throw error
// const { count, double } = useCounterStoreOrThrow()
</script>
<template>
<ul>
<li>
count: {{ count }}
</li>
<li>
double: {{ double }}
</li>
</ul>
</template>
vue
<!-- ButtonComponent.vue -->
<script setup lang="ts">
import { useCounterStore } from './useCounterStore'
// use non-null assertion operator to ignore the case that store is not provided.
const { increment } = useCounterStore()!
</script>
<template>
<button @click="increment">
+
</button>
</template>
<!-- ButtonComponent.vue -->
<script setup lang="ts">
import { useCounterStore } from './useCounterStore'
// use non-null assertion operator to ignore the case that store is not provided.
const { increment } = useCounterStore()!
</script>
<template>
<button @click="increment">
+
</button>
</template>
Type Declarations
typescript
/**
* 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
]
/**
* 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
]
Source
Contributors
Anthony Fu
Tanimodori
ZHAO Jinxiang