场景
2024年03月20日
一、状态管理
可以模拟store
完成一套更灵活的状态管理又或用于子父组件、兄弟组件、全局通信
1.1 defineStore
import { effectScope } from "vue";
function defineStore(setup){
let state;
let isChange = false;
const scope = effectScope(true);
return ()=>{
if(!isChange){
state = scope.run(setup);
isChange = true;
}
return state;
}
}
export default defineStore;
1.2 useStore
import { computed, ref } from "vue";
import defineGlobalStore from "./defineStore";
const useStore = defineGlobalStore(() => {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
const updateCount = () => {
count.value++;
};
return { count, doubleCount, updateCount };
});
export default useStore;
随后, 可以在不同组件中使用
<template>
<div class="b">
<h3> B 组件</h3>
{{ count }}
{{ doubleCount }}
</div>
</template>
<script lang="ts" setup>
import useStore from "./store";
const { count, doubleCount, updateCont } = useStore();
</script>
<template>
<div class="b">
<h3> C 组件</h3>
{{ count }}
{{ doubleCount }}
<button @click="updateCount">C 组件 Update</button>
</div>
</template>
<script lang="ts" setup>
import useStore from "./store";
const { count, doubleCount, updateCount } = useStore();
</script>
二、包装组合函数
2.1 包装 useMouse, 只进行一次监听
import { effectScope, onScopeDispose, ref } from "vue";
function useMouse(){
const x = ref(0);
const y = ref(0);
const updateMouse = (e: MouseEvent) => {
x.value = e.pageX;
y.value = e.pageY;
}
window.addEventListener('mousemove', updateMouse);
onScopeDispose(()=>{
window.removeEventListener('mousemove', updateMouse);
});
return {x,y}
}
function createSharedComposable(composable){
let state;
let scope;
let subscribers = 0;
const dispose = ()=>{
if(scope && --subscribers <= 0){
scope.stop();
state = scope = null;
}
}
return (...args)=>{
subscribers++;
if(!state){
scope = effectScope(true);
state = scope.run(()=> composable(...args));
}
onScopeDispose(dispose);
return state;
}
}
const useShareMouse = createSharedComposable(useMouse);
export default useShareMouse;