vue+element UI 學習總結筆記(十七)_vuex在項目中的應用

what is vuex?

vuex is a state management pattern + library for Vue.js applications

vuex

參考(抄襲):vuex的簡單使用

作用:

vuex解決了組件之間共享同一狀態的麻煩問題。當我們的應用遇到多個組件共享狀態時,會需要:

  1. 多個組件依賴於同一狀態。傳參的方法對於多層嵌套的組件將會非常繁瑣,並且對於兄弟組件間的狀態傳遞無能爲力。這需要你去學習下,vue編碼中多個組件之間的通訊的做法。

  2. 來自不同組件的行爲需要變更同一狀態。我們經常會採用父子組件直接引用或者通過事件來變更和同步狀態的多份拷貝。

以上的這些模式非常脆弱,通常會導致無法維護的代碼。來自官網的一句話:Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態。這裏的關鍵在集中式存儲管理。這意味着本來需要共享狀態的更新是需要組件之間通訊的,而現在有了vuex,就組件就都和store通訊了。問題就自然解決了。

這就是爲什麼官網再次會提到Vuex構建大型應用的價值。如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗餘的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex

什麼可以用:

(需要牢記的一張圖) 

  • state (類似存儲全局變量的數據)
    getters (提供用來獲取state數據的方法)
    actions (提供跟後臺接口打交道的方法,並調用mutations提供的方法)
    mutations (提供存儲設置state數據的方法)

我理解action中的方法,類似事件,只是在vuex中註冊,需要通過dispatch觸發這個方法

mutation中的方法,類似事件,只是在vuex中註冊,需要通過commit觸發這個方法

ps:(官網上說的幾個概念)

It is a self-contained app with the following parts:

  • The state, the source of truth that drives our app;
  • The view, a declarative mapping of the state;
  • The actions, the possible ways the state could change in reaction to user inputs from the view.

This is an simple representation of the concept of "one-way data flow":

However, the simplicity quickly breaks down when we have multiple components that share a common state:

  • Multiple views may depend on the same piece of state.
  • Actions from different views may need to mutate the same piece of state.

Vuex 的內臟由五部分組成:State、Getter、Mutation、Action 和 Module。

項目中引入vuex,見下圖:關鍵字:Vue.use(Vuex)

store可以分模塊管理,下面是我們store總的入口文件:

在入口文件中,引入了多個分模塊store。

 以store 用到的user.js爲例:

import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'

const user = {
  state: {
    token: getToken(),
    name: '',
    avatar: '',
    roles: [],
    allUserInfo: {},
    userInfo: {},
    loginInfo: {},
    isShow: '0'// 單價金額是否顯示 默認0不顯示
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token = token
    },
    SET_NAME: (state, name) => {
      state.name = name
    },
    ......
  },

  actions: {
    // 登錄
    Login({ commit }, userInfo) {
	......
    },

    // 獲取用戶信息
    GetInfo({ commit, state }) {
 	......      
    },

    // 登出
    LogOut({ commit, state }) {
    ...... 
    },

    // 前端 登出
    FedLogOut({ commit }) {
	......
    },
    SetUserInfo({ commit }, userInfo) {
      commit('SET_USERINFO', userInfo)
    },
    SetAllUserInfo({ commit }, userInfo) {
      commit('SET_All_USERINFO', userInfo)
    }
  }
}

export default user

action 中的方法: 

Action 內函數接受一個 context 參數,注意,這個參數可不一般,它與 store 實例有着相同的方法和屬性,但是他們並不是同一個實例。

所以在在action方法中可以使用 context.commit 來提交一個 mutation,或者通過 context.statecontext.getters 來獲取 state 和 getters。

當然,爲了代碼簡化,我們可以使用 ES2015 的 參數解構 來直接展開,便於 commitstate 等多次調用。

例如:

  actions: {
    // 登錄
    Login({ commit }, userInfo) {
       .......
    },

    // 獲取用戶信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo(state.token).then(response => {
          const data = response.data
          if (data.roles && data.roles.length > 0) { // 驗證返回的roles是否是一個非空數組
            // 把roles給存儲下來了。

            commit('SET_loginInfo', data)
            commit('SET_ROLES', data.roles)
            // var json = data.menutree
            // json.forEach(item => {
            //   delete item.id
            // })
          } else {
            reject('getInfo: roles must be a non-null array !')
          }
          commit('SET_NAME', data.name)
          commit('SET_AVATAR', data.avatar)
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
......
}

這裏{ commit, state } 就是參數結構,否則,你就得傳遞參數context, 其寫法變爲:

  actions: {
    // 登錄
    Login(context, userInfo) {
       .......
    },

    // 獲取用戶信息
    GetInfo(context) {
      return new Promise((resolve, reject) => {
        getInfo(context.state.token).then(response => {
          const data = response.data
          if (data.roles && data.roles.length > 0) { // 驗證返回的roles是否是一個非空數組
            // 把roles給存儲下來了。
            //多了context!!!!!!
            context.commit('SET_loginInfo', data)
            context.commit('SET_ROLES', data.roles)
            // var json = data.menutree
            // json.forEach(item => {
            //   delete item.id
            // })
          } else {
            reject('getInfo: roles must be a non-null array !')
          }
          commit('SET_NAME', data.name)
          commit('SET_AVATAR', data.avatar)
          resolve(response)
        }).catch(error => {
          reject(error)
        })
      })
    },
......
}

調用方式:我們在守護路由中調用了store的GetInfo方法: 


        store.dispatch('GetInfo').then(res => { // 拉取用戶信息
           .......
        }).catch((err) => {
		   .......
        })

...mapstate

從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態,當狀態有n個時候,那你需要寫n個計算屬性。vuex提供語法糖...mapsate,讓你少寫幾行代碼,...在此可以理解爲擴展函數吧?。

ps:Vuex教程全集 - 白話篇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章