最近用到vuex,整理一下基础用法。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
这个状态自管理应用包含以下几个部分:
- state,驱动应用的数据源;
- view,以声明方式将state映射到视图;
- actions,响应在view上的用户输入导致的状态变化。
如图示,Vuex为Vue Components建立起了一个完整的生态圈,包括开发中的API调用一环。围绕这个生态圈,简要介绍一下各模块在核心流程中的主要功能:
Vue Components:Vue组件。HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应action进行回应。
dispatch:操作行为触发方法,是唯一能执行action的方法。
actions:操作行为处理模块。负责处理Vue Components接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了Promise的封装,以支持action的链式触发。
commit:状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。
mutations:状态改变操作方法。是Vuex修改state的唯一推荐方法,其他修改方式在严格模式下将会报错。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些hook暴露出来,以进行state的监控等。
state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。
getters:state对象读取方法。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。
Vue组件接收交互行为,调用dispatch方法触发action相关处理,若页面状态需要改变,则调用commit方法提交mutation修改state,通过getters获取到state新值,重新渲染Vue Components,界面随之更新。
把全局数据源state、
改变数据源的方法mutations、
异步操作方法actions
都放提取出来放到store中,实现全局数据状态单独管理的功能
安装与配置
1、安装vuex
使用npm直接安装
npm install vuex
配置package.json安装
"devDependencies": {
...
"vuex": "^2.1.1",
...
},
2、 配置
配置方式和路由的配置方式差不多
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//创建Store实例
const store = new Vuex.Store({
// 存储状态值
state: {
...
},
// 状态值的改变方法,操作状态值
// 提交mutations是更改Vuex状态的唯一方法
mutations: {
...
},
// 在store中定义getters(可以认为是store的计算属性)。Getters接收state作为其第一个函数
getters: {
...
},
actions: {
...
}
})
// 要改变状态值只能通过提交mutations来完成
/* eslint-disable no-new */
new Vue({
el: '#app',
template: '<App/>',
components: { App },
// 将store实例注入到根组件下的所有子组件中
store
// 子组件通过this.$store来方位store
})
Vuex 中 Store 的模板化定义:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
},
actions: {
},
mutations: {
},
getters: {
},
modules: {
}
})
export default store
Vuex Store 时关键的 5 个属性:
1. state:
state 定义了应用状态的数据结构,同样可以在这里设置默认的初始状态。
state: {
projects: [],
userProfile: {}
}
我们可以用以下方式在Vue 组件中获得Vuex的state状态
template:
<div>
{{ $store.state.count }}
</div>
script:
console.log(this.$store.state.count)
2 . actions:
Actions 即是定义提交触发更改信息的描述,常见的例子有从服务端获取数据,在数据获取完成后会调用store.commit()来调用更改 Store 中的状态。可以在组件中使用dispatch来发出 Actions。
actions: {
LOAD_PROJECT_LIST: function ({ commit }) {
axios.get('/secured/projects').then((response) => {
commit('SET_PROJECT_LIST', { list: response.data })
}, (err) => {
console.log(err)
})
}
}
注意:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
Action 还是得通过 mutation 方法来修改state
actions: {
increment (context) {
context.commit('increment')
},
incrementAsync (context) {
// 延时1秒
setTimeout(() => {
context.commit('increment')
}, 1000)
}
},
组件通过commit提交actions的方式来请求改变state
this.$store.dispatch('incrementAsync')
3 . mutations:
mutations: {
SET_PROJECT_LIST: (state, { list }) => {
state.projects = list
}
}
mutations对state的操作
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
组件通过commit提交mutations的方式来请求改变state
this.$store.commit('increment')
mutations方法中是可以传参的,具体用法如下:
mutations: {
// 提交载荷 Payload
add(state, n) {
state.count += n
}
},
this.$store.commit('add', 10)
这里只是传了一个数字,在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读。
4 . getters:
Getters 允许组件从 Store 中获取数据,譬如我们可以从 Store 中的 projectList 中筛选出已完成的项目列表
getters: {
completedProjects: state => {
return state.projects.filter(project => project.completed).length
}
}
getters其实可以认为是 store 的计算属性,用法和计算属性差不多。
定义getter:
getters: {
done(state) {
return state.count + 5;
},
}
使用getter
console.log(this.$store.getters.done)
5 . modules:
modules 对象允许将单一的 Store 拆分为多个 Store 的同时保存在单一的状态树中。