好比, vue作了一個音樂app, 裏面的播放組件, 這組件應該是在全部的頁面都有用到的.
但願在全部的頁面都能控制播放器的 暫停/播放
, 或者說均可以選擇是否 隨便播放/單曲循環
.
這就涉及到了多組件之間的傳參,並且是很是複雜的傳參.這時候使用vuex是合適的.vue
經過簡單的描述, 咱們大概能夠理解爲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.
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 } })
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' ]) } }
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) } }
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()] : [] })