# VueX 学习
# 基本概述
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
# 单向数据流理念
典型通讯方式:父子组件通讯、兄弟组件通讯
state通过声明的方式将数据映射到view中,view拿到数据进行渲染,用户在view层更新数据,view将 更改的数据传递到actions中,actions拿到数据在去状态中更新state。
# 核心概念
在vuex中store是整个应用的核心,“store”属于容器的存在,包含着大部分state状态,为控制store的 途径唯一性,改变状态只能通过mutation来改变。
# State
1、获取vuex中state状态值
this.$store.state.值名称
2、mapState 辅助函数
当一个组件需要获取多个状态时,mapState可自动生成计算属性
import {mapState} from 'vuex'
export default {
name: 'home',
computed: mapState(['nickname','age','gender'])
}
上面代码相当于
nickname(){return this.$store.state.nickname}
age(){return this.$store.state.age}
gender(){return this.$store.state.gender}
如果在计算属性(computed)中需要自定义一个计算属性,将使用下面的方法
computed: { //computed是不能传参数的
value(){
return this.val/7
},
// 使用ES6的扩展运算符
...mapState(['nickname','age','gender'])
}
# Getter
可以将其看作store的计算属性,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
在getter中有两个参数,第一个参数代表当前状态中的state,第二个参数代表getters本身。
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)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
使用方法的方式访问getters
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
mapGetters辅助函数
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
如果你需要在mapGetters中更改属性名称,需要使用对象的形式
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
# mutation
基本定义
在vuex中mutation类似于一个事件,它存在一个事件类型和一个回调函数,回调函数就是我们实际修改state的地方。
在mutation中我们不能直接调取回调函数,必须先注册事件。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
// increment=事件类型(注册事件)
increment (state) {
// 变更状态
// 注意在所有的mutation中,更改的状态都必须在state先声明才能使用。
state.count++
}
}
})
载荷
在mutation中如果你想使用store.commit传入额外的参数,就要使用载荷(payload)。
但是在载荷中我们一般传递的都是对象,因为对象的表意更加的明确。
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {
amount: 10
})
既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
1、在 store 中初始化好所有所需属性。
2、当需要在对象上添加新属性时,使用 Vue.set(obj, 'newProp', 123),
3、或者利用对象展开运算符我们可以这样写:
state.obj = { ...state.obj, newProp: 123 }