Lzh on GitHub

将状态保持在全局范围内,以便在不同的 Vue 实例中 重复使用

Demo

<script setup lang="ts">
import { createGlobalState, reactify, useStorage } from '@vueuse/core'
import YAML from 'yaml'

const stringify = reactify(
  (input: any) => YAML.stringify(input, (k, v) => {
    if (typeof v === 'function') {
      return undefined
    }
    return v
  }, {
    singleQuote: true,
    flowCollectionPadding: false,
  }),
)

const useState = createGlobalState(() =>
  useStorage('vue-use-locale-storage', {
    name: 'Banana',
    color: 'Yellow',
    size: 'Medium',
  }))

const state = useState()
const text = stringify(state)
</script>

<template>
  <div>
    <input v-model="state.name" type="text">
    <input v-model="state.color" type="text">
    <input v-model="state.size" type="text">

    <pre lang="yaml">{{ text }}</pre>
  </div>
</template>

这段代码是一个基于 Vue 3 <script setup>VueUse 的示例,用于构建一个可以响应式编辑并实时预览 YAML 格式数据的组件。

  • 将一个对象转换为 YAML 字符串,并且使用 reactify 包装后,传入响应式对象会得到一个自动更新的 computed 字符串。
  • 页面刷新后还能保存,因为 useStorage 使用的是 localStorage,数据会持久化保存。下次加载页面时仍保留修改后的状态。

使用

无持久化(存储于内存)

store.js
import { createGlobalState } from '@vueuse/core'
// store.js
import { shallowRef } from 'vue'

export const useGlobalState = createGlobalState(
  () => {
    const count = shallowRef(0)
    return { count }
  }
)

更大的示例:

store.js
import { createGlobalState } from '@vueuse/core'
// store.js
import { computed, shallowRef } from 'vue'

export const useGlobalState = createGlobalState(
  () => {
    // state
    const count = shallowRef(0)

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

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

    return { count, doubleCount, increment }
  }
)

使用持久化

使用 useStorage 存储在 localStorage 中:

store.js
// store.js
import { createGlobalState, useStorage } from '@vueuse/core'

export const useGlobalState = createGlobalState(
  () => useStorage('vueuse-local-storage', 'initialValue'),
)
component.js
// component.js
import { useGlobalState } from './store'

export default defineComponent({
  setup() {
    const state = useGlobalState()
    return { state }
  },
})

类型声明

// 表示 createGlobalState 返回的函数,和你传入的 stateFactory 类型一致。
// 也就是说,它 返回一个工厂函数,只不过它内部始终使用的是 同一个实例。
export type CreateGlobalStateReturn<Fn extends AnyFn = AnyFn> = Fn
/**
 * 将状态保留在全局作用域中,以便在多个 Vue 实例之间重用。
 *
 * @see https://vueuse.org/createGlobalState
 * @param stateFactory 一个返回响应式状态的函数(例如 useStorage(...)、reactive(...)、ref(...))
 * @returns 一个函数(你可以随时调用它),但无论调用多少次,返回的都是同一个状态。
 */
export declare function createGlobalState<Fn extends AnyFn>(
  stateFactory: Fn,
): CreateGlobalStateReturn<Fn>

createGlobalState 是一个用于创建 全局响应式状态 的工具函数,可以让某个状态在多个组件或实例中共享

这在需要避免 Vue 的 provide/injectPiniaVuex 等大型状态管理时非常有用。