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
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...