createGlobalState是VueUse库中提供的一个函数,它用于创建全局状态。在Vue中,可以使用provide/inject或Vuex来实现全局状态的管理,但是在某些简单的场景下,使用这些方案可能会过于繁琐。而createGlobalState则提供了一种更加简单的方式来管理全局状态。
createGlobalState函数接收一个参数,即全局状态的初始值,并返回一个数组。数组中的第一个元素为状态值,第二个元素为修改状态的函数。我们可以将这个数组用provide/inject方式提供给子组件使用。
例如,下面的示例代码使用createGlobalState来管理一个全局的计数器:
import { createGlobalState } from 'vueuse';
// 创建全局状态
const useCounter = createGlobalState(0);
// 父组件中使用状态
export default {
setup() {
const [count, setCount] = useCounter();
function increment() {
setCount(count.value + 1);
}
return {
count,
increment,
};
},
};
// 子组件中使用状态
export default {
setup() {
const [count] = useCounter();
return {
count,
};
},
};
源码分析
源码如下:
import { effectScope } from 'vue-demi'
import type { AnyFn } from '../utils'
/**
* Keep states in the global scope to be reusable across Vue instances.
*
* @see https://vueuse.org/createGlobalState
* @param stateFactory A factory function to create the state
*/
export function createGlobalState<Fn extends AnyFn>(
stateFactory: Fn,
): Fn {
let initialized = false
let state: any
const scope = effectScope(true)
return ((...args: any[]) => {
if (!initialized) {
state = scope.run(() => stateFactory(...args))!
initialized = true
}
return state
}) as Fn
}
这段代码定义了一个名为 createGlobalState 的函数,该函数接受一个函数作为参数,用于创建一个全局状态。
该函数利用了 Vue.js 的 effectScope API 来创建一个作用域,并将状态存储在该作用域中,以便在全局范围内重用。
createGlobalState 函数返回一个函数,该函数接受任意数量的参数,并在第一次调用时执行 stateFactory 函数以创建初始状态,并将该状态保存在闭包变量 state 中,之后再次调用该函数时直接返回已经创建好的状态。
由于 TypeScript 中的类型推断,该返回的函数的类型与传入的 stateFactory 函数的类型相同。
该实现还定义了两个变量:initialized 用于标记全局状态是否已经初始化,state 用于保存全局状态。在第一次调用返回的函数时,initialized 变量将设置为 true,并使用 effectScope 创建一个作用域来运行 stateFactory 函数以获取初始状态,并将该状态存储在 state 变量中。此后再次调用该返回的函数时,它将直接返回已经创建好的状态。