通俗易懂了解Vuex

1.前言

在使用Vue进行开发的时候,关于vue组件通信的方式,除了通俗易懂了解Vue组件的通信方式这篇博文谈到三种通信方式,其实vue更提倡我们使用vuex来进行组件间的状态管理以及通信问题。Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

2.引例

在学习vuex之前,我们不妨先看这样一个例子:

在一个父子组件嵌套环境下,父组件可以改变子组件的背景颜色,而子组件自身也可以改变自己的背景颜色。

虽然使用之前谈到的组件通信方式也可以实现这个例子,但是这不是我们今天想讨论的。

我们可以换个角度看这个例子:

我们可以把子组件的背景颜色看做一种状颜色态,我们把这个颜色状态放在组件的外部,让子组件去读取这个状态来决定自己的背景颜色该是什么,如果父组件需要改变子组件的背景颜色,那么只需让父组件去改变这个状态即可,因为子组件的背景颜色取决于这个颜色状态是什么颜色,控制了这个状态,即控制了子组件的背景颜色。

简而言之一句话:就是需要对状态进行管理,这也就是vuex的核心:状态管理。

3.store

vuex对于状态管理提供了状态仓库store,store的作用就是将所有状态统一存储管理起来,状态仓库store是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。说了这么多,我们简单使用一下store。

3.1 安装vuex

在使用vue-cli进行模块化开发时,使用vuex之前必须先安装vuex:

npm install vuex --save

3.2 创建状态仓库store

安装完成后,在项目中main.js文件中按照如下方式引入vuex并创建一个状态仓库store,在状态仓库store内创建第一个状态color并设置该状态初始值为red:

1 import vuex from 'vuex'
2 Vue.use(vuex);
3 var store = new vuex.Store({
4     state:{
5         color:'red'
6     }
7 })

然后,在main.js中的根vue对象中挂载上面创建好的状态仓库store,这样在任何组件中都可以去读取仓库中的状态:

1 new Vue({
2   el: '#app',
3   store,
4   render: h => h(App)
5 })

 OK,到这里,状态仓库和状态就创建好了,接下来我们就可以采用读取状态和改变状态的方式来改写上面的例子了,代码如下:

父组件代码:

<template><div id="app"><h1>我是父组件</h1>  <!--点击按钮后,去状态仓库将状态color改成yellow--><input type="button" value="变成黄色" @click="$store.state.color = 'yellow'"><Child></Child></div>
</template><script>import Child from './Child'export default {name: 'app',components:{Child},data () {return {}},
}
</script><style></style>

子组件代码:

<template><!--子组件的backgroundColor属性值取决于状态仓库中的状态color值--><div class="child" :style="{backgroundColor:$store.state.color}"><h1>子组件</h1><!--子组件点击按钮,也可以去状态仓库中改变color状态值--><input type="button" value="变成蓝色" @click="$store.state.color = 'blue'"></div>
</template><script>export default {name: "Child",}
</script><style scoped>
.child{width: 500px;height: 500px;
}
</style>

效果如下:

 

以上例子就是Vuex最简单的使用,怎么样,是不是so easy!!

3.3  优化代码结构

前面为了方便 , 我们把 store 对象写在了 main.js 里面 , 但实际上为了便于日后的维护 , 我们将store单独隔离出来分开写更好 , 我们在 src 目录下 , 新建一个 store 文件夹 , 然后在里面新建一个 index.js :

import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);export default new vuex.Store({state:{color:'red'}
})

那么相应的 , 在 main.js 里的代码应该改成 :

import Vue from 'vue'
import App from './App.vue'
//引入store
import store from './store'
new Vue({el: '#app',store,render: h => h(App)
})

这样就把 store 单独分离出去了 ,日后当状态越来越多的时候维护起来就更加方便啦!

4.module

虽然我们把 store 单独分离出去了,但是随着项目规模越来越大,组件也越来越多,这就造成store.state里面的状态会越来越多,这么多的状态都堆在store.state里面显然不是一个很好代码结构,更重要的是哪些组件依赖哪些状态也会变得非常不清晰。那有没有什么更好的解决方案呢?其实Vuex早就替我们想到了,Vuex中的modules就是用来解决这个问题的。

modules可以将store.state里面的状态按照各个组件所依赖的情况进行分类,例如,我们将上面例子中子组件Child所依赖的color状态单独写进一个js文件中,然后在store 文件夹下的 index.js 中引入即可,代码如下:

//在store文件夹下新建Child_store.js文件:
export default {state:{color:'red'}
}

然后在store 文件夹下的 index.js 中引入:

import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);import Child_store from './Child_store.js';//引入Child_store.js中的store对象

export default new vuex.Store({modules: {Child_store:Child_store}
})

做出这样的修改之后 , 我们只需将之前我们使用的 $store.state.color 统统改为 $store.state.Child_store.color即可。

如果还有其他的组件所依赖的状态 ,那就在store文件夹下再新建一个对应的xx_store.js文件 , 然后将他们引入到 index.js 文件中的modules中。

import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);import Child_store from './Child_store.js';//引入Child_store.js中的store对象
import xxx_store from './xxx_store.js';//引入xxx_store.js中的store对象

export default new vuex.Store({modules: {Child_store:Child_store,xxx_store :xxx_store }
})

5. mutation

在上面例子中,我们点击按钮这个动作仅仅依赖了一个color状态,所以我们可以将改变状态的动作直接写在按钮的click的事件中,即@click="$store.state.Child_store.color = 'blue'"。,但是如果按钮点击依赖了多个状态,那么我们就不能把所有状态改变的动作都写在click事件中,当然,也不允许我们这么干。此时我们就需要用到mutations了,mutations允许我们一次性更新多个状态。

例如,我们给上面例子中的子组件Child再新增一个状态width,用来改变子组件的宽度,我们希望当点击按钮,既改变了子组件的背景颜色,而且也改变子组件的宽度,代码如下:

1.给Child_store.js中增加mutations选项

//Child_store.js
export default {state:{color:'red',width:'500px'},mutations:{switch(state,payload){    //这里的state对应着上面那个statestate.color = payload.color;state.width = payload.width;}},
}

在mutations选项中定义switch函数,该函数可以接收两个参数,第一个参数必须是state,即为要改变的状态对象,第二个参数称为载荷(payload),即函数内要使用的参数.

2.子组件代码

<template><div class="child" :style="{backgroundColor:$store.state.Child_store.color,width:$store.state.Child_store.width}"><h1>子组件</h1></div>
</template><script>export default {name: "Child",}
</script><style scoped>
.child{height: 500px;
}
</style>

3.父组件代码

<template><div id="app"><h1>我是父组件</h1><input type="button" value="变成蓝色并且宽度变小" @click="$store.commit('switch',{color:'blue',width:'100px'})"><Child></Child></div>
</template><script>import Child from './Child'export default {name: 'app',components:{Child},data () {return {}}
}
</script><style></style>

父组件中使用$store.commit('switch',{color:'blue',width:'100px'})来触发mutations中的switch函数,$store.commit()接收的第一个参数为要触发的mutations中的哪个函数,第二个参数是一个对象,也就是要触发的switch函数中的载荷payload。

效果如下:

6.action

多个state的操作 , 使用mutations会来触发会比较好维护 , 那么需要执行多个mutations就需要用action了:

1.给Child_store.js中增加actions选项

export default {state:{color:'red',width:'500px'},mutations:{switch(state,payload){    //这里的state对应着上面那个statestate.color = payload.color;state.width = payload.width;}},actions:{switch_action(ctx,payload){      //这里的ctx和我们使用的$store拥有相同的对象和方法ctx.commit('switch',payload);//你还可以在下面触发其他的mutations方法
    }}
}

2.子组件不用变,在父组件中需要使用$store.dispatch('switch_action',{color:'blue',width:'100px'})来触发actions中的switch_action方法

<template><div id="app"><h1>我是父组件</h1><input type="button" value="变成蓝色并且宽度变小" @click="$store.dispatch('switch',{color:'blue',width:'100px'})"><Child></Child></div>
</template><script>import Child from './Child'export default {name: 'app',components:{Child},data () {return {}}
}
</script><style></style>

7.getter

 有时候我们需要从state 中派生出一些状态,也就是说,某些状态是通过现有的一个或多个状态通过计算得到的,类似于计算属性computed。假如我们现有一个状态show:true,但是我们很多地方又需要一个跟show状态相反的notShow状态,这种情况放在以前,我们会写一个计算属性来返回notShow:

computed(){not_show(){return !this.$store.state.show;}
}

哪个组件里需要notShow状态,就在哪个组件里写一遍上面的代码,如果需要这个状态的组件很多,那么就需要写很多遍重复的代码。这肯定不是我们想要的,而Vuex中的getter就很好的解决了这个问题:

export default {state:{show:false},getters:{notShow(state){//这里的state对应着上面这个statereturn !state.show;}}
}

我们在组件中使用$store.state.show来获得状态show,类似的 , 我们可以使用$store.state.notShow来获得状态notShow。

注意 $store.state.notShow的值是不能直接修改的 , 需要对应的 state 发生变化才能修改。

8.总结

了解了以上这些,再回头去看Vuex的官方文档,就应该不会一脸懵逼啦,哈哈哈哈。

(完)

 

转载于:https://www.cnblogs.com/wangjiachen666/p/9539039.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jQuery源码分析

(function( window, undefined ) {// jquery code})(window);这是一个自调用匿名函数。什么东东呢&#xff1f;在第一个括号内&#xff0c;创建一个匿名函数&#xff1b;第二个括号&#xff0c;立即执行为什么要创建这样一个“自调用匿名函数”呢&#xff1f; 通过定义一个匿名…

netcore 内存限制_.NET Core 和 Serverless 构建飞速发展的架构

(给DotNet加星标&#xff0c;提升.Net技能)英文&#xff1a;samueleresca.net译文&#xff1a;cnblogs.com/Rwing/p/fast-growing译者&#xff1a;Rwing本篇文章的第一部分介绍了有关Serverless计算的基本概念。第二部分展示了如何构建 .NET Core的Lambda函数&#xff0c;其中使…

更多Requests的小技巧以及总结

对于requests的爬虫库&#xff0c;我们已经学到了尾声。 我们在这儿可以挖掘出更多的requests的使用小技巧。 一.cookie对象与字典的转换 在爬取目标cookie的时候&#xff0c;我们可以将cookie信息进行简化处理。 现在做一个简单的代码验证看看&#xff0c;使用百度的cookies&a…

进入Undertow Web服务器

随着Java EE 7的到来以及处理诸如Web Sockets API和HTTP升级&#xff08;例如EJB over HTTP&#xff09;之类的高级功能的要求&#xff0c;WildFly开发团队已经做出了重要决定。 在长期致力于JBoss Web服务器&#xff08;Apache Tomcat的一个分支&#xff09;之后&#xff0c;新…

HTTPHandler有什么作用

一 asp.net请求的处理过程&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;Http…

centos 重启网卡_CentOS6 网络管理之网卡配置及简单路由设置

CentOS6中关于网络配置的命令有很多&#xff0c;本文将介绍几个平时最长用的几个命令&#xff0c;以及网卡IP地址的配置和简单路由配置。1、经常使用的查看IP地址命令为 ifconfig&#xff0c;不跟参数的情况下默认查看所有已启用的网卡信息&#xff0c;如下图所示&#xff1a;如…

绝地求生 android版支持蓝牙吗,《绝地求生》吃鸡必须要顶配吗?这些配置也能畅玩...

导读《绝地求生》火爆之余&#xff0c;很多人在想要加入这款游戏时&#xff0c;却被游戏传闻中的超高配置要求给吓到了&#xff0c;然后心生退意。事实上&#xff0c;吃鸡的配置要求真的这么高吗&#xff1f;其实并不是&#xff01;传言1&#xff1a;8G内存不能玩这则传言的说法…

《美团机器学习实践》高清PDF+思维导图+美团算法团队

在美团的搜索、推荐、计算广告、风控、图像处理等领域&#xff0c;相关的人工智能技术得到广泛的应用。《美团机器学习实践》包括通用流程、数据挖掘、搜索和推荐、计算广告、深度学习以及算法工程6大部分内容&#xff0c;全面介绍了美团在多个重要方面对机器学习的应用。通过本…

如何使用HttpModule来实现我们日常的应用:

1、向每个页面动态添加一些备注或说明性的文字&#xff1a; 有的网站每一个页面都会弹出一个广告或在每个页面都以注释形式&#xff08;<!-- -->&#xff09;加入网站的版权信息。如果在每个页面教编写这样的JS代码的话&#xff0c;对于大一点的网站&#xff…

Java 8中的java.util.Random

Java 8中java.util.Random类的简洁功能之一是对其进行了改进&#xff0c;现在可以返回随机的数字流 。 例如&#xff0c;要生成一个介于0&#xff08;含&#xff09;和1&#xff08;不含&#xff09;之间的随机双精度数的无限流&#xff1a; Random random new Random(); Do…

appium判断元素是否存在_Python+selenium自动化之判定元素是否存在

在测试过程中&#xff0c;我碰到过这类的问题&#xff0c;使用find_element却找不到某个元素而产生异常&#xff0c;这就需要在操作某个元素之前判定该元素是否存在&#xff0c;而selenium中没有判定元素是否存在的方法&#xff0c;或者判定相同的元素有几个&#xff0c;需要操…

棋盘DP三连——洛谷 P1004 方格取数 洛谷 P1006 传纸条 Codevs 2853 方格游戏

P1004 方格取数 题目描述 设有N $\times N$NN的方格图(N $\le 9$)(N≤9)&#xff0c;我们将其中的某些方格中填入正整数&#xff0c;而其他的方格中则放入数字00。如下图所示&#xff08;见样例&#xff09;: A0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 …

html一张图片用两种滤镜,HTML图片CSS滤镜—灰度效果

this.p{ m:2,b:2,loftPermalink:,id:fks_082065087087086069087082087095083084084067083083082065,blogTitle:HTML图片CSS滤镜—灰度效果,blogAbstract: ,blogTag:html,blogUrl:blog/static/72507542200941384735902,isPublished:1,istop:false,type:2,modifyTime:13288029920…

将动态aspx页面转换成为静态html页面的几种方法

1. 模版法 该方法历史悠久&#xff0c;具体处理流程为采用一个html模版&#xff0c;将其中的关键字替换为我们希望的信息。 优点: 缺点: 所有的信息都要采取字符串批凑的方式来实现&#xff0c;比如需要一个列表&#xff0c;就需要拼凑字符串。问题是开发周期长&…

SSH协议详解

简介 SSH只是一个协议&#xff0c;基于这个协议有不同的实现&#xff0c;这些实现中有开源&#xff0c;也有收费。 原理 普通网络通信一般是明文通信&#xff0c;数据容易被中间人拦截并且解析&#xff0c;而SSH协议则提供了基于内容加密服务。 流程&#xff1a; 第一种&#x…

怎么通过media foundation将图像数据写入虚拟摄像头_千倍成本压缩!特斯拉开发虚拟激光雷达,替代最贵自动驾驶传感器...

「谁用激光雷达&#xff0c;谁完蛋&#xff01;」在去年特斯拉举办的 Autonomy Day 上&#xff0c;特斯拉 CEO Elon Musk 言辞激烈地炮轰激光雷达。「昂贵的传感器是不必要的&#xff0c;这就像是一大堆昂贵的附属品。」「像阑尾一样。一个阑尾不好——那么&#xff0c;一大堆阑…

JBoss Fuse 6.1 + HawtIO第一部分

它是开源的&#xff01; JBoss Fuse是开源ESB &#xff0c;是Red Hat收购FuseSource之后Fuse ESB的发展。 它是开源的 &#xff0c; Apache v2许可的 &#xff0c; 并由Red Hat完全支持 。 最好的部分之一是&#xff0c;您可以免费下载并使用它&#xff0c;并且在生产或订阅中支…

html5新增的js api,对HTML5新增JS Api的思考

1.为什么javascript的变量名不使用css中的命名方法&#xff0c;而选择使用驼峰命名法因为在javascript中“-”表示减法&#xff0c;所以如果使用“-”的话会出现不必要的问题。2.在javascript中已经有className方法添加类名&#xff0c;为什么还要新增加classList.add方法因为c…

什么是URL转发和一个IP建多个Web站点--主机头名法

什么是URL转发&#xff1f; 所谓 URL 转发&#xff0c;是中企资源对在中企资源注册的域名&#xff0c;所提供的一项特别的域名增值服务&#xff0c;此服务是通过中企资源服务器的特殊技术设置&#xff0c;实现当访问您的域名时&#xff0c;将会自动跳转到您所指定的另一个网络地…

eval()

eval() 接收一个字符串&#xff0c;这个字符串必须是一个表达式&#xff0c;然后执行并返回表达式的值 In [6]: x 7In [7]: eval(3 x) Out[7]: 10 In [8]: eval(pow(2, 3)) Out[8]: 8 In [9]: eval(2 3) Out[9]: 5 转载于:https://www.cnblogs.com/pzk7788/p/10264105.h…