在vue2中,提供了provide和inject配置,可以让开发者在高层组件中注入数据,然后在后代组件中使用除了兼容vue2的配置式注入,vue3在composition api 中添加了provide和inject方法,可以在setup函数中注入和使用数据基本使用provide(‘key’,value)

// app.vue 定义数据import { provide,ref } from 'vue'const sum = ref(1)provide('foo',sum) 
// 其他页面调用import { inject } from 'vue'let foo = inject('foo')//传入key 在其他任意页面都能获取到console.log(foo.value)// 1

考虑到有些数据需要在整个vue应用中使用,vue还在应用实列中加入了provide方法,用于提供整个应用的共享数据

creaetApp(App).provide('fpp',ref(1)).provide('foo',ref(2)).mount('#app')

因此,我们可以利用这一点,在整个vue应用中提供共享数据目录结构:

模块封装

userSever.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)        })    }}// store  提供当前登录用户的共享数据import { readonly,reactive,inject } from 'vue';const key = Symbol();// 在传入的vue应用实列中提供数据export function provideStore(app){    //  创建默认的响应式数据    const state = reactive({user:null,loading:false});    // 登录    async function login (loginId,loginPwd){        state.loading = true        const user = await userSery.login(loginId,loginPwd);        state.user = user;        state.loading = false    }    // 退出    async function loginOut (){        state.loading = true        await userSery.loginOut();        state.user = null;        state.loading = false    }        // 恢复登录状态    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    }    app.provide(key,{        state:readonly(state), // 对外只读        login,        loginOut,        whoAmI    })}export function useStore(defaultValue = null){    return inject(key,defaultValue)}

View Code封装注入模块给appsrc/store/index.js

import { provideStore as provideLoginUserStore } from "./userSever.js"// 继续导入其他共享数据模块...// import {provideStore as provideNewsStore } from './sueNew.js'// 提供统一的数据注入接口export default function provideStore (app){provideLoginUserStore(app);// 继续注入其他共享数据// provideNewsStore}

main.js导入并且注入app

import { createApp } from 'vue'import App from './App.vue'import router from './router'import provideStore from './store'const app = createApp(App).use(router);provideStore(app) // 提供所有共享数据app.mount('#app')// createApp(App).use(store).use(router).mount('#app')

到这里就已经完成了 全部准备工作在你想调用的地方和页面进行下面引入和使用

import { useStore} from '../store/userSever.js'const Store  =  useStore()console.log(Store.state); //定义的state响应式数据// 下面调用 导入模块的指定的函数方法去修改 state共享的响应式数据内容// 点击 登录const loginEvent = ()=>{Store.login('allen',18)};// 退出登录const loginOutEvent = ()=>{Store.loginOut()};// 恢复登录Store.whoAmI()

共享响应式数据,在A页面使用到了state,在B页面去调用函数改变 state 那么A页面的state数据也会发送改变,只要使用到的state的地方都会响应式改变数据,相比vuex 更加轻量级 更加具有自定义扩展的能力,因为他本身不依赖任何第三方插件,完全是靠vue本身提供的独立响应式系统来实现的。