Vuex的使用
Vuex的使用
1.什么是状态管理模式?
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,
并以相应的规则保证状态以一种可预测的方式发生变化。Vuex也集成到Vue的官方调式工具devtools extension,
提供了诸如零配置的time-travel调式、状态快照导入导出等高级调式功能。
2.组成部分
-
state,驱动应用的数据源;
-
view,以声明方式将 state 映射到视图;
-
actions,响应在 view 上的用户输入导致的状态变化。
以下是一个表示“单向数据流”理念的简单示意:
3.什么情况应该使用Vuex?
Vuex可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用Vuex可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好
不要使用Vuex.一个简单的store模式就足够您所需。但是您需要构建一个中大型单页应用,您很可能会考虑如何更好地
在组件外部管理状态,Vuex将会成为自然而然的选择。
4.安装并使用vuex
4.1 安装依赖
npm install vuex --save
4.2 在main.js中注入vuex
import Vuex from 'vuex' Vue.use(Vuex)
4.3 在src目录下,创建store文件夹,并新建index.js,内容如下
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex) export default new Vuex.Store({ state:{ hello:12 }, mutations:{ increment:state => state.hello++, decrement:state => state.hello-- }, getters:{ change: state => { return "结果是"+state.hello } } })
4.4 在main.js导入store
import store from "@/store/store"; new Vue({ render: h => h(App), Router, store }).$mount('#app')
4.5 新建hello.vue,内容如下
<template> <div> {{count}} <button @click="add">增加</button> <button @click="minus">减1</button> <p>{{desc}}</p> </div> </template> <script> export default { name: "Hello", computed:{ count(){ return this.$store.state.hello; }, desc(){ return this.$store.getters.change; } }, methods:{ add(){ this.$store.commit('increment'); }, minus(){ this.$store.commit('decrement'); } } } </script> <style scoped> </style>
5. Getter
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数
组件:
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
-------------------------------------------------------------------------------
index.js:
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)
}
}
})
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
6.Mutations
6.1基本介绍
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment
的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type 调用 store.commit 方法:
store.commit('increment')
6.2 提交负载
你可以向 store.commit
传入额外的参数,即 mutation 的 载荷(payload):
// ...
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
})
6.3 使用常量代替Mutation事件类型
使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 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
}
}
})
7. actions
在mutation中我们讲到,mutation是存放处理数据的方法集合,我们使用的时候需要commit。但是commit是同步函数,而且只能是
同步执行。那我们想异步操作怎么办?这时候就需要用到actions,actions可以理解为通过将muations里面处理数据的方法变成可异步
的处理数据的方法,简单的说就是异步操作数据。
- Action提交的是mutation,而不是直接变更状态
- Action 可以包含任意异步操作
让我们来注册一个简单的action:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
store.dispatch('increment')
Action函数接受一个与store实例具有相同方法和属性的context对象,因此你可以调用context.commit提交一个mutation,或者
通过context.state 和 context.getters来获取state和getters。