vuex基礎(chǔ)總結(jié)

vuex是什么?

Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化。也是一種組件間通信的方式。


Snipaste_2021-08-10_10-22-21.png

上面的例子只是一個簡單的組件間通信的例子,在實際項目中,組件間的通信往往比這要復雜的很多,所以說當我們的應用遇到多個組件共享狀態(tài)時,單向數(shù)據(jù)流的簡潔性很容易被破壞
而vuex就是將所有狀態(tài)集中管理起來,更加方便的實現(xiàn)組件間的通信,以往要實現(xiàn)數(shù)據(jù)的傳遞需要一步一步的向上傳遞,有了vuex,所有組件都可以向vuex中存數(shù)據(jù),也可以取數(shù)據(jù)


Snipaste_2021-08-10_10-28-39.png

應用vuex的好處

  • 能夠集中管理共享的數(shù)據(jù),易于開發(fā)和后期的維護
  • 高效的實現(xiàn)組件之間的數(shù)據(jù)共享,提高開發(fā)效率
  • 存在vuex的數(shù)據(jù)也是響應式的,能夠?qū)崟r保持數(shù)據(jù)與頁面的同步

應用場景

多個組件共享數(shù)據(jù)或者是跨組件傳遞數(shù)據(jù)時

vuex基本使用

  • 安裝
npm i vuex
  • 導入vuex
import Vuex from 'vuex'
Vue.use(Vuex)
  • 創(chuàng)建store對象
const store = new Vuex.Store({
  state: {
      // 存放全局共享的數(shù)據(jù)
  },
  actions: {},
  mutatiions: {},
  getters: {}
})
  • 全局掛載store到vue上
new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app')

然后在組件中就可以通過this.$store訪問到vuex了

vuex核心概念

一、state

state作為唯一的數(shù)據(jù)源,所有的共享數(shù)據(jù)都存放在state中,如:

const store = new Vuex.Store({
  state: {
      count: 0
  }
})
  • 組件訪問state數(shù)據(jù)的方式
    1. 通過已經(jīng)掛載到vue實例上的store對象
     this.$store.state.count
    
    2.mapState輔助函數(shù),當需要訪問的狀態(tài)有多個時,上面的方式就略顯麻煩,代碼冗余,vuex提供了mapState函數(shù)解決這個問題
    在組件中先從vuex中導入mapState函數(shù)
    import {mapState} from "vuex"
    
    通過mapstate函數(shù),和展開運算符將當前組件所需要的全局數(shù)據(jù)映射成當前組件的computed計算屬性,函數(shù)傳遞一個數(shù)組,這種最常用,你想要什么數(shù)據(jù),就傳入該數(shù)據(jù)的名稱,這個名稱也將作為該組件的一個計算屬性使用
    computed: {
      ...mapState(['count'])
    }
    // 使用展開運算符在這里必須用{}包起來
    // 如果當前組件沒有私有的計算屬性,可以直接簡寫成
    computed: mapState(['count'])
    
    
    Snipaste_2021-08-10_11-38-20.png

    另一種方法就是傳入配置對象

    // 如果當前組件沒有私有的計算屬性,可以直接簡寫成
    computed: mapState({})
    // 有私有的計算屬性,不能簡寫
    computed: {
      ...mapState({
          // 函數(shù)方法有一個參數(shù)state,就是數(shù)據(jù)源
          aaa(名字自定義): state => state.count
          // 簡寫
          aaa: 'count' // 傳字符串的方式等同于state => state.count
          // 若要訪問組件的this,就得寫成普通函數(shù)
          aaa(state){
            // 必須return
            return this.num + state.count
          }
      })
    }
    

二、mutations

vuex不允許在組件中修改state中的狀態(tài),如果想要修改state的數(shù)據(jù),唯一的方法就是通過mutations修改,其實在組件中是可以直接修改的,但是這樣通過mutations修改的方式,可以更加集中的監(jiān)控所有數(shù)據(jù)的變化。
在mutations中定義一些修改state數(shù)據(jù)的方法,方法第一個參數(shù)就是state對象

mutations: {
  add(state){
    state.count ++
  }
}

(1)觸發(fā)mutation的方法

  • 通過store對象
this.$store.commit('add')
Snipaste_2021-08-10_13-13-41.png
Snipaste_2021-08-10_13-15-17.png
  • mapMutations映射
    組件中導入mapMutations函數(shù)
import {mapMutations} from 'vuex'

這次是在組件的methods中,將mutation映射成methods的方法

methods: {
  ...mapMustations(['add'])
}
Snipaste_2021-08-10_13-53-31.png

(2)mutation傳值(官網(wǎng)將傳遞的值稱為載荷)
對于mutaion而言,方法接受的第一個參數(shù)始終是自身的state,第二個才是傳遞過來的參數(shù),這個參數(shù)一般是一個對象,因為對象可以攜帶更多的數(shù)據(jù)。當然只有一條數(shù)據(jù)可以只傳遞這條數(shù)據(jù)

mutations: {
  add(state, param){
    state.count += param.xxx
  }
}
Snipaste_2021-08-10_13-33-16.png

還可以寫成一種對象的方式

this.$store.commit({
  type: add,
  step: 20
});

// mutation的寫法不變

mapMutations傳值


Snipaste_2021-08-10_17-48-19.png

(3)注意

  • 一般我們會將mutation的名字寫成是全大寫和“_”,如
mutations: {
  SET_TOKEN(state){},
  RECEIVE_CATE_LIST(state){}.
  ...
}
  • 方法中不能執(zhí)行異步操作,也不能執(zhí)行if語句

Vuex中所有的狀態(tài)更新的唯一途徑都是mutation,異步操作通過 Action 來提交 mutation實現(xiàn),這樣使得我們可以方便地跟蹤每一個狀態(tài)的變化,從而讓我們能夠?qū)崿F(xiàn)一些工具幫助我們更好地了解我們的應用。
每個mutation執(zhí)行完成后都會對應到一個新的狀態(tài)變更,這樣devtools就可以打個快照存下來,然后就可以實現(xiàn) time-travel 了。如果mutation支持異步操作,就沒有辦法知道狀態(tài)是何時更新的,無法很好的進行狀態(tài)的追蹤,給調(diào)試帶來困難。
引自「水墨-青花」:https://blog.csdn.net/lovemyself196221/article/details/105488288

  • 大多數(shù)情況下也不是在組件中觸發(fā),而是通過actions中的方法觸發(fā)mutation

三、actions

actions和mutations類似,不同的是,actions是提交mutation修改共享數(shù)據(jù),不是直接改變共享數(shù)據(jù)的,只有通過mutation才能修改state中的函數(shù);actions中可以執(zhí)行異步操作。actions中的每一個方法的第一個參數(shù)默認使context,是與 store 實例具有相同方法和屬性的對象(context !== store對象)。而在組件中執(zhí)行actions方法的方式就是:this.$store.dispatch('方法名')
比如定義一個定時器異步的使count自增

actions: {
  async asyncIncrement(context){
    console.log(context)
  }
}
Snipaste_2021-08-10_18-33-26.png

而提交mutation的方法是commit,利用解構(gòu)賦值將commit結(jié)構(gòu)出來,提交mutation修改state的值


Snipaste_2021-08-10_18-37-39.png
  • 分發(fā)actions
    說白了就是觸發(fā)actions中的方法

    1. this.$store.dispatch("xxx")

    2.mapActions,映射在組件的methods中

     methods: {
        ...mapActions(['asyncIncrement']) // 將asyncIncrement映射成methods中的一個方法
     }
    
     methods: {
        // 若要自定義方法名
        ...mapActions({
          newMethodName(){
            this.$store.dispatch("asyncIncrement");
          }
    
           //或者
           newMethodName:  "asyncIncrement"
        }) 
     }
    
  • 傳遞載荷(參數(shù))
    1.dispatch

     this.$store.dispatch('xxx', params)
     // 對象形式
     this.$store.dispatch({
       type: asyncIncrement,
       params
     })
    
    Snipaste_2021-08-10_19-47-17.png

    2.mapActions


    Snipaste_2021-08-10_19-49-43.png

四、getters

有時候我們需要從 store 中的 state 中派生出一些狀態(tài),例如對列表進行過濾等,其實也可以理解為是類似vue的計算屬性,函數(shù)接受一個參數(shù)state,也就是數(shù)據(jù)源,數(shù)據(jù)也是響應式的,state數(shù)據(jù)變化。getters里面的數(shù)據(jù)也會隨之變化,不會修改state中的數(shù)據(jù),第二個參數(shù)是getters,通過這個屬性我們就可以訪問到其他的getter了

  • 定義getter
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    nameList: [
      {
        title: "標題一",
        id: 1
      },{
        title: "標題二",
        id: 2
      },{
        title: "標題三",
        id: 3
      }
    ]
  },

  getters: {
    numArr: (state, getters) => {
      console.log(getters.testGetters) // {a: 2}
      return state.nameList.filter((item) => {
        return item.num > 11
      })
    },

    testGetters: () {
      return {a: 2}
    }
  }
})

組件中訪問getters中的屬性
其實和state差不多,就不多說了

  • this.$store.getters.getterName
this.$store.getters.numArr
  • mapGetters
import { mapGetters } from "vuex";

// 同state一樣,將getters中的getter映射成組件的computed的計算屬性
export default {
  computed: {
    ...mapGetters(['numArr'])
    // 重命名
    ...mapGetters({
      newName: 'numArr'
    })
  },
};

下一節(jié):vuex模塊化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對于小型應用來說,完全沒用必要引入狀態(tài)管理,因為這會帶來更多的開發(fā)成本。 對于組件化開發(fā)來講,大型應用的狀態(tài)往往跨...
    涼城十月閱讀 621評論 0 0
  • 1 vuex簡介 vuex 是 Vue 配套的 公共數(shù)據(jù)管理工具,它可以把一些共享數(shù)據(jù),保存到 vuex 中,方便...
    上善若淚閱讀 329評論 0 1
  • Vue之vuex狀態(tài)管理 Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。 這個Vuex包含以下幾...
    差一點沒吃西瓜閱讀 398評論 0 2
  • 1.vuex基礎(chǔ) 1.1 vuex概述 1 問題 之前共享數(shù)據(jù),是通過以上方式以上方式,只適用于小范圍內(nèi)傳遞數(shù)據(jù) ...
    新苡米閱讀 1,041評論 2 16
  • 一、State Vuex 使用單一狀態(tài)樹,用一個對象就包含了全部的應用層級狀態(tài)。至此它便作為一個“唯一數(shù)據(jù)源 (S...
    Sun____閱讀 295評論 0 1

友情鏈接更多精彩內(nèi)容