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