淺談VUE的狀態管理模式-vuex

      網友投稿 946 2025-04-01

      Vuex

      Vuex是一個專為Vue.js應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。

      什么是“狀態管理模式”?

      以一個簡單的 Vue 計數應用開始:

      new Vue({ // state data () { return { count: 0 } }, // view template: `

      {{ count }}
      `, // actions methods: { increment () { this.count++ } } })

      這個狀態自管理應用包含以下幾個部分:

      state,驅動應用的數據源;

      view,以聲明方式將?state?映射到視圖;

      actions,響應在?view?上的用戶輸入導致的狀態變化。

      “單向數據流”理念的簡單示意:

      為什么需要Vuex

      但是,當我們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:

      多個視圖依賴于同一狀態。

      來自不同視圖的行為需要變更同一狀態。

      對于問題一,傳參的方法對于多層嵌套的組件將會非常繁瑣,并且對于兄弟組件間的狀態傳遞無能為力。

      對于問題二,我們經常會采用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。以上的這些模式非常脆弱,通常會導致無法維護的代碼。

      當頁面中的組件層級很深時,組件之間的通信變得十分繁瑣和難以維護

      這個時候需要把組件的共享狀態抽取出來,以一個全局單例的模式來管理。

      在這種模式下,我們的組件樹構成了一個巨大的“視圖”,不管在樹的哪個位置,任何組件都能獲取狀態或者觸發行為。如下圖

      vuex組成

      在VueX對象中,其實不止有state,還有用來操作state中數據的方法集,以及當我們需要對state中的數據需要加工的方法集等等成員。

      核心

      State-所有的原始數據

      Getter- State的計算屬性(類比組件的Computed屬性)

      Mutation - 內部的事件,控制state (同步事件)

      Action-外部事件,對應組件的methods(同步、異步事件Module - 對Store進行分模塊

      VueX的流程

      首先,Vue組件如果調用某個VueX的方法過程中需要向后端請求時或者說出現異步操作時,需要dispatch?VueX中actions的方法,以保證數據的同? 步。可以說,action的存在就是為了讓mutations中的方法能在異步操作中起作用。

      如果沒有異步操作,那么我們就可以直接在組件內提交狀態中的Mutations中自己編寫的方法來達成對state成員的操作。

      最后被修改后的state成員會被渲染到組件的原位置當中去。

      在 Vue 組件中獲得 Vuex 狀態

      store

      那么我們如何在 Vue 組件中展示狀態呢?由于 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性 中返回某個狀態:

      // 創建一個 Counter 組件 const Counter = { template: `

      {{ count }}
      `, computed: { count () { return store.state.count } } }

      每當?store.state.count?變化的時候, 都會重新求取計算屬性,并且觸發更新相關聯的 DOM。

      然而,這種模式導致組件依賴全局狀態單例。在模塊化的構建系統中,在每個需要使用 state 的組件中需要頻繁地導入,并且在測試組件時需要模擬狀態。

      Vuex 通過?store?選項,提供了一種機制將狀態從根組件“注入”到每一個子組件中(需調用?Vue.use(Vuex)):

      const app = new Vue({ el: '#app', // 把 store 對象提供給 “store” 選項,這可以把 store 的實例注入所有的子組件 store, components: { Counter }, template: `

      ` })

      通過在根實例中注冊?store?選項,該 store 實例會注入到根組件下的所有子組件中,且子組件能通過?this.$store?訪問到。讓我們更新下?Counter?的實現:

      const Counter = { template: `

      {{ count }}
      `, computed: { count () { return this.$store.state.count } } }

      getter

      Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。

      Getter 接受 state 作為其第一個參數:

      通過屬性訪問

      Getter 會暴露為?store.getters?對象,你可以以屬性的形式訪問這些值:

      store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]

      Getter 也可以接受其他 getter 作為第二個參數:

      getters: { // ... doneTodosCount: (state, getters) => { return getters.doneTodos.length } }

      store.getters.doneTodosCount // -> 1

      我們可以很容易地在任何組件中使用它:

      computed: { doneTodosCount () { return this.$store.getters.doneTodosCount } }

      淺談VUE的狀態管理模式-vuex

      注意,getter 在通過屬性訪問時是作為 Vue 的響應式系統的一部分緩存其中的。

      通過方法訪問

      你也可以通過讓 getter 返回一個函數,來實現給 getter 傳參。在你對 store 里的數組進行查詢時非常有用。

      getters: { // ... getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } }

      store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

      注意,getter 在通過方法訪問時,每次都會去進行調用,而不會緩存結果

      Mutation

      更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的?事件類型 (type)?和 一個?回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數:

      const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 變更狀態 state.count++ } } })

      你不能直接調用一個 mutation handler。這個選項更像是事件注冊:“當觸發一個類型為?increment?的 mutation 時,調用此函數。”要喚醒一個 mutation handler,你需要以相應的 type 調用?store.commit?方法:

      store.commit('increment')

      Action

      Action 類似于 mutation,不同在于:

      Action 提交的是 mutation,而不是直接變更狀態。

      Action 可以包含任意異步操作。

      讓我們來注冊一個簡單的 action:

      const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } })

      Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用?context.commit?提交一個 mutation,或者通過?context.state?和?context.getters?來獲取 state 和 getters。當我們在之后介紹到?Modules?時,你就知道 context 對象為什么不是 store 實例本身了。

      Module

      隨著項目的復雜度增大,為了方便管理vuex,一般會將其按功能分割成不同的模塊(Module),方便日后管理。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊

      const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的狀態 store.state.b // -> moduleB 的狀態

      總結:簡單說了下vuex的應用和核心,如果想詳細了解vuex,建議去官網看文檔。

      Vue

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:PDF識別
      下一篇:【轉載】linux查找目錄下的所有文件中是否含有某個字符串
      相關文章
      国产亚洲一区二区精品| 亚洲国产第一站精品蜜芽| 亚洲一区二区三区四区在线观看| 中文字幕精品亚洲无线码一区| 亚洲精品无码久久不卡| 亚洲国产高清精品线久久| 亚洲A∨精品一区二区三区| 337p日本欧洲亚洲大胆人人| 亚洲精品国产摄像头| 亚洲欧美一区二区三区日产| 亚洲中文字幕乱码AV波多JI| 亚洲中文字幕无码mv| 亚洲高清国产拍精品熟女| 亚洲aⅴ无码专区在线观看| 久久无码av亚洲精品色午夜| 亚洲AV无码精品国产成人| 亚洲aⅴ无码专区在线观看春色| 337p日本欧洲亚洲大胆人人| 日韩亚洲翔田千里在线| 亚洲免费日韩无码系列| jlzzjlzz亚洲乱熟在线播放| 亚洲无线码一区二区三区| 亚洲VA中文字幕无码一二三区| 亚洲AV无码国产精品色午友在线| 色婷婷亚洲十月十月色天| 亚洲欧洲国产精品久久| 亚洲娇小性色xxxx| 亚洲精品女同中文字幕| 国产亚洲蜜芽精品久久| 久久精品国产精品亚洲下载| 亚洲国产精品一区二区久久hs| 亚洲天堂中文字幕| 精品亚洲成A人无码成A在线观看| 国产 亚洲 中文在线 字幕| 亚洲成a人无码亚洲成av无码| 亚洲高清成人一区二区三区| 久久亚洲AV永久无码精品| 亚洲av无码一区二区三区乱子伦| 久久久无码精品亚洲日韩京东传媒 | 亚洲视频在线视频| 亚洲人成在久久综合网站|