Vuex的初探与实战
1.背景
最近在做一个单页面的管理后台项目,为了提高开发效率,使用了Vue框架来开发。为了使各个部分的功能,独立结构更加清晰,于是就拆分了很多组件,但是组件与组件之间数据共享成了一个问题,父子组件实现起来相对简单,prop,$emit,$on就能搞定。除此之外,有很多兄弟组件和跨多级组件,实现起来过程繁琐,在多人协同开发上,不利于统一管理,于是,开始了Vue的生态之一的Vux实践之旅。
2.概述
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。
Vuex 和单纯的全局对象有以下两点不同:
1.Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新;2.你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用
3.安装使用
3.1.使用Vue-cli开发安装vue包
cnpm install vuex --save
3.2.在src目录下创建store文件夹并创建index.js如下(src/store/index.js)
import Vue from 'vue'
import Vuex from 'vuex' Vue.use(Vuex); export default new Vuex.Store({
state: { },
getters: { },
mutations: { },
actions: { }
});
然后在src文件下的main.js中使用
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false new Vue({
el: '#app',
store,
components: { App },
template: '<App/>'
})
4.用法简介
4.1.state
state是保存共享数据的,现在改store/index.js如下:
**
state: {
count:
},
**
在components目录下创建Index.vue如:
<template>
<div class="index">
{{count}}
</div>
</template> <script>
export default {
name: "index",
computed:{
count(){
return this.$store.state.count;
}
}
}
</script>
结果如下:

我们可以通过组件的计算属性来保存state里面的值,那么问题来了,如果store太多的话,我们组件里面的计算属性岂不是成了这个样子:
**
computed:{
count(){
return this.$store.state.count;
},
stateA(){
return this.$store.state.stateA;
},
stateB(){
return this.$store.state.stateB;
}
}
**
这样获取共享状态的数据也没有什么问题不过看起来还是有大量的重复冗余代码,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
**
import {mapState} from 'vuex'
export default {
name: "index",
computed:{
...mapState(['count']),
}
}
**
小结:使用 Vuex 并不意味着你需要将所有的状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。
4.2.getter
有的时候我们需要对共享状态里面的某一个属性做一些处理后再使用,我们可以把数据获取后再在组件的计算属性中处理,举个例子如下:
// store/index.js
state: {
count:,
numbers:[,,,,,,,,]
},
// Index组件
<template>
<div class="index">
{{count}}
<br>
{{numbers.join()}}
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "index",
computed:{
...mapState(['count']),
numbers(){
return this.$store.state.numbers.filter((item)=>{
return item>;
})
}
}
}
</script>
结果如下:

那么问题来了,如果多个组件都要做同样的处理,我们就需要把一份代码复制到多个地方,显然是不大合理的,于是有了getter,可以理解为组件里面的计算属性。示例如下:
/ store/index.js
getters: {
filterNumbers(state){
return state.numbers.filter((item)=>{
return item>;
})
}
},
// Index组件
<template>
<div class="index">
{{count}}
<br>
{{filterNumbers.join()}}
</div>
</template> <script>
import {mapState} from 'vuex'
export default {
name: "index",
computed:{
...mapState(['count']),
filterNumbers(){
return this.$store.getters.filterNumbers;
}
}
}
</script>
结果完全一样,我们可以根据this.$store.getters.属性名来获取getters,也可以通过mapGetters 辅助函数将 store 中的 getter 映射到局部计算属性:
具体实现方式如下:
<template>
<div class="index">
{{count}}
<br>
{{filterNumbers.join()}}
<br>
{{antherNumbers.join()}}
</div>
</template> <script>
import {mapState,mapGetters} from 'vuex'
export default {
name: "index",
computed:{
...mapState(['count']),6
...mapGetters(['filterNumbers']),
...mapGetters({
antherNumbers:'filterNumbers'
})
}
}
</script>
如果用同一名字直接把数组作为参数,如果想改一个名字,可以传入一个对象作为参数,结果如下:

4.3.mutation
在组件内,来自store的数据只能读取,不能手动改变,改变store中数据唯一的途径就是显示的提交mutations。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。改变代码如下:
// store/index.js
mutations: {
add(state){
state.count++;
}
}, // Index组件
**
<button @click="add">+</button>
**
methods:{
add(){
this.$store.commit('add');
console.log(this.count);
}
**

连续点击5次增加按钮,发现count的值也改变了。当然,我们也可以传参进去
// store/index.js
mutations: {
add(state,n){
state.count+=n;
}
}, // Index组件
**
<button @click="add">+</button>
**
methods:{
add(){
this.$store.commit('add',);
console.log(this.count);
}
**
触发方法语句为:this.$store.commit(方法名);也可以使用辅助函数mapMutations代替:
**
methods:{
...mapMutations(['add']),
}
**
4.4.action
前面我们讲过,mutation有必须同步执行这个限制,我们在业务需求中有时候需要在获取ajax请求数据之后再操作或定时器操作数据,这些都属于异步请求,要用actions来实现。具体实现如下:
// store/index.js
**
mutations: {
changeCount(state){
state.count=;
},
},
actions: {
changeCount3000s(context){
setTimeout(()=>{
context.commit('changeCount')
},) // Index组件
**
<button @click="changeCount3000s">点击按钮3s后count的值改变</button>
**
methods:{
...mapMutations(['add']),
changeCount3000s(){
this.$store.dispatch('changeCount3000s');
}
}
**
我们在点击按钮3s后count的值改变为3000,我们可以通过this.$store.dispatch(方法名)来触发事件,也可以通过辅助函数mapActions来触发。
**
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
**
methods:{
...mapMutations(['add']),
...mapActions(['changeCount3000s'])
}
**
学会以上几个属性的使用基本就可以满足平时业务中的需求了,但使用Vuex会有一定的门槛和复杂性,它的主要使用场景是大型单页面应用,如果你的项目不是很复杂,用一个bus也可以实现数据的共享,但是它在数据管理,维护,还只是一个简单的组件,而Vuex可以更优雅高效地完成状态管理,所以,是否使用Vuex取决于你的团队和技术储备。
参考资料:
《Vue.js实践》 Vuex
Vuex的初探与实战的更多相关文章
- Python爬虫 ---scrapy框架初探及实战
目录 Scrapy框架安装 操作环境介绍 安装scrapy框架(linux系统下) 检测安装是否成功 Scrapy框架爬取原理 Scrapy框架的主体结构分为五个部分: 它还有两个可以自定义下载功能的 ...
- 深入解析Vuex实战总结
这篇文章主要介绍了Vuex的初探与实战小结,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 1.背景 最近在做一个单页面的管理后台项目,为了提高开 ...
- 极客时间-vue开发实战学习(ant-design vue作者)
vue基础 属性 事件 插槽 指令(Directives) 生命周期 底层原理 vue生态 路由管理器vue Router 状态管理器vuex 同构Nuxt vue实战 实战项目-ant-desing ...
- 【原创】go语言学习(二十)并发编程
目录 并发和并行 Goroutine初探 Goroutine实战 Goroutine原理浅析 Channel介绍 Waitgroup介绍 Workerpool的实现 并发和并行 1.概念A. 并发:同 ...
- 物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探
物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探 唐朝实验室 · 2015/10/30 10:22 Author: FengGou 0x00 目录 0x00 目录 0x01 前言 0x02 BLE概 ...
- [vue最新实战] gank客户端(vue2 + vue-router2 + vuex +webpace + es6)新手福利,干货多多
vue-meizi 本项目是基于vue2最新实战项目,是适合新手进阶的绝佳教程.代码简单易懂,注释多多.实现了移动端使用最多的 无限滚动,图片加载,左右滑动,等待.先发布预览版本,后面更多更全的功能和 ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单
前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...
- vue+vue-router+vuex实战
shopping vue + vue-router + vuex实现电商网站 效果展示 install 下载代码: git clone https://github.com/chenchangyuan ...
- Vue 入门之 Vuex 实战
Vue 入门之 Vuex 实战 引言 Vue 组件化做的确实非常彻底,它独有的 vue 单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其 Vue 组件设计的就 ...
随机推荐
- Ext Js v6.2.0.103 Sencha Cmd 命令
Sencha Cmd v6.2.0.103 Sencha Cmd 提供几种全局开关命令. 在大多数案例中, 第一步是在Sencha SDK基础上创建应用 例如 Ext JS 或 Sencha Touc ...
- ccf 目录格式转换
任务背景: 在网络上获取的ccf目录的格式是PDF,但是要进行数据分析时,PDF格式的数据是不符合要求的,因此需要将pdf格式转化为excel格式 任务目的: 将pdf格式的CCF目录转化为excel ...
- 并查集(union-find set)与Kruskal算法
并查集 并查集处理的是集合之间的关系,即‘union' , 'find' .在这种数据类型中,N个不同元素被分成若干个组,每组是一个集合,这种集合叫做分离集合.并查集支持查找一个元素所属的集合和两个元 ...
- 用户注册登录系统 V2.0
# 准备空列表 users = [] # 准备当前在线用户 online_user = {} while True: # 打印系统提示 print("欢迎使用 用户注册登录系统V2.0&qu ...
- JS的事件绑定、事件流模型
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.JS事件 (一)JS事件分类 1.鼠标事件:click/dbclick ...
- Javassist字节码增强示例
概述 Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果.熟练使用这套工具,可以让Java编程更接近与动态语言编程. 下面一个方 ...
- mybatis一对一映射配置详解
听说mybatis一对一有三种写法,今天我试了一下. 数据库表准备 为了偷懒,我直接就拿用户权限菜单里的菜单表和菜单与权限的中间表做实现,他们原来是多对多的关系,这边我假设这两张表是一对一. 表 g ...
- java并发之TimeUnit理解
TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),在很长一段时间里Thread的sle ...
- 深入出不来nodejs源码-编译启动(1)
整整弄了两天,踩了无数的坑,各种奇怪的error,最后终于编译成功了. 网上的教程基本上都过时了,或者是版本不对,都会报一些奇怪的错误,这里总结一下目前可行的流程. node版本:v10.1.0. 首 ...
- 通过VirtualBox安装Linux系统(CentOS7)
本文目的:创建虚拟系统.在windows系统中通过虚拟工具VirtualBox创建一个虚拟系统CentOS. 备注:(1)版本如下:VirtualBox-5.2.12-122591-Win 和Cent ...