Skip to content

createInjectionState

Category
Export Size
386 B
Last Changed
3 days ago

Create global state that can be injected into components.

Demo

  • count: 0
  • double: 0

Usage

ts
// useCounterStore.ts
import { 
createInjectionState
} from '@vueuse/core'
import {
computed
,
shallowRef
} from 'vue'
const [
useProvideCounterStore
,
useCounterStore
] =
createInjectionState
((
initialValue
: number) => {
// state const
count
=
shallowRef
(
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
:
shallowRef
(0),
double
:
shallowRef
(0),
increment
: () => {},
} } export function
useCounterStoreOrThrow
() {
const
counterStore
=
useCounterStore
()
if (
counterStore
== null)
throw new
Error
('Please call `useProvideCounterStore` on the appropriate parent component')
return
counterStore
}
js
// useCounterStore.ts
import { createInjectionState } from '@vueuse/core'
import { computed, shallowRef } from 'vue'
const [useProvideCounterStore, useCounterStore] = createInjectionState(
  (initialValue) => {
    // state
    const count = shallowRef(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: shallowRef(0),
      double: shallowRef(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>
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: shallowRef(0), double: shallowRef(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>

Provide a custom InjectionKey

ts
// useCounterStore.ts
import { 
createInjectionState
} from '@vueuse/core'
import {
computed
,
shallowRef
} from 'vue'
// custom injectionKey const
CounterStoreKey
= 'counter-store'
const [
useProvideCounterStore
,
useCounterStore
] =
createInjectionState
((
initialValue
: number) => {
// state const
count
=
shallowRef
(
initialValue
)
// getters const
double
=
computed
(() =>
count
.
value
* 2)
// actions function
increment
() {
count
.
value
++
} return {
count
,
double
,
increment
}
}, {
injectionKey
:
CounterStoreKey
})
js
// useCounterStore.ts
import { createInjectionState } from '@vueuse/core'
import { computed, shallowRef } from 'vue'
// custom injectionKey
const CounterStoreKey = 'counter-store'
const [useProvideCounterStore, useCounterStore] = createInjectionState(
  (initialValue) => {
    // state
    const count = shallowRef(initialValue)
    // getters
    const double = computed(() => count.value * 2)
    // actions
    function increment() {
      count.value++
    }
    return { count, double, increment }
  },
  { injectionKey: CounterStoreKey },
)

Provide a custom default value

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

Type Declarations

ts
export interface 
CreateInjectionStateOptions
<
Return
> {
/** * Custom injectionKey for InjectionState */
injectionKey
?: string |
InjectionKey
<
Return
>
/** * Default value for the InjectionState */
defaultValue
?:
Return
} /** * Create global state that can be injected into components. * * @see https://vueuse.org/createInjectionState * * @__NO_SIDE_EFFECTS__ */ 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

Contributors

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

Changelog

v13.6.0 on
d32f8 - refactor: add @__NO_SIDE_EFFECTS__ annotations to all pure functions (#4907)
v12.0.0-beta.1 on
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
v10.10.0 on
fb468 - feat: add defaultValue option (#3902)
v10.8.0 on
c2cfd - feat: injectionKey use composable name (#3788)
v10.5.0 on
90d34 - feat: add injectionKey option (#3404)
5d948 - feat: allow provide and inject in same component (#3387)

Released under the MIT License.

AI-Driven Development
You. But 10x faster
The structured masterclass to help you leverage AI and build with an edge
Join Early