vue 全局状态(VUE3 自定义 轻量级全局数据共享方案之一 Provide&inject (简单快速实现vuex功能))
导读:除了兼容vue2的配置式注入,vue3在composition api 中添加了provide和inject方法,可以在setup函数中注入...
除了兼容vue2的配置式注入 ,vue3在composition api 中添加了provide和inject方法 ,可以在setup函数中注入
和使用数据
基本使用
provide(key,value)
// app.vue 定义数据
<script setup>
import { provide,ref } from vue
const sum = ref(1)
provide(foo,sum)
</script>
// 其他页面调用
<script setup>
import { inject } from vue
let foo = inject(foo)//传入key 在其他任意页面都能获取到
console.log(foo.value)// 1
</script>
考虑到有些数据需要在整个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
封装注入模块给app
src/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本身提供的独立响应式系统来实现的 。
声明:本站所有文章,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!