vuex介绍
// main.js引入
import store from './store'
new Vue({
el: '#app',
store
})
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
1、在 Vue 组件中访问 this.$store.state.count
2、由于 Vuex 的状态存储是响应式的,Vue 组件中 从 store 实例中读取状态最好的方法就是在计算属性中。
3、在 Vue 组件中访问:mapState
辅助函数帮助我们生成计算属性,获取数据
import { mapState } from 'vuex'
export default {
//1、 在单独构建的版本中辅助函数为 Vuex.mapState
computed: mapState({
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
// 2、当映射的计算属性的名称与 state 的子节点名称相同时
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
}
4、更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,组件里可通过commit()去调用且可传参。
//1、你不能直接调用一个 mutation handler
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
//2、你需要以相应的 type 调用 store.commit 方法;最好传入一个对象
store.commit('increment', {amount: 10})
//3、或者是直接使用包含 type 属性的对象
store.commit({
type: 'increment',
amount: 10
})
5、使用常量替代 mutation 事件类型、mutation 必须是同步函数
mutations: {
INCRE_MRNT (state, payload) {
state.count += payload.amount
}
}
6、你可以在组件中使用 this.$store.commit('xxx')
提交 mutation,
或者使用 mapMutations
辅助函数将组件中的 methods 映射为 store.commit
调用(需要在根节点注入 store
)
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
// 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
'incrementBy'
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
7、Action
-
Action 提交的是 mutation,而不是直接变更状态。
-
Action 可以包含任意异步操作。
const store = new Vuex.Store({ state: { count: 0 }, mutations: { INCRE_MRNT (state) { state.count++ } }, actions: { //Action接收store实例具有相同方法和属性的context对象,因此你可以调用 `context.commit` increment (context) { context.commit('INCRE_MRNT') } //es6 简化写法 increment ({ commit }) { commit('increment') } } })
8、Action 在组件里可通过 store.dispatch
方法触发:
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('INCRE_MRNT')
}, 1000)
}
}
/*在其他组件里可以运用store.dispatch触发该方法*/
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
9、从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: (state, getters) => {
return state.todos.filter(todo => todo.done)
}
}
})
Getter 会暴露为 store.getters
对象,你可以以属性的形式 【访问】 这些值:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
10、module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: