vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
简单来说: 对应用中组件的状态进行集中式的管理(读/写)
状态自管理应用
state: 驱动应用的数据源
view: 以声明方式将state映射到视图
actions: 响应在view上的用户输入导致的状态变化(包含n个更新状态的方法)
多组件共享状态的问题
多个视图依赖于同一状态
来自不同视图的行为需要变更同一状态
以前的解决办法
* 将数据以及操作数据的行为都定义在父组件
* 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
vuex就是用来解决这个问题的
将vuex引到项目中
下载: npm install vuex --save
将vuex引到项目中
下载: npm install vuex --save
使用vuex
store.js
import Vuex from 'vuex'
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules
})
main.js
import store from './store.js'
new Vue({
store
})
vuex的核心概念
- state
vuex管理的状态对象
它应该是唯一的
const state = {
xxx: initValue
}
- mutations
包含多个直接更新state的方法(回调函数)的对象
谁来触发: action中的commit(‘mutation名称’)
注意:只能包含同步的代码, 不能写异步代码
const mutations = {
yyy (state, data) {
// 更新state的某个属性
}
}
- actions
包含多个事件回调函数的对象
通过执行: commit()来触发mutation的调用, 间接更新state
谁来触发: 组件中: $store.dispatch(‘action名称’) // ‘zzz’
可以包含异步代码(定时器, ajax)
const actions = {
zzz ({commit, state}, data1) {
commit('yyy', data2)
}
}
- getters
包含多个计算属性(get)的对象
谁来读取: 组件中: $store.getters.xxx
const getters = {
mmm (state) {
return ...
}
}
- modules
包含多个module
一个module是一个store的配置对象
与一个组件(包含有共享数据)对应
向外暴露store对象
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
映射store
import store from './store'
new Vue({
store
})
store对象
- 所有用vuex管理的组件中都多了一个属性$store, 它就是一个store对象
- 属性:
state: 注册的state对象
getters: 注册的getters对象 - 方法:
dispatch(actionName, data)
: 分发action
mapState、mapGetters、mapMutations、mapActions 辅助函数
引入辅助函数
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
使用
computed: {
...mapState(['xxx']),
...mapGetters(['xxx'])
methods: {
...mapActions(['xxx,' 'xxx', 'xxx', 'xxx']),
...mapMutations (['xxx', 'xxx'])
}
使用常量替代 Mutation 事件类型
创建向外部暴露的常量
mutation-types.js
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
在mutations.js中的用法
import { INCREMENT, DECREMENT } from './mutation-types'
export default {
[INCREMENT] (state) { //mutation-types.js中的常量做为方法名必须使用'[]',否则不匹配,相当于'INCREMENT' (state) { ... }
state.count++
},
[DECREMENT] (state) {
state.count--
}
}
将他们拆分出来
一个简单的加减法例子
App.vue
<template>
<div>
<p>click {{count}} times, count is {{evenOrOdd}}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementIfOdd">increment if odd</button>
<button @click="incrementAsync">increment async</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count']),
...mapGetters(['evenOrOdd']),
evenOrOdd () {
return this.$store.getters.evenOrOdd
},
count () {
return this.$store.state.count
}
},
methods: {
...mapActions(['increment', 'decrement', 'incrementIfOdd', 'incrementAsync'])
}
}
</script>
<style>
</style>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App),
router,
store
})
store下index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
state,
mutations,
actions,
getters
}
)
store下state.js
export default {
count: 0
}
store下actions.js
import { INCREMENT, DECREMENT } from './mutation-types'
export default {
increment ({commit}) {
commit(INCREMENT)
},
decrement ({commit}) {
setTimeout(() => {
commit(DECREMENT)
}, 1000)
},
incrementIfOdd ({commit, state}) {
if (state.count % 2 === 1) {
commit(INCREMENT)
}
},
incrementAsync ({commit}) {
setTimeout(() => {
commit(INCREMENT)
}, 1000)
}
}
store下mutations.js
import { INCREMENT, DECREMENT } from './mutation-types'
export default {
[INCREMENT] (state) {
state.count++
},
[DECREMENT] (state) {
state.count--
}
}
store下getters.js
export default {
evenOrOdd (state) {
return state.count % 2 === 0 ? '偶数' : '奇数'
}
}
store下mutation-types.js
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
运行结果