vuex的命名空间有哪些_Vue 3 带来的 Vuex 的替代方案
一、前言
就像是 React 社區在 HOOK API 出現后很快就使用 useReducer、useContext 代替了 Redux 進行狀態管理一樣。Vue3 也是時候拋棄 Vuex 進行狀態管理了。在考慮為什么要拋棄 Vuex 之前,我們先來想一下為什么要引入 Vuex?
Vuex 實際上解決的問題是「組件間傳遞對象」的問題:
在傳統的方式里,我們如果要把一個對象從父組件傳遞到子組件,要使用 prop 進行傳遞。
如果組件間不是直接的「父子關系」的話(如「爺孫關系」),傳遞對象的過程要經過整顆組件樹————這讓我們的代碼變得很丑陋,提高了相當多的復雜度。
我們引入 Vuex 就是為了提供一個統一管理組件狀態的地方,來讓我們的組件之間可以簡單的傳遞對象。
但是引入 Vuex 的本質原因還是:降低代碼的復雜度
但是 Vuex 陡峭的學習曲線,令人費解的 Getter、Module、Store、Mutation、Action 等概念,又引入了新的代碼復雜度,新的心智負擔。
當我真正掌握了它的時候,我并沒有驚呼,而是對其產生了深深的排斥。
所以,當現在 Vue3 到來,有了更新、更輕量的依賴注入工具 provide、inject 函數,我們有什么道理不像隔壁的 React 社區學習————用 useReducer、useContext (provide、inject)代替 Redux(Vuex)呢?
二、關于 Vue3 與 Vue Composition API
目前 Vue 3 還處于 Alpha 版本,但是我們已經可以通過使用 @vue-composition 來提前在 Vue2 環境下體驗 Vue3 的新特性了。
- vue 3 的 Github:https://github.com/vuejs/vue-next
- vue-composition 的 Github:https://github.com/vuejs/composition-api
- vue-composition 的使用文檔:https://vue-composition-api-rfc.netlify.com/api.html
vue-composition 提供了類似 React Hook 的能力,將 Vue 的抽象層級從「組件級(Component)」降低為「函數級(Function)」。
用了將近一周的時間,說句實話,我感覺到非常的興奮!
Vue Composition API 的建議學習路線
如果想學習 vue-composition 的同學,可以點擊上面的 vue-composition 的使用文檔進行學習,學習路線建議如下:
三、Vuex 是什么?
打開 Vuex 的官方網站,我們可以看到這樣一段描述:
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也集成到了 Vue 的官方調試工具 devtools extension,提供了諸如零配置的 time-travel 調試、狀態快照導入導出等高級調試功能。我們來畫一下重點,看看 Vuex 提供了什么能力:
我們仔細的看一下,然后準備去設計一個新的狀態管理模式
第一條:集中式存儲管理「所有組件」的「狀態」
請注意,這里它并不是要去管理「所有組件」的「所有狀態」———— 也就是說我們每個組件中還是可以有自己的「私有狀態」的。
這很好理解:比如在「登錄注冊頁面」中我們的「短信驗證碼計時器」的狀態很明顯就是一個「私有狀態」。
那我們要解決的就是集中式存儲管理這件事情了,我認為該難點在于:
第二條:保證狀態以「可預測」的方式「發生變化」
需要解決的難點就是,狀態的變化可以被追溯到:
即:「哪個組件」改變了「什么狀態」
第三條:時間旅行與狀態快照導入導出
本條的難點在于——是否全局狀態就是一個 Vue APP 的快照?
以及是否有一個工具配合你做調試。
四、provide、inject 是什么?
provide、inject 是 vue-composition-api 的一個新功能:依賴注入功能
import { provide, inject } from 'vue'const ThemeSymbol = Symbol()const Ancestor = {setup() {provide(ThemeSymbol, 'dark')} }const Descendent = {setup() {const theme = inject(ThemeSymbol, 'light' /* optional default value */)return {theme}} }這是怎么注入的呢?我們還是看圖來說話:
我們都知道 Vue 是一顆「組件樹」,我們只要保證是「父節點」 provide,那么它的「子節點」就一定可以通過 inject 獲取到。
舉例:
- A provide,B 可以 inject,C 可以 inject,D 可以 inject
- B provide,D 可以 inject
- D provide,沒有其它節點可以 inject
- C provide,沒有其它節點可以 inject
五、我們結合一下 Vuex 的特點和 provide、inject 的特性來看,新的狀態管理應該具有哪些特點
5.1 聲明一次,全局可訪問
為了實現這樣子的特點,我們就需要將「需要共享的狀態」事先在我們 Vue 的根節點 App.vue 中通過 provide 聲明好了。
而「單例」的需求也在這里得到解決——我們的狀態不會被創建多次。
5.2 全局可訪問「公共狀態」的「命名」
全局可訪問即全局可導入,我們僅需要把「公共狀態」的「命名」放在一個單一的文件中即可:
// src/store/store.ts const temporaryPlanList = Symbol() const dailyPlanList = Symbol() export default {temporaryPlanList,dailyPlanList }然后再在需要訪問的地方導入:比如 App.vue 中 provide
// src/App.vue <script lang="ts"> import Store from "./store/store"import { defineComponent, provide, ref } from "@vue/composition-api" export default defineComponent({setup() {provide(Store.temporaryPlanList, ref([]))provide(Store.dailyPlanList, ref([]))} }) </script>比如 Plan.vue 中 inject(Plan.vue 是 App.vue 的子節點)
// src/views/Plan.vue <script lang="ts"> import Store from "./store/store"import { defineComponent, provide, ref } from "@vue/composition-api" export default defineComponent({setup() {const temporaryPlanList = inject(Store.temporaryPlanList)const dailyPlanList = inject(Store.dailyPlanList)} }) </script>5.3 保證「狀態」以可預測的方式發生變化
其實.....就是要多設置一個 setter 而已。
就像是 Vuex 中 Store 中存儲的狀態要靠 mutation 提交才可以更改。
但是這真的有用嗎?不是脫了褲子放屁嗎?
反正我認為是多此一舉,還不如就是直接修改全局變量的狀態。
5.4 時間旅行與應用快照
這點需要調試工具配合,目前來看是無法用 inject、provide 替代了。
六、參考文獻
https://blog.logrocket.com/use-hooks-and-context-not-react-and-redux/?blog.logrocket.com 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的vuex的命名空间有哪些_Vue 3 带来的 Vuex 的替代方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序快递查询插件
- 下一篇: 浅谈vue $mount()