好比, 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()] : [] })