全局状态管理
刀刀
0字
0分钟
2026/8/16
小项目或对代码体积有要求的项目,可能不希望引入Pinia、Vuex 等全局状态管理库,而是自己实现一个简单的全局状态管理。
实现
通过闭包将状态存储,使用时拿到之前存储的值。第一次调用时无数据,触发一次回调函数;后续调用时直接返回之前存储的返回值。
js
import { ref } from 'vue'
export const useCounter = defineStore(() => {
const count = ref(1)
const addFn = () => {
count.value++
}
return {
count,
addFn,
}
})
function defineStore(fn) {
let state
return () => {
if (state) return state
return (state = fn())
}
}vue
<script setup>
import { useCounter } from './store/counter.js'
import Father from './components/Father.vue'
import Son from './components/Son.vue'
const { count } = useCounter()
</script>
<template>
<h1>{{ count }}</h1>
<Father />
<Son />
</template>vue
<script setup>
import { useCounter } from './store/counter.js'
const { count, addFn } = useCounter()
</script>
<template>
<h3>Father: {{ count }}</h3>
<button @click="addFn">add</button>
</template>vue
<script setup>
import { useCounter } from './store/counter.js'
const { count } = useCounter()
</script>
<template>
<div>Son: {{ count }}</div>
</template>细化
js
import { ref, getCurrentScope, effectScope } from 'vue'
export const useCounter = defineStore(() => {
const count = ref(1)
const addFn = () => {
count.value++
}
const scope = getCurrentScope()
return {
count,
scope,
addFn,
}
})
function defineStore(fn) {
let state
return () => {
if (state) return state
const scope = effectScope(true)
return (state = scope.run(fn))
}
}通过 effectScope 创建闭包,将状态存储在闭包中。defineStore 返回的函数第一次调用时执行 effectScope 中的函数,将状态存储并返回;第二次调用时直接返回之前存储的状态。
effectScope 用于创建作用域,作用域中的变量和函数在作用域销毁后会自动清理。它用于分组和管理多个响应式 effect,解决复杂场景下组织和清理 effect 的问题。
动手实操
跳转预览:点击跳转