vuex 理解與應用

第一章 初識vuex

vuex有什麼用?

好比, vue作了一個音樂app, 裏面的播放組件, 這組件應該是在全部的頁面都有用到的.
但願在全部的頁面都能控制播放器的 暫停/播放, 或者說均可以選擇是否 隨便播放/單曲循環.
這就涉及到了多組件之間的傳參,並且是很是複雜的傳參.這時候使用vuex是合適的.vue

vuex是什麼?

經過簡單的描述, 咱們大概能夠理解爲vuex是一個公共 狀態庫 , 你能夠在全部的組件裏面去使用,修改web

那這個狀態庫是由什麼組成的?

一. state: 最最基本的狀態vuex

const store = new Vuex.Store({
  state: {
    count: 0
  }
  ...
})

二. getters: 至關於計算屬性vue-cli

當咱們獲得state的值以後, 使用getters, 將這些基本的值進行組合加工, 獲得咱們須要的值

三. mutations: app

他的做用就是來改變state的值, 而且是惟一的方法

四. actions: webapp

假如你有好幾個mutation須要提交, 一個一個的寫就太傻逼了. 能夠用 actions 來封裝 mutations.

☆☆☆☆☆☆☆☆☆☆☆暫且完結☆☆☆☆☆☆☆☆☆☆☆☆☆

第二章 vuex核心概念詳解

1. state的運用

a. 最簡單的方法就是在計算屬性中返回state狀態異步

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

b. 咱們用vue-cli來製做webapp的時候函數

import store from './store'
const app = new Vue({
  el: '#app',
  // 把 store 對象提供給 「store」 選項,這能夠把 store 的實例注入全部的子組件
  store
})

// 而後就能夠在組件中
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

c. 若一個組件須要不少的state狀態的話, 上面方式就不夠簡潔了. 使用 mapState 輔助函數性能

computed: mapState({
  // 箭頭函數可以使代碼更簡練
  count: state => state.count,

  // 傳字符串參數 'count' 等同於 `state => state.count`
  countAlias: 'count',

  // 爲了可以使用 `this` 獲取局部狀態,必須使用常規函數
  countPlusLocalState (state) {
    return state.count + this.localCount
  }
})

2. getters的運用

a. 基本使用this

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

// 在組件中使用它
computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

b. mapGetters 輔助函數 簡化應用

import { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
    ...mapGetters([
      'doneTodosCount'
      // ...
      // 設置別名 ,使用對象形式:
      // doneCount: 'doneTodosCount'
    ])
  }
}

3. mutations的運用

a. mutations 下面是一個簡單的例子

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

// 調用mutations的方法
store.commit('increment')

b. 給mutations 提交額外的參數

mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit('increment', 10)

// 通常載荷應該是一個對象,這樣能夠包含多個字段而且記錄的 mutation 會更易讀
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit('increment', {amount: 10})
// 或者用對象的方式提交
store.commit({
  type: 'increment',
  amount: 10
})

c. 使用常量替代 Mutation 事件類型

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
  // ...
  mutations: {
    // 假如不用常量, 如 'some-mutations' , 可能會形成格式上的錯亂
    [SOME_MUTATION] (state) {
      // ...
    }
  }
})

d. 在組件中提交 Mutations

// 方法1
this.$store.commit('xxx')
// 方法2 使用 mapMutations 
import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment' // 映射 this.increment() 爲 this.$store.commit('increment')
    ]),
    ...mapMutations({
      add: 'increment' // 映射 this.add() 爲 this.$store.commit('increment')
    })
  }
}

□□□□□□□□□□□□□綜合實例□□□□□□□□□□□□

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    [SOME_MUTATION] (state, n) {
      state.count += n
    }
  }
})
import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      // 映射 this.increment() 爲 this.$store.commit('increment')
      increment: 'SOME_MUTATION'
    ]),
    
    // 調用上面映射的方法 而且把參數n傳進去
    this.increment(1)
  }
}

4. actions的運用

a. 前面咱們已經說過了,actions主要是來同時提交多個mutations

// mutations.js
import * as types from './mutation-types'
const mutations = {
  [types.sx](state, a){
    state.a = a    
  },
  [types.sb](state, b){
    state.b = b    
  }...
}
// actions.js
// 咱們須要同時更改state的a,b的值
import * as types from './mutation-types'
export const selectPlay = function ({commit, state}, a, b) {
  commit(types.sx, a)
  commit(types.sb, b)...
}

b. 進行異步操做 多看看 這例子寫的很好

actions: {
  checkout ({ commit, state }, products) {
    // 把當前購物車的物品備份起來
    const savedCartItems = [...state.cart.added]
    // 發出結帳請求,而後樂觀地清空購物車
    commit(types.CHECKOUT_REQUEST)
    // 購物 API 接受一個成功回調和一個失敗回調
    shop.buyProducts(
      products,
      // 成功操做
      () => commit(types.CHECKOUT_SUCCESS),
      // 失敗操做
      () => commit(types.CHECKOUT_FAILURE, savedCartItems)
    )
  }
}

c. 在組件中分發 Action

// 原始方法 如提交上面的購物車
this.$store.dispatch('checkout ')
// 使用 mapActions
import { mapActions } from 'vuex'
export default {
  // ...
  methods: {
    ...mapActions([
      'increment' // 映射 this.increment() 爲 this.$store.dispatch('increment')
    ]),
    ...mapActions({
      add: 'increment' // 映射 this.add() 爲 this.$store.dispatch('increment')
    })
  }
}

☆☆☆☆☆☆☆☆☆☆☆暫且完結☆☆☆☆☆☆☆☆☆☆☆☆☆

第三章 項目結構

圖片描述

這是vue-cli構建的一個項目, store就是存放vuex的文件夾

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'

// 插件的運用, 它能監控state的值
import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)

// 可是, 這會耗性能, 全部判斷線上線下打包模式, 從而決定是否使用
const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
  actions,
  getters,
  state,
  mutations,
  strict: debug,
  plugins: debug ? [createLogger()] : []
})
相關文章
相關標籤/搜索