自定义 封装单列模式! 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文件只会加载一次,并且在去读取是有缓存的。

    diyVuex
{{loginUserStore.loading?'加载中...':''}}

if="!loginUserStore.user" @click="loginEvent">去登录

else-if="loginUserStore.user" @click="loginOutEvent">退出登录

<div v-if="loginUserStore.user"> 用户:{{loginUserStore.user.name}}
年龄:{{loginUserStore.user.age}} import { login,loginUserStore,loginOut ,whoAmI} from '../store/diy-vuex.js' const router = useRouter(); // 点击 登录 const loginEvent = ()=>{ login('allen',18) }; // 退出登录 const loginOutEvent = ()=>{ loginOut() }; // 恢复登录 whoAmI();

点击登录 页面最后这样

注意:当我们登录成功了 保存了数据 跳转到其他页面的时候 其他页面需要读取和修改的时候 ,一样的引入这个模块就可以使用了,并且数据是随时更新的,实现了类似vuex的全局响应式共享数据,

也就是说上一个页面修改了 这个模块的state数据,其他任何地方展示或读取到的就是最后一次修改的state数据。

最后优化建议:以上只是一个最基本的结构是这样的,当我们在中大型项目中 全部数据内容和函数写一个文件肯定不行的 建议模块化导入,像vuex一样 一个index.js 其他分模块合并在 一个index.js中