初识vuex
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双向绑定,使其视图的更新影响模型,模型的更新影响视图,你会不会 ...
随机推荐
- 关于hashmap的底层实现
注:以下内容并非基于最新的jdk版本 q1:hashmap为什么叫hashmap? 答:hashmap基于hashtable(不是hashtable类)实现. q2:hashtable(不是hasht ...
- 初识XMLHttpRequeset
XMLHttpRequeset是什么 XmlHttpRequest,可扩展的超文本传输歇息.从字面上理解:xml,可扩展的标记语言:http,超文本传送协议:request,请求.XmlHttpReq ...
- [转]CentOS 6.3下Samba服务器的安装与配置
一.简介 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件,而SMB是Server Message Block的缩写,即为服务器消息块 ,SMB主要是作为Microsoft的 ...
- C#用DesignSurface实现一个简单的窗体设计器
System.ComponentModel.Design.DesignSurface是为设计组件提供一个用户界面,通过它可以实现一个简单的窗体设计器. 在构建之前,我们需要引入System.Desig ...
- 响应式布局中的CSS相对量
一个响应式布局,要能够根据设备屏幕尺寸的改变,动态的调整页面内容,展现不同的设计风格. 在进行响应式的 CSS 代码编写过程中,经常会用到一些相对尺寸,以达到相对定位的目的.例如,常见的响应式布局中需 ...
- Linux实战教学笔记17:精简shell基础
第十七节 精简shell基础 标签(空格分隔): Linux实战教学笔记 1,前言 1.1 为什么学习shell编程 Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, ...
- Android 调用jepg库进行图片压缩,保持图片不失真
1. 浅谈为什么Android和iOS图片质量差距那么大? 首先来说,作为一个安卓狗,机器当然用的是安卓的手机.现在的安卓手机大多数都会以高清拍照,动不动就几千万柔光相机来吸引各种买家.买来后,拍照发 ...
- 以setTimeout来聊聊Event Loop
平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...
- JAVA 在程序中存储和修改信息
1.语句和表达式 计算机程序是一组告诉计算机什么的指令,每一个指令称为语句. 2.指定变量类型 变量名.变量存储的信息类型 整型int(-2.14*109~2.14*109).浮点型float(38位 ...
- C++拷贝构造&操作符重载
头文件 DString.h如下 #ifndef __DSTRING_H #define __DSTRING_H #endif #include <stddef.h> class DStri ...