Vuex简介:
由于使用propes传递数据太麻烦,所以使用vuex进行状态管理。
不能直接修改vuex中的数据,只能调用方法修改数据数据。
vuex的核心:store(仓库)
vuex是响应式的
核心四个点:
-
state
在项目中引入store
在computed中调用state数据:
conputed:{
count(){
return store.state.count
}
}
在methods中调用方法mutations方法:
methods:{
increment(){
store.commit('increment')
}
}
mapState
当一个组件需要多个状态时,帮助生产计算属性得到state中的数据。
当映射的计算属性的名称与state的子节点名称相同时,可以直接传递一个字符串数组。
computed:mapState(['count','color']}
这样一来,count就是state中的count,color就是state中的color
对象展开运算符,当computed中还有其他属性时,可以使用对象展开运算符将mapState返回的对象合并到computed中。
-
getter
从store中的state中派生出一些状态,如doneTodosCount,
当多个组件都需要用到这个方法(属性)时,可以将其放入store里的getters中,使其成为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)
}
}
})
此时可以使用store.getters.doneTodos 来获取数据。
getters也可以接受其他getters作为参数。
mapGetters辅助函数,和mapState类似,如果想要将getter属性另取一个名字,使用对象形式:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
//另取名字,使用对象形式
mapGetters({
// 映射 `this.doneCount` 为 `store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
-
mutation
非常类似于事件,每一个都有字符串的事件类型(type)和一个回掉函数(handler),这个回掉函数就是实际进行状态更改的地方,并且会接受state作为第一个参数。
如state例子中的mutation,
在调用mutation时,不可以直接调用handler(回掉函数)只能通过commit方法传入事件类型的字符串进行mutation的调用。
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
store.commit('increment')
提交载荷(payload)
commit可以接受额外的参数,多数情况下,载荷是个对象,其代码风格如下:
store.commit({
type: 'increment',
amount: 10
})
在大型项目中,通常将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({
state: { ... },
mutations: {
// 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
mutation必须是同步函数,没有什么异步请求
组件中提交mutation,mapMutation
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
与mapGtter类似。
mutation类似于vue实例中的methods,但是调用方法不同。
getters类似于vue实例中的computed。
-
Action
类似于mutation,不同在于:
- action提交的是mutation,而不是直接改变状态
- action可以包含任意异步操作
action函数接受一个与store实例具有相同方法和属性的context对象,使用context.commit提交一个mutation
或者使用context.state \ context.getters来获取state和getters。
context不是store实例本身。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
-###Module
当一个应用十分复杂时,将所有状态放在一个单一状态树时会使得store变得十分臃肿,所以可以使用module进行分割。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
每个模块的第一个参数是其自身的state。