vue3如何使用provide實現(xiàn)狀態(tài)管理詳解
前言
在 Vue 生態(tài)中, Vuex 這個官方的狀態(tài)管理庫在 Vue 應(yīng)用開發(fā)中,為我們帶來了非常便捷的功能。但是 Vuex 20K+ 的大小,也帶來了一些成本,對于項目規(guī)模較小的應(yīng)用來說, 引入 Vuex 只是為了存儲用戶信息之類的一小撮數(shù)據(jù),有點不值得。
Vue2.2.x 在后期就提供了 provide/inject API 來幫我們實現(xiàn)跨層級組件之間的通信。
Vue3.x 把 provide 也放到了應(yīng)用 API 上,這就更方便讓我們在此基礎(chǔ)上,實現(xiàn)一個基礎(chǔ)的狀態(tài)管理。
如何通過 provide/inject 實現(xiàn) Vuex的功能
首先我們想一下大概的邏輯,把它做成一個插件,通過 use 方法注冊到應(yīng)用實例中。
在 install 方法中,通過 app.provide 方法,把數(shù)據(jù)掛載到根組件上,該數(shù)據(jù)應(yīng)該是一個響應(yīng)式數(shù)據(jù),并且為了數(shù)據(jù)安全,應(yīng)該對數(shù)據(jù)的變更進(jìn)行限制,遵循單向數(shù)據(jù)流的設(shè)計,不能讓用戶直接的進(jìn)行修改,所以在暴露數(shù)據(jù)時,應(yīng)該對數(shù)據(jù)進(jìn)行 readonly(只讀) 處理。
實現(xiàn)類似 Vuex 的 useStore 功能,讓用戶通過此方法訪問數(shù)據(jù)。
實現(xiàn)類似 Vuex 的 mapState、mapMutations 和 mapActions方法,簡化操作。
用法直接跟 Vuex 一樣。
在應(yīng)用中注冊此插件
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)
app.use(router).use(store).mount('#app')
插件的入口文件
在入口文件中,直接導(dǎo)出所有方法。
// sky-vuex/index.ts export * from './main/index'
創(chuàng)建 store ,把對應(yīng)的數(shù)據(jù)掛載到根組件上
store 本身是一個對象,包含 state 屬性和 commit、dispatch 等方法。 store 最主要的一些功能就是讓所有組件,都能拿到 store 對象,來獲取 state 中的數(shù)據(jù),以及調(diào)用相關(guān)方法來修改 state。
// sky-vuex/main/index.ts
import {inject, reactive, readonly} from 'vue'
const mainStoreSky = Symbol('main store key')
interface storeOptions {
state?: any
actions?: any
mutations?: any
}
export const createStore = (options: storeOptions = {}) => { // 創(chuàng)建 store 對象
const initOptions = {
state: {},
actions: {},
mutations: {},
}
const mergeOptions: storeOptions = Object.assign(initOptions, options)
const state = reactive(mergeOptions.state)
const store = {
state: readonly(state),
dispatch(eventName: string, ...args: any[]) {
mergeOptions.actions[eventName](store, ...args)
},
commit(eventName: string, ...args: any[]) {
...
},
}
return {
install(app: any) {
app.provide(mainStoreSky, store)
},
}
}
export const useStore = (): any => { // 其他組件通過此方法,獲取 store 對象
return inject(mainStoreSky)
}
實現(xiàn) mapState、mapMutations 和 mapActions方法
export const mapState = () => {
const store = useStore()
return store.state
}
export const mapActions = (eventName: string) => {
const store = useStore()
return (...args: any[]) => store.dispatch(eventName, ...args)
}
export const mapMutations = (eventName: string) => {
const store = useStore()
return (...args: any[]) => store.commit(eventName, ...args)
}
組件中使用
// store/index.ts
import { createStore } from '../sky-vuex/index'
export default createStore({
state: {
age: 18
},
mutations: {
setAge(state: any, data: number) {
state.age = data
}
},
})
// Home.vue
<template>
<div class="home">
<button @click="handleAge(23)">修改數(shù)據(jù)</button>
<h1>{{ state.age }}</h1>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useStore, mapActions, mapMutations } from '@/sky-vuex/index'
export default defineComponent({
name: 'Home',
setup() {
const store = useStore()
const handleAge = mapMutations('setAge')
// const handleAge = mapActions('setAge')
// const handleAge = () => {
// store.dispatch('setAge', 5)
// }
return {
state: store.state,
handleAge,
}
},
})
</script>
總結(jié)
至此已經(jīng)實現(xiàn)了基礎(chǔ)的 Vuex 功能,可以自己動手實踐一下,進(jìn)行優(yōu)化,有問題歡迎大家提出
到此這篇關(guān)于vue3如何使用provide實現(xiàn)狀態(tài)管理的文章就介紹到這了,更多相關(guān)vue3 provide實現(xiàn)狀態(tài)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在vue中實現(xiàn)iframe嵌套Html頁面及注意事項說明
這篇文章主要介紹了在vue中實現(xiàn)iframe嵌套Html頁面及注意事項說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10
vue-element-admin中node-sass換成dart-sass,安裝依賴報code?128多種問題的解決
這篇文章主要介紹了vue-element-admin中node-sass換成dart-sass,安裝依賴報code?128多種問題的解決方法,本文給大家分享問題原因分析及解決方法,需要的朋友可以參考下2023-02-02
Vue使用antd組件a-form-model實現(xiàn)數(shù)據(jù)連續(xù)添加功能
這篇文章主要介紹了Vue使用antd組件a-form-model實現(xiàn)數(shù)據(jù)連續(xù)添加功能,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12
一步一步實現(xiàn)Vue的響應(yīng)式(對象觀測)
這篇文章主要介紹了一步一步實現(xiàn)Vue的響應(yīng)式(對象觀測),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09

