自定義 封裝單列模式! global state 由於vue3的響應式系統本身可以脫離組件而存在,因此可以充分利用這一點,輕鬆製造多個全局響應式數據, 並且通過和vuex一樣 通過某個模塊指定方法修改數據,不能直接修改數據,並且讓數據成為全局響應式 並且在代碼體積上絕對的輕量級!比市面上的任何第三方 ...
自定義 封裝單列模式! global state
由於vue3的響應式系統本身可以脫離組件而存在,因此可以充分利用這一點,輕鬆製造多個全局響應式數據, 並且通過和vuex一樣 通過某個模塊指定方法修改數據,不能直接修改數據,並且讓數據成為全局響應式 並且在代碼體積上絕對的輕量級!比市面上的任何第三方共用數據插件都要輕量。1.創建一個js ,diy-vuex.js 名字自己定義 我為了模擬共用數據 和vuex相似所以叫這個
2.第二步封裝 我們的共用數據模塊
diy-vuex.js
// 模擬ajax api介面使用 const userSery = { // 登錄介面 login: (name,age) =>{ // 介面返回用戶數據 儲存在本地 return new Promise((resolve,reject)=>{ setTimeout(()=>{ let user = { name :name, age:age } window.sessionStorage.setItem('user',JSON.stringify(user)) console.log('登錄成功') resolve(user) },1000) }) }, // 退出登錄 loginOut:()=>{ return new Promise((resolve,reject)=>{ setTimeout(()=>{ window.sessionStorage.removeItem('user') resolve('退出成功') },1000) }) }, // 恢復登錄 whoAmI:()=>{ // 讀取本地儲存的用戶數據 return new Promise((resolve,reject)=>{ setTimeout(()=>{ let user = window.sessionStorage.getItem('user'); if(user){ user = JSON.parse(user); console.log('恢覆成功',user) resolve(user); } else { reject('恢復失敗'); }; },1000) }) } } import { reactive,readonly } from 'vue' // 創建預設的全局單列響應式數據,僅供改模塊內部使用 const state = reactive({user:null,loading:false}); // 對外保留的數據只能讀取,不能修改 // 也可以進一步使用toRefs進行封裝,從而避免解構或展開後響應式丟失 export const loginUserStore = readonly(state); // 登錄 export async function login (loginId,loginPwd){ state.loading = true const user = await userSery.login(loginId,loginPwd); state.user = user; state.loading = false } // 退出 export async function loginOut (){ state.loading = true await userSery.loginOut(); state.user = null; state.loading = false } // 恢復登錄狀態 export async function whoAmI (){ state.loading = true try { const user = await userSery.whoAmI(); state.user = user; state.loading = false } catch (e) { state.user = null; } state.loading = false }
3.頁面調用我們的封裝模塊
因為js文件只會載入一次,並且在去讀取是有緩存的。
<template> diyVuex<br/> <div> <span >{{loginUserStore.loading?'載入中...':''}}</span> <p style="cursor: pointer;" v-if="!loginUserStore.user" @click="loginEvent"><span>去登錄</span></p> <p style="cursor: pointer;" v-else-if="loginUserStore.user" @click="loginOutEvent"><span>退出登錄</span></p> <div v-if="loginUserStore.user"> <span>用戶:{{loginUserStore.user.name}}</span><br/> <span>年齡:{{loginUserStore.user.age}}</span> </div> </div> </template> <script setup> import { login,loginUserStore,loginOut ,whoAmI} from '../store/diy-vuex.js' const router = useRouter(); // 點擊 登錄 const loginEvent = ()=>{ login('allen',18) }; // 退出登錄 const loginOutEvent = ()=>{ loginOut() }; // 恢復登錄 whoAmI(); </script> <style scoped> </style>
點擊登錄 頁面最後這樣
註意:當我們登錄成功了 保存了數據 跳轉到其他頁面的時候 其他頁面需要讀取和修改的時候 ,一樣的引入這個模塊就可以使用了,並且數據是隨時更新的,實現了類似vuex的全局響應式共用數據,
也就是說上一個頁面修改了 這個模塊的state數據,其他任何地方展示或讀取到的就是最後一次修改的state數據。
最後優化建議:以上只是一個最基本的結構是這樣的,當我們在中大型項目中 全部數據內容和函數寫一個文件肯定不行的 建議模塊化導入,像vuex一樣 一個index.js 其他分模塊合併在 一個index.js中