結合 Vue.observable 寫一個簡易 Vuex


作為 Vue 全家桶的一員,Vuex 的重要性不言而喻,不管是用來管理狀態,還是封裝 Controler 都很好用

不過在一些體量較小的項目中,為了幾個簡單的狀態或者處理函數而引入 Vuex,就像是高射炮打蚊子,大材小用了

這時候就可以模擬 Vuex,自己寫一個簡單的 Store, 用來管理狀態並實時更新數據

 

 

一、構造函數

模擬 Vuex 的結構,創建一個 Class

export default class Store { constructor({ states, actions, mutations }) { // 狀態
    this.states = states || {}; // 異步函數
    this.actions = actions || {}; // 同步函數
    this.mutations = mutations || {}; } // 調用 mutations 中的同步函數
  commit = (fun, params) => {}; // 調用 actions 中的異步函數
  dispatch = (fun, params) => {}; // 更新 states 的狀態
  update = (key, value) => {}; }

 

然后實例化一個 Store

import Store from './store'; import states from './states'; import actions from './actions'; import mutations from './mutations'; const store = new Store({ states, actions, mutations, }); export default store;

 

然后掛到 vue 的原型上,通過 vue.$store 的方式使用,一個高仿 vuex 的架子就搭好了

// 在 main.js 中引入 Store
import store from './store/index'; Vue.prototype.$store = store;

 

 

二、實現操作函數(commit、dispatch、update

在 Vuex 中,如果需要更新 state 中的狀態,需要通過 commit 調用 mutations 中的方法

而 mutations 的方法都具備一個默認的參數 state,因此 commit 方法可以這么寫:

// 向 mutations 中的傳入固定參數 state
commit = (fun, params) => { this.mutations[fun](this.states, params); };

 

不過由於一些歷史遺留問題,我習慣用 this.states 的方式獲取 state(這個習慣不好),所以改成了這樣:

  commit = (fun, params) => { if (fun) { this.mutations[fun].call(this, params); } else { return false; } };

類似的 actions 和 update 可以參考 commit 的寫法

 

 

三、響應式對象

目前的 store 有一個致命的問題:state 更新之后並不會即時渲染到視圖層

這時候 Vue 2.6.0 新增的 observable() 就派上用場了

 

如果將一個對象作為入參傳給 Vue.observable() ,經過處理之后,這個對象在 Vue 內就可以實時更新

其返回值可以直接用於 render 和 computed 中,並且會在發生改變時觸發相應的更新

 

於是 Store 的構造函數需要改一改:

 constructor({ states, actions, mutations }) { // 狀態
    this.states = Vue.observable(states || {}); // 異步函數
    this.actions = Vue.observable(actions || {}); // 同步函數
    this.mutations = Vue.observable(mutations || {}); }

 

⚠️注意:

假如對象 obj 經過 observable() 處理之后,賦值給了新對象 new_obj

在 Vue 2.x 中,直接修改 obj 也會觸發 new_obj 的更新

但在 Vue 3.x 中,由於響應機制的變更,只有修改 new_obj 才能觸發視圖層的更新

所以在使用 observable() 的時候,最好始終操作使用 observable() 處理后的 new_obj

 

 

四、簡單用用

超低配的 Vuex 已經寫好了,上面已經把 store 掛到 Vue 的原型上,所以可以直接使用

假如 state 中已經存在一個狀態 name,在組件中可以通過 computed 去獲取

computed: { name() { return this.$store.states.name; }, }

如果需要修改狀態,可以通過 $store.update()

methods: { updateName(val) { this.$store.update('name', val); } }

或者使用 $store.commit() 調用 mutations 中的方法

methods: { commitName(val) { this.$store.commit('handleNameChange', val); } }

大功告成~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM