1、什么是vuex?

vuex 是一个专为 Vue.js 应用程序开发的状态管理模式(通俗一点的说Vuex就是存储数据的工具,类似于cookie、sessionStorage、localStorage)。

2、vuex和cookie、sessionStorage、localStorage的区别:

cookie、sessionStorage、localStorage是浏览器存储,每当页面刷新时数据依然存在(在过期时间内),而vuex在页面刷新时存储的数据会丢失。

3、vuex一般用于大型的SPA应用,否则最好不要使用vuex。

4、基本用法:

npm安装: npm install vuex --save

新建一个store文件夹,在该文件夹下新建一个index.js文件,机构目录入下图:

Vuex有以下几个选项:state、mutations、actions、getters、module

在该index.js文件里:

import Vue from 'vue';  //引入vue
import Vuex from 'vuex';//引入vuex
Vue.use(Vuex);
//新建一个store仓库, state 是存储数据的
const store=new Vuex.Store({
state:{
count:12
}
})
export default store;

 4.1、读取数据: 在任何组件里可以通过$store.state.count来读取数据

 <p>{{$store.state.count}}</p>

或者通过计算属性进行处理

<template>
<div class="hello">
<!--直接读取-->
<p>{{$store.state.count}}</p>
<!--通过计算属性获取-->
<p>{{count}}</p>
</div>
</template> <script>
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
count(){
return this.$store.state.count;
}
} }
</script>
<style> </style>

结果如下图:

    4.2、修改数据:

在组件内,来自store的数据只能读取,不能手动修改,改变store中数据的唯一途径就是显式的提交mutations。

在以下demo中实现加1和减一的效果:

const store=new Vuex.Store({
//选项一:state用来存储数据的
state:{
count:12
},
//选项二:mutations用来修改state中的数据的
mutations:{
increament(state){
console.log(state);
//以上打印的是 count:12 ,在这里可以获取到state中的count数据,所以可以在这里直接进行修改
state.count ++;
},
decrease(state){
       console.log(state);
state.count --;
}
}
})

加1的结果:

减1的结果:

以上结果显式通过mutations已经成功的修改了state中的数据。

此外mutations还可以接受第二个参数:

修改之前的代码:

 methods:{
//自定义一个num传给mutations
addOne(){
let num=10;
this.$store.commit('increament',num);
},
reduceOne(){
let num=5;
this.$store.commit('decrease',num);
}
}
mutations:{
increament(state,num){
console.log(num); //打印的是10
state.count+=num;
},
decrease(state,num){
console.log(num); //打印的是5
state.count-=num;
}
}

此时,加10和减5修改成功。

5、高级用法:

 Vuex除了state、mutations外还有getters、actions、modules选项

 5.1、getters:

“Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算”

demo:过滤出偶数

const store=new Vuex.Store({
//选项一:state用来存储数据的
state:{
count:[1,2,3,4,5,6,7,8,9,10]
},
//选项二:mutations用来修改state中的数据的
mutations:{
increament(state,num){
state.count+=num;
},
decrease(state,num){
state.count-=num;
}
},
//选项三:getters相当于计算属性
getters:{
filterData(state){
console.log(state)
//过滤出偶数
return state.count.filter(item=>item%2==0)
}
}
})
<template>
<div class="hello">
<!--通过计算属性获取-->
<p v-for="item in count">{{item}}</p>
</div>
</template> <script>
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
count(){
return this.$store.getters.filterData;
}
}
}
</script>
<style> </style>

结果如下:

 5.2、actions:异步操作state数据,一般用于后台请求数据。

mutation里尽量不要异步操作数据,如果异步操作数据了,组件在commit后数据不能立即改变,而且也不知道什么会改变,actions就是专门处理异步操作的。

demo:3s后原数据加20

<template>
<div class="hello">
异步数据:{{count}}
<button @click="asyncClick">异步处理</button>
</div>
</template> <script>
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
list(){
return this.$store.getters.filterData;
},
count(){
return this.$store.state.count;
}
},
methods:{
asyncClick(){
//这里随便传过去一个数字20
this.$store.dispatch('asyncIncreament',20).then(()=>{
//修改成功的回调
console.log(this.$store.state.count); //
});
}
}
}
</script>
<style> </style>

store

const store=new Vuex.Store({
//选项一:state用来存储数据的
state:{
list:[1,2,3,4,5,6,7,8,9,10],
count:12,
},
//选项二:mutations用来修改state中的数据的
mutations:{
increament(state,num){
state.count+=num;
},
decrease(state,num){
state.count-=num;
}
},
//选项三:getters相当于计算属性
getters:{
filterData(state){
console.log(state)
//过滤出偶数
return state.list.filter(item=>item%2==0)
}
},
//选项四:actions实现异步操作
actions:{
asyncIncreament(content,num){
return new Promise(resolve=>{
setTimeout(()=>{
content.commit('increament',num);
resolve();
},3000)
})
}
}
})
export default store;

结果如下:

点击 “异步处理”按钮3s后页面的数据由原来的12变为32,修改成功后控制台打印结果32

5.3、module: 模块化处理

    module是用来将store分割到不同的模块,当你的项目足够大时,store里的state、getters、mutations、actions会非常多,都放在mian.js里不是很友好,使用modules可以把它们写到不同的文件中。每个module拥有自己的state、getters、mutations、         actions,而且可以多层嵌套。

demo:

目录结构:

<template>
<div class="hello">
<button @click="asyncClick">异步处理</button>
<p> 模块A的数据:{{countOne}}</p>
<p> 模块B的数据:{{countTwo}}</p>
</div>
</template> <script>
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
countOne(){
//获取模块a的state数据
return this.$store.state.a.countOne;
},
countTwo(){
//获取模块b的state数据
return this.$store.state.b.countTwo;
}
},
methods:{
asyncClick(){
//异步处理模块a的数据
this.$store.dispatch('asyncIncreamenta',30);
//异步处理模块b的数据
this.$store.dispatch('asyncIncreamentb',30);
}
}
}
</script>

模块a:

//模块A
export default{
//选项一:state用来存储数据的
state:{
list:[1,2,3,4,5,6,7,8,9,10],
countOne:12,
},
//选项二:mutations用来修改state中的数据的
mutations:{
increamentOne(state,num){
state.countOne+=num;
},
decreaseOne(state,num){
state.countOne-=num;
}
},
//选项三:getters相当于计算属性
getters:{
filterDataOne(countOne){
//过滤出偶数
return countOne.list.filter(item=>item%2==0)
}
},
//选项四:actions实现异步操作
actions:{
asyncIncreamenta(content,num){
return new Promise(resolve=>{
setTimeout(()=>{
content.commit('increamentOne',num);
resolve();
},1000)
})
}
}
}

模块b:

//模块B
export default{
//选项一:state用来存储数据的
state:{
list:[1,2,3,4,5,6,7,8,9,10],
countTwo:52,
},
//选项二:mutations用来修改state中的数据的
mutations:{
increament(state,num){
state.countTwo+=num;
},
decrease(state,num){
state.count-=num;
}
},
//选项三:getters相当于计算属性
getters:{
filterData(state){
//过滤出偶数
return state.list.filter(item=>item%2==0)
}
},
//选项四:actions实现异步操作
actions:{
asyncIncreamentb(content,num){
return new Promise(resolve=>{
setTimeout(()=>{
content.commit('increament',num);
resolve();
},1000)
})
}
}
}

store下的index.js:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import moduleA from './moduleA.js'
import moduleB from './moduleB.js'
const store=new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})
export default store;

点击“异步处理”按钮 1s后模块a和模块b的state的数据发生了改变。

6、mapState 、mapGetters、mapActions:

 6.1、mapState 
通过this.$store.state.count 获取store中的数据写法很长,所以为了简化写法可以使用 mapState 进行操作,
<template>
<div class="hello">
<button @click="asyncClick">异步处理</button>
<p> 模块A的数据:{{countOne}}</p>
<p> 模块B的数据:{{countTwo}}</p>
<p> mapState获取模块A的数据:{{messageOne}}</p>
<p> mapState获取模块B的数据:{{messageTwo}}</p>
</div>
</template> <script>
//首先引入mapState,mapGetters,mapActions
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
countOne(){
//获取模块a的state数据
return this.$store.state.a.countOne;
},
countTwo(){
//获取模块b的state数据
return this.$store.state.b.countTwo;
},
//这里的3个点表示扩展运算符(ES6的知识)
...mapState({
messageOne: state => state.a.countOne,
/*
相当于:
messageOne(){
return state.a.countOne;
}
* */
messageTwo: state => state.b.countTwo, })
},
methods:{
asyncClick(){
//异步处理模块a的数据
this.$store.dispatch('asyncIncreamenta',30);
//异步处理模块b的数据
this.$store.dispatch('asyncIncreamentb',30);
}
}
}
</script>
<style> </style>

结果如下:

结果显示:通过mapState获取的数据和通过this.$store获取的数据一致。

6.2、mapGetters
<template>
<div class="hello">
<button @click="asyncClick">异步处理</button>
<p> 模块A的数据:{{countOne}}</p>
<p> 模块B的数据:{{countTwo}}</p>
<!--遍历模块a中的列表-->
<p>遍历模块a中的列表:</p>
<p v-for="item in filterDataOne">{{item}}</p>
</div>
</template> <script>
//首先引入mapState,mapGetters,mapActions
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
countOne(){
//获取模块a的state数据
return this.$store.state.a.countOne;
},
countTwo(){
//获取模块b的state数据
return this.$store.state.b.countTwo;
},
...mapGetters([
//模块a中 filterDataOne
'filterDataOne',
]),
},
methods:{
asyncClick(){
//异步处理模块a的数据
this.$store.dispatch('asyncIncreamenta',30);
//异步处理模块b的数据
this.$store.dispatch('asyncIncreamentb',30);
}
}
}
</script>

结果如下:

6.3、mapAction:

<template>
<div class="hello">
<!-- <button @click="asyncClick">异步处理</button>-->
<p> 模块A的数据:{{countOne}}</p>
<p> 模块B的数据:{{countTwo}}</p>
<p> mapState获取模块A的数据:{{messageOne}}</p>
<p> mapState获取模块B的数据:{{messageTwo}}</p>
<!--遍历模块a中的列表-->
<!--<p v-for="item in filterDataOne">{{item}}</p>-->
<button @click="asyncIncreamenta(100)">mapActions异步处理</button>
</div>
</template> <script>
//首先引入mapState,mapGetters,mapActions
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
data(){
return{
originData:'hello Vue'
}
},
computed:{
countOne(){
//获取模块a的state数据
return this.$store.state.a.countOne;
},
countTwo(){
//获取模块b的state数据
return this.$store.state.b.countTwo;
},
//这里的3个点表示扩展运算符(ES6的知识)
...mapState({
messageOne: state => state.a.countOne,
/*
相当于:
messageOne(){
return state.a.countOne;
}
* */
messageTwo: state => state.b.countTwo, }),
...mapGetters([
//模块a中 filterDataOne
'filterDataOne',
]),
},
methods:{
...mapActions(['asyncIncreamenta']),
// asyncClick(){
// //异步处理模块a的数据
// this.$store.dispatch('asyncIncreamenta',30);
// //异步处理模块b的数据
// this.$store.dispatch('asyncIncreamentb',30);
// }
}
}
</script>
<style> </style>

点击“mapActions”按钮1后结果如下:

模块a的数据增加了100

 
 

       

深度解析vuex的更多相关文章

  1. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  2. 第37课 深度解析QMap与QHash

    1. QMap深度解析 (1)QMap是一个以升序键顺序存储键值对的数据结构 ①QMap原型为 class QMap<K, T>模板 ②QMap中的键值对根据Key进行了排序 ③QMap中 ...

  3. Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN

    http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...

  4. (转载)(收藏)OceanBase深度解析

    一.OceanBase不需要高可靠服务器和高端存储 OceanBase是关系型数据库,包含内核+OceanBase云平台(OCP).与传统关系型数据库相比,最大的不同点, 是OceanBase是分布式 ...

  5. Kafka深度解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...

  6. java内存分配和String类型的深度解析

    [尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...

  7. Unity加载模块深度解析(Shader)

    作者:张鑫链接:https://zhuanlan.zhihu.com/p/21949663来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 接上一篇 加载模块深度解析(二 ...

  8. Unity加载模块深度解析(网格篇)

    在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能.这次,我们再来为你揭开其他主流资源的加载效率. 这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何 ...

  9. 深度解析Java8 – AbstractQueuedSynchronizer的实现分析(上)

    本文首发在infoQ :www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer 前言: Java中的FutureTask作为可异步执行任 ...

随机推荐

  1. O - Muddy Fields

    来源poj2226 Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R & ...

  2. Coffee and Coursework (Hard Version)

    Coffee and Coursework (Hard Version) time limit per test 2.5 seconds memory limit per test 256 megab ...

  3. Nginx打卡

    Nginx打卡 此括号中的是干货 [ 直接说最关心的事:如何去掉访问路径的端口号? 答案:使用Nginx啊 具体安装还需看底下啰嗦的东东,安装OK且完美启动的同学,server proxy_pass ...

  4. jQuery 中的 39 个技巧【申明:来源于网络】

    jQuery 中的 39 个技巧[申明:来源于网络] 地址:http://blog.csdn.net/zhongqi2513/article/details/53704812?ref=myread

  5. JavaScript面向对象之get和set设置读写属性

    之前我们通过this和prototype申明的属性都是可读写的属性,如果想实现单独控制,就必须使用get和set存取期. 基本方法的 步骤一般包含两个步骤,1,使用var关键字定义一个私有属性作为中间 ...

  6. XSS笔记

    XSS测试代码: <img src="javascript:alert(/xss/)"> <script src=http://evil.com/xss.js&g ...

  7. 更新node的版本,node没有安装到c盘,安装到了D盘

    百度的很久,只有这一个实用,记录一下 https://www.cnblogs.com/xinjie-just/p/7061619.html

  8. 7.0-uC/OS-III中断管理

    1.CPU的中断处理 理器通常有多个中断源. 例如, UART中断. DMA中断. ADC中断.定时器中断等. 2.中断器件标志中断处理器,然后中断处理器将优先级最高的中断提交给CPU. 现在的中断控 ...

  9. 一年工作经验的大专生程序员(java后台)

    1.文章前言     作为18应届毕业大专生已工作一年,相信这也是大部分同届生的现状.       那么,一个萌新进入职场一年都经历了什么呢?在校那会我是挺好奇的.       这篇文章是根据自己一年 ...

  10. VUE 全局变量的几种实现方式

    最近在学习VUE.js 中间涉及到JS全局变量,与其说是VUE的全局变量,不如说是模块化JS开发的全局变量. 1.全局变量专用模块 就是以一个特定模块来组织管理这些全局量,需要引用的地方导入该模块便好 ...