vuex其實超簡單,只需3步

前言

以前幾個項目中,都多多少少碰到一些組件之間須要通訊的地方,而由於種種緣由,
event bus 的成本反而比vuex還高, 因此技術選型上選用了 vuex, 可是不知道爲何,
團隊裏的一些新人一聽到vuex,就開始退縮了, 由於vuex 很難? 真的很難嗎?
今天咱們用簡單的3步來證實一下,vuex有多簡單.vue

純屬我的經驗,不免有不正確的地方,若有發現,歡迎指正!

這是一個針對新手的入門級教程、入門級教程、入門級教程

第零步

新建一個vue項目,安裝vuex,這裏不作過多介紹,能點進來的,默認你具有這些技能 ^_^git

第一步

新建一個.js 文件,名字位置任意,按照慣例,建議在/src/store 目錄下(沒有的話本身新建一個唄)github

文件位置 /src/store/index.jsvuex

// 引入vue 和 vuex
import Vue from 'vue'
import Vuex from 'vuex'

// 這裏須要use一下,固定寫法,記住便可
Vue.use(Vuex)

// 直接導出 一個 Store 的實例
export default new Vuex.Store({
  // 相似 vue 的 data
  state: {
    name: 'oldName'
  },
  // 相似 vue 裏的 mothods(同步方法)
  mutations: {
    updateName (state) {
      state.name = 'newName'
    }
  }
})

代碼看起來稍微有那麼一點點多,不過看起來是否是很熟悉? 跟普通的 vue 沒多大差異嘛.
這一步其實就是新建一個store,可是咱們還沒在項目中使用.vue-cli

第二步

在入口文件引入上述文件, 並稍微改一下傳給 new Vue()的參數,新增的行後面有備註緩存

文件位置 /src/main.js (vue-cli自動生成的入口,若是你能不用腳手架,那麼也就不須要我說明了)app

import Vue from 'vue'
import App from './App'
import vuexStore from './store'   // 新增

new Vue({
  el: '#app',
  store:vuexStore                 // 新增
  components: { App },
  template: '<App/>'
})
Tip: import store from './store' 後面的地址,就是上面咱們新建那個文件的位置( /src/store/index.js),
由於我這裏是index.js,因此能夠省略.

第三步

以上2步,其實已經完成了vuex的基本配置,接下來就是使用了異步

文件位置 /src/main.js (一樣是vue-cli生成的app.vue,這裏爲了方便演示,我去掉多餘的代碼)模塊化

<template>
  <div>
    {{getName}}
    <button @click="changeName" value="改名">改名</button>
  </div>
</template>

<script>
export default {
  computed:{
    getName(){
      return this.$store.state.name
    }
  },
  methods:{
    changeName () {
      this.$store.commit('updateName')
    }
  }
}
</script>

這裏就是一個很普通的vue文件了,有區別的地方是這裏咱們須要用computed屬性去獲取 store 裏的 "data"函數

還有就是咱們要改變數據的話,再也不用 this.xxx = xxx 改爲 this.$store.commit('updateName')

總結

你可能會以爲,上例這樣作的意義何在,爲什麼不直接用vue的data跟methods?

上例只是爲了簡單講解如何使用vuex,因此簡化了一些流程,試想一下,若是你有這樣一個頁面:
一共嵌套了10層組件(即子組件裏面還有子子組件,子子組件下面還有子子子組件,以此類推10層)
而後最後一層組件一個數據改變了,要通知第一層組件的時候,咱們只需在最底層組件裏this.$store.commit(),
而後再最外層組件上用computed屬性獲取對應的值,就能作到實時更新.無需層層$emit上去.

最後

原本想在最後再擴展一下getter,action+dispatch,模塊化等等,不過爲了對得起這個標題,
只好放在 下一篇:vuex其實超簡單,喝完這3步,還有3步

vuex其實超簡單,喝完這3步,還有3步

上一篇 vuex其實超簡單,只需3步
簡單介紹了vuex的3步入門,不過爲了初學者容易消化,我削減了不少內容,這一節,就是把少掉的內容補上,
若是你沒看過上篇,請戳連接過去先看一下再回來,不然,你會以爲本文摸不着頭腦.

純屬我的經驗,不免有不正確的地方,若有發現,歡迎指正!

仍是同樣,本文針對初學者.

1、 Getter

咱們先回憶一下上一篇的代碼

computed:{
    getName(){
      return this.$store.state.name
    }
}

這裏假設如今邏輯有變,咱們最終指望獲得的數據(getName),是基於 this.$store.state.name
上通過複雜計算得來的,恰好這個getName要在好多個地方使用,那麼咱們就得複製好幾份.

vuex 給咱們提供了 getter,請看代碼 (文件位置 /src/store/index.js)

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

Vue.use(Vuex)

export default new Vuex.Store({
  // 相似 vue 的 data
  state: {
    name: 'oldName'
  },
  // 相似 vue 的 computed -----------------如下5行爲新增
  getters:{
    getReverseName: state => {
        return state.name.split('').reverse().join('')
    }
  },
  // 相似 vue 裏的 mothods(同步方法)
  mutations: {
    updateName (state) {
      state.name = 'newName'
    }
  }
})

而後咱們能夠這樣用 文件位置 /src/main.js

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

事實上, getter 不止單單起到封裝的做用,它還跟vue的computed屬性同樣,會緩存結果數據,
只有當依賴改變的時候,纔要從新計算.

2、 actions和$dispatch

細心的你,必定發現我以前代碼裏 mutations 頭上的註釋了 相似 vue 裏的 mothods(同步方法)

爲何要在 methods 後面備註是同步方法呢? mutation只能是同步的函數,只能是同步的函數,只能是同步的函數!!
請看vuex的解釋:

如今想象,咱們正在 debug 一個 app 而且觀察 devtool 中的 mutation 日誌。每一條 mutation 被記錄,
devtools 都須要捕捉到前一狀態和後一狀態的快照。然而,在上面的例子中 mutation 中的異步函數中的回調讓這不
可能完成:由於當 mutation 觸發的時候,回調函數尚未被調用,devtools 不知道何時回調函數實際上被調
用——實質上任何在回調函數中進行的狀態的改變都是不可追蹤的。

那麼若是咱們想觸發一個異步的操做呢? 答案是: action + $dispatch, 咱們繼續修改store/index.js下面的代碼

文件位置 /src/store/index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  // 相似 vue 的 data
  state: {
    name: 'oldName'
  },
  // 相似 vue 的 computed
  getters:{
    getReverseName: state => {
        return state.name.split('').reverse().join('')
    }
  },
  // 相似 vue 裏的 mothods(同步方法)
  mutations: {
    updateName (state) {
      state.name = 'newName'
    }
  },
  // 相似 vue 裏的 mothods(異步方法) -------- 如下7行爲新增
  actions: {
    updateNameAsync ({ commit }) {
      setTimeout(() => {
        commit('updateName')
      }, 1000)
    }
  }
})

而後咱們能夠再咱們的vue頁面裏面這樣使用

methods: {
    rename () {
        this.$store.dispatch('updateNameAsync')
    }
}

3、 Module 模塊化

當項目愈來愈大的時候,單個 store 文件,確定不是咱們想要的, 因此就有了模塊化.
假設 src/store 目錄下有這2個文件

moduleA.js

export default {
    state: { ... },
    getters: { ... },
    mutations: { ... },
    actions: { ... }
}

moduleB.js

export default {
    state: { ... },
    getters: { ... },
    mutations: { ... },
    actions: { ... }
}

那麼咱們能夠把 index.js 改爲這樣

import moduleA from './moduleA'
import moduleB from './moduleB'

export default new Vuex.Store({
    modules: {
        moduleA,
        moduleB
    }
})

這樣咱們就能夠很輕鬆的把一個store拆分紅多個.

4、 總結

  1. actions 的參數是 store 對象,而 getters 和 mutations 的參數是 state .
  2. actions 和 mutations 還能夠傳第二個參數,具體看vuex官方文檔
  3. getters/mutations/actions 都有對應的map,如: mapGetters , 具體看vuex官方文檔
  4. 模塊內部若是怕有命名衝突的話,可使用命名空間, 具體看vuex官方文檔
  5. vuex 其實跟 vue 很是像,有data(state),methods(mutations,actions),computed(getters),還能模塊化.
相關文章
相關標籤/搜索