VUE3 自定義 輕量級全局數據共用方案之一 Provide&inject (簡單快速實現vuex功能)

来源:https://www.cnblogs.com/Allen-project/archive/2022/11/24/16920770.html
-Advertisement-
Play Games

在vue2中,提供了provide和inject配置,可以讓開發者在高層組件中註入數據,然後在後代組件中使用 除了相容vue2的配置式註入,vue3在composition api 中添加了provide和inject方法,可以在setup函數中註入 和使用數據 基本使用 provide('key' ...


在vue2中,提供了provide和inject配置,可以讓開發者在高層組件中註入數據,然後在後代組件中使用 除了相容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本身提供的獨立響應式系統來實現的。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、MySQL簡介 ​ MySQL是一種關係型資料庫管理系統,關係資料庫將數據保存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。 二、安裝與下載 1、下載流程 1、訪問官方(www.mysql.com) 2、點擊‘DOWNLOADS’,進入下載界面 3、下拉,找到‘ ...
  • 關於 uniapp 獲取已安裝應用列表 uniapp 中返回的數據問題 獲取所有安裝的app 判斷是否是系統應用 獲取詳細app信息 遇到的問題 參考文檔 uniapp 中返回的數據問題 在uniapp中有時候放回的數據是 一個對象裡面(如下麵所示這種)根本不知大怎麼處理,查閱資料也沒相關資料,只能 ...
  • Android開發之線程間通信 當我們的軟體啟動的時候,電腦會分配進程給到我們運行的程式,在進程中包含多個線程用於提高軟體運行速度。 在android網路請求中,我們知道在日常開發中不能在子線程中跟新ui,否則報錯Only the original thread that created a vi ...
  • 現如今, AR技術不斷發展,人們不再滿足於運用鍵盤、滑鼠等簡單器械來實現傳統的人機交互模式。隨著用戶接觸機器的多樣化,繁瑣的操作不但對一些用戶有門檻,而且還增加其學習成本;如果能用自然且符合日常生活習慣的人機交互模式,不僅更好上手,也能讓開發者們在應用內開發更多玩法。比如在視頻直播或者拍照過程中,一 ...
  • 對象中可以直接寫變數 ES6 允許在大括弧裡面,直接寫入變數和函數,作為對象的屬性和方法。 const foo = 'bar'; const obj = {foo}; //key值就是foo,value值是 foo變數對應的值 // 輸出的是 {foo: "bar"} console.log(obj ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 現在 uniapp 開發的實時音視頻聊天類的 APP 大部分都要在 nvue 頁面上進行開發。雖然 nvue 與 vue 的區別不是很大,但還是有所差異的。 仔細查看了 uniapp 官網,發現了可以使用原生子窗體進行開發,可以把整個視頻 ...
  • 要成為一名優秀的 Web 開發人員,最快的方法就是練習。一個很好的練習方法是儘可能多地構建初學者項目。那是因為每個項目都會提出一個獨特的問題和解決方案,因此您解決的項目越多,您獲得的知識就越多。將您完成的每個項目都視為您獲得的獎牌。您擁有的獎牌越多,您就越能準備好應對下一個難度更大的項目。 為了幫助 ...
  • 個人名片: 對人間的熱愛與歌頌,可抵歲月冗長:sun_with_face: Github👨🏻‍💻:念舒_C.ying CSDN主頁✏️:念舒_C.ying 個人博客:earth_asia: :念舒_C.ying 預覽圖 直接進入我的網站吧 >> Z_C戀愛日記 下載源碼 鏈接:https:// ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...