1.简介
vuex是 vue官方推荐的一个状态管理器。当我们遇到很多状态改变时,组件之间的通信就会变得复杂,这时候vuex的强大就展现出来。
我们从vuex的原理以及vuex的api两个部分介绍vuex
原理:
vuex的核心是store对象,它承载了vue的状态管理。vuex的实现分为了2个部分,第一个部分是store的创建,以及第二部分store的挂载,并且解析store。
vuex通过插件安装的形式来使得vue挂载vuex的store,当然这个是在vue组件的createBefore阶段实现的。随后Vuex将它直接挂载到 $options.$store 以供使用vue使用。
对于vuex的属性,Vuex 会将 vuex 属性解构成 getters 和 actions。并将 getters 的每个属性都挂载 vm 下(有可能被组件的 $options.data() 的属性覆盖),同时定义每个值的 getter 方法,但并不会定义 setter 方法,这是因为根据 Vuex 的设计是不允许开发者直接在组件内更改 store.state,而对数据的改动要通过提交 mutation。Vuex 实际上将 vm.vuex.getter 内的属性当作当前 vm 的计算属性来处理。和计算属性的区别是计算属性依赖计算的是 vm.$options.data 内的值,而 vm.vuex.getter 的属性依赖计算的是 store._vm.$options.data。这样所有组件的渲染都将都可以直接从状态树拿数据来渲染 UI 。
所有的组件都可以和vuex的状态树进行数据交互。但是不允许直接改变状态树的状态,应该用vuex的mutations来提交状态的改变。vuex会将actions内的方法绑定到vue的$options.methods下,它们与vue中定义的方法并没有区别。而 actions 内的方法将通过 dispatch 触发 mutations 来更新全局状态,actions方法与mutations的区别是,mutations改变state并且必须是同步改变,而actions可以作为异步提交的方法,dispatch 可以接收一个promise,并且返回一个promise。
2.API:
state:在vue中引入store对象,在子组件中通过this.$store来访问vuex中状态,并且我们最好在vue的computed中获取vuex的状态。
mapState:这是一个语法糖,可以快捷的获取更多的state。
接受一个object参数:
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex' export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count', // 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
当计算属性的名称和节点名称相同时,也可以接受一个数组对象。
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
对象展开:合成最终的computed属性
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
getter:store的计算属性,在获取数据的时候,我们可以通过getter进行数据的操作,在相同地方用到的数据操作就不需要写一个公用的处理函数。它接受2个参数,state和getters。
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1
mapGetters:
export default {
// ...
computed: {
// 使用对象展开运算符将 getters 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
或者
mapGetters({
// 映射 this.doneCount 为 store.getters.doneTodosCount
doneCount: 'doneTodosCount'
})
mutations:vuex提交状态的唯一方式。mutations更像一个事件监听器,当vue中commit了信息之后,相应的mutation才会执行相应的回掉函数。它接受2个参数,state和object。
因为vue是响应式的,所以mutations也应该遵守vue的动态绑定,所以在需要使用mutations前,尽量初始化。或者是添加时使用vue.set(obj,'new obj', 'value')或者以新运算符state.obj = { ...state.obj, newProp: 123 }
mutations必须是同步函数
组件中提交mutations:
import { mapMutations } from 'vuex' export default {
// ...
methods: {
...mapMutations([
'increment' // 映射 this.increment() 为 this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
})
}
}
actions: actions提交的是mutations,因为mutations是必须为同步状态,actions就提供了一种异步的形式提交mutations,我们可以在active中去做异步处理,并且提交mutation。它接受一个context参数,这个参数具有store对象相同属性和方法,但是并不是store本身。
actions: {
increment (context) {
context.commit('increment')
}
} //或者 使用解值
actions: {
increment ({ commit }) {
commit('increment')
}
}
actions以dispatch来分发
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
}) // 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
组合的actions:
store.dispatch
可以处理被触发的action的回调函数返回的Promise,并且store.dispatch仍旧返回Promise
actions: {
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}
// 可以这样触发
//一个store.dispatch
在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。
store.dispatch('actionA').then(() => {
// ...
}) // 也可以这样子触发
actions: {
// ...
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
}
modules:
Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters、甚至是嵌套子模块——从上至下进行类似的分割。
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 的状态
模块的局部状态
对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态。
const moduleA = {
state: { count: 0 },
mutations: {
increment (state) {
// state 模块的局部状态
state.count++
}
}, getters: {
doubleCount (state) {
return state.count * 2
}
}
}
对于模块内部的 action,context.state
是局部状态,根节点的状态是 context.rootState。
const moduleA = {
// ...
actions: {
incrementIfOddOnRootSum ({ state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
对于模块内部的 getter,根节点状态会作为第三个参数。
const moduleA = {
// ...
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}
}
命名空间:
模块内部的 action、mutation、和 getter 现在仍然注册在全局命名空间——这样保证了多个模块能够响应同一 mutation 或 action。你可以通过添加前缀或后缀的方式隔离各模块,以避免名称冲突。你也可能希望写出一个可复用的模块,其使用环境不可控。例如,我们想创建一个 todos
模块:
// types.js // 定义 getter、action、和 mutation 的名称为常量,以模块名 `todos` 为前缀
export const DONE_COUNT = 'todos/DONE_COUNT'
export const FETCH_ALL = 'todos/FETCH_ALL'
export const TOGGLE_DONE = 'todos/TOGGLE_DONE'
// modules/todos.js
import * as types from '../types' // 使用添加了前缀的名称定义 getter、action 和 mutation
const todosModule = {
state: { todos: [] }, getters: {
[types.DONE_COUNT] (state) {
// ...
}
}, actions: {
[types.FETCH_ALL] (context, payload) {
// ...
}
}, mutations: {
[types.TOGGLE_DONE] (state, payload) {
// ...
}
}
}
我们也可以运用es6的新方法,symbol做命名;
需要了解更多关于symbol的信息,请移步阮一峰老师的ES6
参考文献:
初识vuex的更多相关文章
-
初识vuex vuex 的基本用法
Vuex 是什么? 官方是这么说的:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 一个完 ...
-
vue(21)初识Vuex
Vuex是做什么的? 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex ...
-
Vuex ~ 初识
状态:data中的属性需要共享给其他vue组件使用的部分(即data中需要共用的属性) 1.初识vuex直接来个小demo 下面操作都是基于vue-cli,如果不了解先学习下vue-cli 利用n ...
-
vuex的学习和理解
初识Vuex: vuex是 vue官方推荐的一个状态管理器,也是vue专用的一个插件.当我们遇到很多状态改变时,组件之间的通信就会变得复杂,这时候vuex的强大就体现出来了. Vuex 应用的核心就是 ...
-
Vue爬坑之vuex初识
在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用 props 或者 $emit 等方式 http://www.cnblogs.com/wisewrong/p/62660 ...
-
Vuex初识
vuex是vue中单向数据流的一个状态管理模式,它可以集中存储管理应用中所有组件的状态,并且有一套相应的规则可以去预测数据的变化.类似与此的还有react中的redux,dva等状态管理模式. 一般我 ...
-
[20190620]日常学习记录(三)-初识promise及vuex
在学习promise之前重温了Ajax的原生js实现, 在原生js中发送一个http请求首先new XMLHttpRequest() 然后定义状态变更事件 浏览器监听请求的状态,触发不同状态下相应的代 ...
-
前端笔记之Vue(四)UI组件库&;Vuex&;虚拟服务器初识
一.日历组件 new Date()的月份是从0开始的. 下面表达式是:2018年6月1日 new Date(2018, 5, 1); 下面表达式是:2018年5月1日 new Date(2018, 4 ...
-
Vuex原来可以这样上手
在Mvc模式大行其道的今天,后端通过各种Mvc框架实现视图与数据模型的隔离,而前端这方面也发展迅速.vue实现了Dom与viewModel双向绑定,使其视图的更新影响模型,模型的更新影响视图,你会不会 ...
随机推荐
-
无线网破解软件|一键式破解无线网|BT17软件包下载[笔记本+软件就行]
从新版BT17发布到现在已经有一段时间,谢谢大家的一直来的关注.现在给大家讲解一下无线网破解问题,告诉 大家如何一键式破解WPA,WPA2,AES.Tkip等加密方式以及新版BT17软件包的下载地址. ...
-
hdu 1875 畅通project再续
链接:hdu 1875 输入n个岛的坐标,已知修桥100元/米,若能n个岛连通.输出最小费用,否则输出"oh!" 限制条件:2个小岛之间的距离不能小于10米,也不能大于1000米 ...
-
一个好用的Dialog插件
网页中常常须要弹出dialog,尽管非常多JS开源框架都提供这个功能,可是效果都不是非常好,比方easy-UI.改动样式这些又不是我擅长的,身边又没有美工兄弟,苦逼啊! (Easy-UI的BasicD ...
-
java的多线程初体验
这里以车站售票作为模拟场景,多个票务人员同时出售某一列高铁(G250?)的车票,售票的基本保证有2点: 1.不能售出多于预定限额的车票. 2.不能售出具有相同座位的车票. 初学java,有不当的地方各 ...
-
ABP入门系列(17)——使用ABP集成的邮件系统发送邮件
ABP中对邮件的封装主要集成在Abp.Net.Mail和Abp.Net.Mail.Smtp命名空间下,相应源码在此. #一.Abp集成的邮件模块是如何实现的 分析可以看出主要由以下几个核心类组成: E ...
-
Entity Framework教程翻译 ---- 系列教程
Entity Framework教程(第二版) (翻译)Entity Framework技巧系列之十四 - Tip 56 (翻译)Entity Framework技巧系列之十三 - Tip 51 - ...
-
使用InputStreamReader读入,使用OutputStreamWriter写出,将一首诗按行重写?
https://www.processon.com/view/link/5b1a3880e4b00490ac8f5f40 改善后: (可将不管一行有几个字时的不规律的文本,按行倒写) package ...
-
学习笔记之Moq
dotnet/src/MoqSample at master · haotang923/dotnet · GitHub https://github.com/htanghtang/dotnet/tre ...
-
Eclipse的基本使用
01Eclipse的下载安装 * A: Eclipse的下载安装 * a: 下载 * http://www.eclipse.org * b: 安装 * 只需要解压后就能使用 * c: 卸载 * 只 ...
-
Executor Framework
Why? look at the following 2 pieces of code for implementing a simple web server based on socket, ca ...