Vue学习日记(四)——Vue状态管理vuex
前言
先说句前话,如果不是接触大型项目,不需要有多个子页面,不使用vuex也是完全可以的。
说实在话,我在阅读vuex文档的时候,也很难以去理解vuex,甚至觉得没有使用它我也可以。但是直到我在项目碰到下面这些问题:
- 当路由切换的时候,原本路由的数据太多,传递过去太麻烦。
- 有些数据是多个路由需要用到的,那我就需要从后台获取多次数据
当然,这些问题都可以解决,就是在实例化vue对象的时候,就将这些数据绑定在window对象上面。但是我们也不得不设想:
- 万一数据太多了,那么可阅读性是不是会下降
- 如果只是修改单独的数据,是不是所有的页面都可以更新
对于第一个问题,答案是肯定的,虽然说,我们现在也可以用模块化的思想去使可阅读性更加好,但是没有一个规范,对于刚入手项目的总是难以理解。
对于第二个问题,当你页面少的时候,是不会出现这样的问题的,但是如果页面多了,你就会发现,当你把window.$data里面的数据更新的时候,所有页面的计算属性都会失效,就是你无论怎么修改数据,页面都不会更新数据。
这时候,就需要用到我们的vuex了。
vuex介绍
那么vuex 到底是什么?
引用官网的说法就是Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
是不是还是有点难以理解,其实简单的说vuex就是把这个项目的所有数据都存储在一个地方,方便修改和获取数据。
例如,我们从下面这张图给大家先简单的分析一下

在这张图片里面我们很明显可以看到三个部分
- Vue Components 表示vue里面的组件
- Backend API 后台API
- vuex 组件里面的数据管理
我们可以生动形象的理解,如果说Vuex是一个仓库,那么么Vue Components就就是售货者,负责把仓库里面的东西展现出来,Backend API就相当于入货的人,负责将货物买进来(也就是后台返回数据给前端,保存在vuex里面)。而vuex就是仓库,这个仓库里面有货物state,有管理货物进出的Muations
引用vuex
在说state之前,我们可以先在我们vue项目引用vuex
npm install vuex
然后在我们的src目录下新建一个store的文件夹,在store文件夹里面新建一个index.js的文件
// ~/src/store/index.js
import Vue from 'Vue'
import Vuex from 'Vuex'
// 在这里声明实例一个Vue 去引用Vuex状态管理插件
// 这样就可以减少在main.js里面的代码量了
Vue.use(Vuex)
// 返回store实例对象
export default new Vuex.Store({
})
这里说一下吧,这里Store其实就是相当vuex实例化的一个仓库。
data替代者state
为什么说state是data的替代者呢?
很容易理解,就是讲组件里面的局部参数,改成了一个可以全局使用的参数state,例如,我们在me.vue组件引用的数据todo。
那么我们可以在store里面这样实例化它出来
// ~/src/store/index.js
// ...
export default new Vuex.Store({
state: {
todo: []
}
})
那么,我们在组件里面怎么使用这个数据呢?
// me.vue组件文件
// ...
<script type="text/ecmascript-6">
export default {
data() {
meTodo: [] // 然后在方法里面引用this.meTodo = this.$store.state.todo
}
}
</script>
// ...
是不是很简单,但是我们不可能每次使用这个值都要获取一次吧,这些vue团队也都想好了,我们可以通过计算属性来获取state里面的数据。
// ...
<script type="text/ecmascript-6">
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
computed: mapState([
// 映射 this.todo 为 store.state.todo
'todo'
])
}
</script>
// ...
相当于
// ...
<script type="text/ecmascript-6">
export default {
computed:
todo () {
return this.$store.state.todo
}
])
}
</script>
// ...
计算属性Getter
有时候我们会需要对state的数据进行一些过滤操作,例如我们只要在todo里面大于10的数字,如果是用computed的话,我们就需要使用filter函数,为了更加简便,vuex也给我们提供了计算属性getter。
我们可以修改我们的~/src/store/index文件
// ...
export default new Vuex.Store({
state: {
todo: []
},
getters: {
todo: state => state.todo.filter(number => number > 10)
}
})
然后在me.vue里面引用
// ...
<script type="text/ecmascript-6">
// 在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
// 映射 this.todo 为 store.state.todo
'todo'
])
}
}
</script>
// ...
这样就可以简单拿到大于10的todo数据了
修改state的Mutation
我们说了怎么获取数据,但是我们应该怎么修改数据呢,是不是直接赋值给数据就可以了呢?
答案当然不是,vuex规定了,我们只能用Mutation来进行修改数据,那么,我们怎么进行修改数据呢?
修改我们的~/src/store/index.js
// ...
export default new Vuex.Store({
state: {
todo: []
},
getters: {
todo: state => state.todo.filter(number => number > 10)
},
mutations: {
revsiseTode: (state, oneTodo) => (state.todo = oneTodo) // 修改state的值
}
})
然后在我们的me.vue组件里面修改
// ...
// 在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
// 在单独构建的版本中辅助函数为 Vuex.mapMutations
import { mapMutations } from 'vuex'
export default {
computed: {
...mapGetters([
// 映射 this.todo 为 store.state.todo
'todo'
])
},
method: {
...mapMutations(
[
// 将 `this.revsiseTode()` 映射为 `this.$store.commit('revsiseTode')`
// 如果想传递参数可以使用this.$store.commit('revsiseTode', oneTode)
// 或者Action
'revsiseTode'
]
)
}
}
Action的使用
写了这么久,终于到了Action的出场了,其实不管怎么说,Action主要是为了与后台交互而使用的属性,这里,我就假设todo的数据在路由/me/gettodo里面能够获取,因此,修改~/store/index.js
// ...
export default new Vuex.Store({
state: {
todo: []
},
getters: {
todo: state => state.todo.filter(number => number > 10)
},
mutations: {
revsiseTode: (state, oneTodo) => (state.todo = oneTodo) // 修改state的值
},
actions: {
getTodo: context => Vue.http.get('/me/gettodo', (res) => {
context.commit('revsiseTode', res.body.todo)
})
}
})
然后就可以通过触发我们的actions来提交mutations去修改state的数据了,在me.vue修改
// ...
// 在单独构建的版本中辅助函数为 Vuex.mapGetters
import { mapGetters } from 'vuex'
// 在单独构建的版本中辅助函数为 Vuex.mapMutations
import { mapActions } from 'vuex'
export default {
computed: {
...mapGetters([
// 映射 this.todo 为 store.state.todo
'todo'
])
},
method: {
...mapActions(
[
'reviseTodo', // 将 `this.reviseTodo()` 映射为 `this.$store.dispatch('reviseTodo')
]
)
}
}
// ...
vuex目录结构
上面主要只是简单的讲了一下vuex的使用,也只是讲了一部分,不过相信看了这里之后再去官网就会有更深的理解。当然这些都是简单的使用,如果想把vuex运用到项目,必须把他们模块化更加好看,vuex官网也为我们提供了规范的项目目录结构,我这里就不多啰嗦几句了。
总结
vuex其实不难,我一开始也以为很难一直学不会,只要多使用就会觉得,其实也就只是别人都封装好了的方法,我们去使用这个简便的仓库就行了。
Vue学习日记(四)——Vue状态管理vuex的更多相关文章
- Vue状态管理vuex
前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...
- Vue之状态管理(vuex)与接口调用
Vue之状态管理(vuex)与接口调用 一,介绍与需求 1.1,介绍 1,状态管理(vuex) Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态 ...
- day 82 Vue学习三之vue组件
Vue学习三之vue组件 本节目录 一 什么是组件 二 v-model双向数据绑定 三 组件基础 四 父子组件传值 五 平行组件传值 六 xxx 七 xxx 八 xxx 一 什么是组件 首先给 ...
- 状态管理Vuex
路由Router 配置 {path:'/login',component:Login} 路由出口 router-view 传参 {path:'/login/:id',component:Login} ...
- day 81 Vue学习一之vue初识
Vue学习一之vue初识 本节目录 一 Vue初识 二 ES6的基本语法 三 Vue的基本用法 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 vue初识 vue称为渐进式js ...
- day 80 Vue学习一之vue初识
Vue学习一之vue初识 本节目录 一 Vue初识 二 ES6的基本语法 三 Vue的基本用法 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 vue初识 vue称为渐进式js框架 ...
- day 82 Vue学习二之vue结合项目简单使用、this指向问题
Vue学习二之vue结合项目简单使用.this指向问题 本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...
- day 81 Vue学习二之vue结合项目简单使用、this指向问题
Vue学习二之vue结合项目简单使用.this指向问题 本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...
- vue中状态管理vuex的使用分享
一.main.js中引入 store import store from './store' window.HMO_APP = new Vue({ router, store, render: h = ...
随机推荐
- TP5模型belongsTo和hasOne这两个方法的区别
在使用tp5模型的ORM的时候出现belongsTo和hasOne都有表示一对一的关系,但是二者并不相同.以下举例说明两者的区别: 首先有user表 字段 id name password字段 然后有 ...
- python常见队列queue分类
import queue # 1.普通q# 2.先进后出q# 3.优先级q 普通Queue q=queue.Queue(3)q.put(1)q.put(2)q.put(3)print(q.get()) ...
- python中 __file__的小坑坑
在python脚本中,我们难免会需要用到自身文件所在的绝对路径,第一想法可能就是用os.path.dirname(__file__) 但是这里有个大坑,我就踩了,这种方式得到路径会出现问题,脚本执行报 ...
- 使用Java实现hello/hi的简单网络聊天程序
Socket又称套接字,是基于应用服务与TCP/IP通信之间的一个抽象,它是计算机之间进行通信的一种约定或一种方式.通过socket这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送 ...
- bootstrap-table服务端分页操作
由于数据库查询的数据过多,所以采取服务端分页的操作,避免一次性加载的数据量过多,导致页面加载缓慢. 后端数据的封装格式json数据 rows里的数据是当前页的数据,total是总条数: { " ...
- Java基础 面试总结(一)
一.java基础篇-概念 1.简述你所知道的Linux: Linux起源于1991年,1995年流行起来的免费操作系统,目前, Linux是主流的服务器操作系统, 广泛应用于互联网.云计算.智能手机( ...
- 拜托,别再问我 QPS、TPS、PV、UV、GMV、IP、RPS 好吗?
关于 QPS.TPS.PV.UV.GMV.IP.RPS 这些词语,看起来好像挺专业.但实际上,我认为是这是每个程序员必懂的知识点了,你可以搞不懂它们怎么计算的,但是你最少要知道它们分别代表什么意思吧? ...
- 并不对劲的复健训练-bzoj5253:loj2479:p4384:[2018多省联考]制胡窜
题目大意 给出一个字符串\(S\),长度为\(n\)(\(n\leq 10^5\)),\(S[l:r]\)表示\(S_l,S_{l+1}...,S_r\)这个子串.有\(m\)(\(m\leq 3\t ...
- .Net面试题四
1.C#编译成的dll存放在哪个目录?C#程序文件的后缀名是什么?.csproj后缀名是什么文件? 2.请写出C#中常用文件操作类.数据库操作类.网络请求类.每项至少写出三个 3.请定义一个只读属性: ...
- 怎样使用 v-if 实现 html 元素的显示 / 隐藏?
1. 首先, 指令后的引号内是可以写 js 表达式的, 这点很重要. v-if 的用法很简单, 只需要给 v-if = " " 的引号内放一个 布尔值 即可. 注意: v-if 的 ...