Vue中的Vuex(一)

小編在項(xiàng)目中,經(jīng)常會使用到Vuex,其實(shí)小編自己只是知道Vuex是為了解決什么痛點(diǎn),但是具體這個東西是怎么回事,小編自己有點(diǎn)迷迷糊糊,昨天小編痛下決心,認(rèn)認(rèn)真真的把Vuex的官網(wǎng)(https://vuex.vuejs.org/zh/)讀了一遍,收獲還是很多的,特地拿出來與大家分享,也希望能在大家今后的面試中,增加一些籌碼和信心。大家還可以關(guān)注我的微信公眾號,蝸牛全棧。

Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。Vuex 也集成到 Vue 的官方調(diào)試工具 devtools extension (opens new window),提供了諸如零配置的 time-travel 調(diào)試、狀態(tài)快照導(dǎo)入導(dǎo)出等高級調(diào)試功能。

這個是官網(wǎng)對Vuex的描述,小編之前的項(xiàng)目經(jīng)常會用Vuex存儲用戶信息,比如當(dāng)前用戶的id,用戶所在部門,頭像等等,這些信息都是通過數(shù)據(jù)接口獲得的數(shù)據(jù),其實(shí)存儲在用戶瀏覽器的Cookie和LocalStorage都是可以的,用的時候,再從本地的相應(yīng)位置獲取,用戶退出的時候,清空對應(yīng)的信息,同樣也可以較少多次請求,并且也解決了多個組件共享數(shù)據(jù)的痛點(diǎn)。但是很多成型的admin都在使用Vuex,同樣對于另一個前端框架大名鼎鼎的React也在用類似的方案(Redux),面臨前端日新月異的發(fā)展,學(xué)會使用Vuex就顯得更為重要。
Vuex主要分為四個部分,State、Getters、Mutations、Actions,小編下面就結(jié)合實(shí)例一一的解釋一下。在正式進(jìn)入Vuex的世界之前,我們需要先安裝Vuex

npm install vuex --save

在我們使用腳手架構(gòu)建項(xiàng)目的時候,需要顯示的在項(xiàng)目入口文件main.js中引入Vuex,并通過Vue.use()來安裝

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

Vuex依賴Promise,還不了解Promise的,可以查看小編之前的文章《ES6中的Promise》一、State

Vuex核心就是一個store,store中的數(shù)據(jù)都存放在State中,可以將State理解成一個大倉庫,大倉庫中存著我們需要共享的數(shù)據(jù)。在組件中,可以通過this.$store獲取State中的數(shù)據(jù),為了保證數(shù)據(jù)的一致性,State中數(shù)據(jù)是不允許直接修改的,改變 store 中的狀態(tài)的唯一途徑就是顯式地提交 (commit)

下面我們來創(chuàng)建一個最簡單的store

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

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

現(xiàn)在,你可以通過 store.state 來獲取狀態(tài)對象,以及通過 store.commit 方法觸發(fā)狀態(tài)變更:

store.commit('increment')
console.log(store.state.count) // -> 1

最后,我們需要把store注入到創(chuàng)建的Vue實(shí)例中,就像這樣

new Vue({
  el: '#app',
  store // 這個位置因?yàn)閷ο蟮膋ey和value一樣,使用es6語法可以簡寫成這樣
})

那么我們?nèi)绾卧?Vue 組件中展示狀態(tài)呢?由于 Vuex 的狀態(tài)存儲是響應(yīng)式的,從 store 實(shí)例中讀取狀態(tài)最簡單的方法就是在計(jì)算屬性(computed)中返回某個狀態(tài):

// 創(chuàng)建一個 Counter 組件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

我們還可以這樣

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

實(shí)際上以上內(nèi)容,我們就可以正常讀取store中的值了,官方還提供我們一種更簡便的方式:mapState

// 在單獨(dú)構(gòu)建的版本中輔助函數(shù)為 Vuex.mapState
import { mapState } from 'vuex'

export default {
  // ...
  computed: mapState({
    // 箭頭函數(shù)可使代碼更簡練
    count: state => state.count,

    // 傳字符串參數(shù) 'count' 等同于 `state => state.count`
    countAlias: 'count',

    // 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù)
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })
}

同樣,類似es6對象的擴(kuò)展中,key和value值一樣的時候,可以簡寫,同樣,mapState也提供類似的使用方法

computed: mapState([
  // 映射 this.count 為 store.state.count
  'count'
])

在es6出現(xiàn)了擴(kuò)展運(yùn)算符的之后,我們可以更加簡便的寫法,也是小編在github上最常見的方式

computed: {
  localComputed () { /* ... */ },
  // 使用對象展開運(yùn)算符將此對象混入到外部對象中
  ...mapState({
    // ...
  })
}

二、Getters
小編個人感覺這個和一些后端語言有類似的地方,比如我們想獲取一個store中數(shù)組的長度,沒有Getters的時候,我們需要在計(jì)算屬性(computed)這么寫

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

這個例子還是相對比較簡單的,要是遇上更復(fù)雜的情況,在獲取到State中數(shù)據(jù)之后,還要各種處理,想想一坨坨的js代碼,頭就大,還好,Vuex提供了Getters。我們可以這樣寫

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: { // 通過Getters將doneTodos暴露出去
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

在獲取的時候,這樣就可以獲取到內(nèi)容了,就像這樣

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

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

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

store.getters.doneTodosCount // -> 1

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

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

同樣,我們還可以讓Getters結(jié)合es6箭頭函數(shù)返回一個函數(shù),在實(shí)際使用頁面中傳遞參數(shù)來獲取不同的結(jié)果,就類似原生js的過濾器filter一樣

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

和上面mapState類似,Getters也提供了類似的方式

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用對象展開運(yùn)算符將 getter 混入 computed 對象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

如果你想將一個 getter 屬性另取一個名字,使用對象形式:

...mapGetters({
  // 把 `this.doneCount` 映射為 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})

參考文獻(xiàn):https://vuex.vuejs.org/zh/

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

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

  • 為什么要用vuex? 首先,需要清楚為什么要用vuex,當(dāng)我們的應(yīng)用遇到**多個組件共享狀態(tài)**時 -多層級父子組...
    kino2046閱讀 543評論 0 1
  • vuex是什么鬼? 如果你用過redux就能很快的理解vuex是個什么鬼東西了。他是vuejs用來管理狀態(tài)的插件。...
    麥子_FE閱讀 7,019評論 3 37
  • 本文僅為 vuex 使用方法,如有不對的地方,歡迎指正。項(xiàng)目使用可以直接拉到后面 vuex 實(shí)際項(xiàng)目中使用部分。 ...
    睡神瘋子閱讀 2,583評論 0 2
  • 目錄 1 引入 vuex 2 state 訪問狀態(tài)對象 3 mutations(同步) 模板獲取方法 4 gett...
    林ze宏閱讀 394評論 0 0
  • 理解vue 引用一段官方的原話: Vue.js(讀音 /vju?/,類似于 view) 是一套構(gòu)建用戶界面的漸進(jìn)式...
    綽號陸拾柒閱讀 2,449評論 3 6

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