vue3如何使用provide實現狀態管理詳解
前言
在 Vue 生態中, Vuex 這個官方的狀態管理庫在 Vue 應用開發中,為我們帶來瞭非常便捷的功能。但是 Vuex 20K+ 的大小,也帶來瞭一些成本,對於項目規模較小的應用來說, 引入 Vuex 隻是為瞭存儲用戶信息之類的一小撮數據,有點不值得。
Vue2.2.x 在後期就提供瞭 provide/inject API 來幫我們實現跨層級組件之間的通信。
Vue3.x 把 provide 也放到瞭應用 API 上,這就更方便讓我們在此基礎上,實現一個基礎的狀態管理。
如何通過 provide/inject 實現 Vuex的功能
首先我們想一下大概的邏輯,把它做成一個插件,通過 use 方法註冊到應用實例中。
在 install 方法中,通過 app.provide 方法,把數據掛載到根組件上,該數據應該是一個響應式數據,並且為瞭數據安全,應該對數據的變更進行限制,遵循單向數據流的設計,不能讓用戶直接的進行修改,所以在暴露數據時,應該對數據進行 readonly(隻讀) 處理。
實現類似 Vuex 的 useStore 功能,讓用戶通過此方法訪問數據。
實現類似 Vuex 的 mapState、mapMutations 和 mapActions方法,簡化操作。
用法直接跟 Vuex 一樣。
在應用中註冊此插件
// 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')
插件的入口文件
在入口文件中,直接導出所有方法。
// sky-vuex/index.ts export * from './main/index'
創建 store ,把對應的數據掛載到根組件上
store 本身是一個對象,包含 state 屬性和 commit、dispatch 等方法。 store 最主要的一些功能就是讓所有組件,都能拿到 store 對象,來獲取 state 中的數據,以及調用相關方法來修改 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 = {}) => { // 創建 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) }
實現 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)">修改數據</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>
總結
至此已經實現瞭基礎的 Vuex 功能,可以自己動手實踐一下,進行優化,有問題歡迎大傢提出
到此這篇關於vue3如何使用provide實現狀態管理的文章就介紹到這瞭,更多相關vue3 provide實現狀態管理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!