前言

先说句前话,如果不是接触大型项目,不需要有多个子页面,不使用vuex也是完全可以的。

说实在话,我在阅读vuex文档的时候,也很难以去理解vuex,甚至觉得没有使用它我也可以。但是直到我在项目碰到下面这些问题:

  1. 当路由切换的时候,原本路由的数据太多,传递过去太麻烦。
  2. 有些数据是多个路由需要用到的,那我就需要从后台获取多次数据

当然,这些问题都可以解决,就是在实例化vue对象的时候,就将这些数据绑定在window对象上面。但是我们也不得不设想:

  1. 万一数据太多了,那么可阅读性是不是会下降
  2. 如果只是修改单独的数据,是不是所有的页面都可以更新

对于第一个问题,答案是肯定的,虽然说,我们现在也可以用模块化的思想去使可阅读性更加好,但是没有一个规范,对于刚入手项目的总是难以理解。

对于第二个问题,当你页面少的时候,是不会出现这样的问题的,但是如果页面多了,你就会发现,当你把window.$data里面的数据更新的时候,所有页面的计算属性都会失效,就是你无论怎么修改数据,页面都不会更新数据。

这时候,就需要用到我们的vuex了。

vuex介绍

那么vuex 到底是什么?

引用官网的说法就是Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

是不是还是有点难以理解,其实简单的说vuex就是把这个项目的所有数据都存储在一个地方,方便修改和获取数据

例如,我们从下面这张图给大家先简单的分析一下

在这张图片里面我们很明显可以看到三个部分

  1. Vue Components 表示vue里面的组件
  2. Backend API 后台API
  3. vuex 组件里面的数据管理

我们可以生动形象的理解,如果说Vuex是一个仓库,那么么Vue Components就就是售货者,负责把仓库里面的东西展现出来,Backend API就相当于入货的人,负责将货物买进来(也就是后台返回数据给前端,保存在vuex里面)。而vuex就是仓库,这个仓库里面有货物state,有管理货物进出的Muations

引用vuex

在说state之前,我们可以先在我们vue项目引用vuex

  1. npm install vuex

然后在我们的src目录下新建一个store的文件夹,在store文件夹里面新建一个index.js的文件

  1. // ~/src/store/index.js
  2. import Vue from 'Vue'
  3. import Vuex from 'Vuex'
  4. // 在这里声明实例一个Vue 去引用Vuex状态管理插件
  5. // 这样就可以减少在main.js里面的代码量了
  6. Vue.use(Vuex)
  7. // 返回store实例对象
  8. export default new Vuex.Store({
  9. })

这里说一下吧,这里Store其实就是相当vuex实例化的一个仓库。

data替代者state

为什么说state是data的替代者呢?

很容易理解,就是讲组件里面的局部参数,改成了一个可以全局使用的参数state,例如,我们在me.vue组件引用的数据todo。

那么我们可以在store里面这样实例化它出来

  1. // ~/src/store/index.js
  2. // ...
  3. export default new Vuex.Store({
  4. state: {
  5. todo: []
  6. }
  7. })

那么,我们在组件里面怎么使用这个数据呢?

  1. // me.vue组件文件
  2. // ...
  3. <script type="text/ecmascript-6">
  4. export default {
  5. data() {
  6. meTodo: [] // 然后在方法里面引用this.meTodo = this.$store.state.todo
  7. }
  8. }
  9. </script>
  10. // ...

是不是很简单,但是我们不可能每次使用这个值都要获取一次吧,这些vue团队也都想好了,我们可以通过计算属性来获取state里面的数据。

  1. // ...
  2. <script type="text/ecmascript-6">
  3. // 在单独构建的版本中辅助函数为 Vuex.mapState
  4. import { mapState } from 'vuex'
  5. export default {
  6. computed: mapState([
  7. // 映射 this.todo 为 store.state.todo
  8. 'todo'
  9. ])
  10. }
  11. </script>
  12. // ...

相当于

  1. // ...
  2. <script type="text/ecmascript-6">
  3. export default {
  4. computed:
  5. todo () {
  6. return this.$store.state.todo
  7. }
  8. ])
  9. }
  10. </script>
  11. // ...

计算属性Getter

有时候我们会需要对state的数据进行一些过滤操作,例如我们只要在todo里面大于10的数字,如果是用computed的话,我们就需要使用filter函数,为了更加简便,vuex也给我们提供了计算属性getter。

我们可以修改我们的~/src/store/index文件

  1. // ...
  2. export default new Vuex.Store({
  3. state: {
  4. todo: []
  5. },
  6. getters: {
  7. todo: state => state.todo.filter(number => number > 10)
  8. }
  9. })

然后在me.vue里面引用

  1. // ...
  2. <script type="text/ecmascript-6">
  3. // 在单独构建的版本中辅助函数为 Vuex.mapGetters
  4. import { mapGetters } from 'vuex'
  5. export default {
  6. computed: {
  7. ...mapGetters([
  8. // 映射 this.todo 为 store.state.todo
  9. 'todo'
  10. ])
  11. }
  12. }
  13. </script>
  14. // ...

这样就可以简单拿到大于10的todo数据了

修改state的Mutation

我们说了怎么获取数据,但是我们应该怎么修改数据呢,是不是直接赋值给数据就可以了呢?

答案当然不是,vuex规定了,我们只能用Mutation来进行修改数据,那么,我们怎么进行修改数据呢?
修改我们的~/src/store/index.js

  1. // ...
  2. export default new Vuex.Store({
  3. state: {
  4. todo: []
  5. },
  6. getters: {
  7. todo: state => state.todo.filter(number => number > 10)
  8. },
  9. mutations: {
  10. revsiseTode: (state, oneTodo) => (state.todo = oneTodo) // 修改state的值
  11. }
  12. })

然后在我们的me.vue组件里面修改

  1. // ...
  2. // 在单独构建的版本中辅助函数为 Vuex.mapGetters
  3. import { mapGetters } from 'vuex'
  4. // 在单独构建的版本中辅助函数为 Vuex.mapMutations
  5. import { mapMutations } from 'vuex'
  6. export default {
  7. computed: {
  8. ...mapGetters([
  9. // 映射 this.todo 为 store.state.todo
  10. 'todo'
  11. ])
  12. },
  13. method: {
  14. ...mapMutations(
  15. [
  16. // 将 `this.revsiseTode()` 映射为 `this.$store.commit('revsiseTode')`
  17. // 如果想传递参数可以使用this.$store.commit('revsiseTode', oneTode)
  18. // 或者Action
  19. 'revsiseTode'
  20. ]
  21. )
  22. }
  23. }

Action的使用

写了这么久,终于到了Action的出场了,其实不管怎么说,Action主要是为了与后台交互而使用的属性,这里,我就假设todo的数据在路由/me/gettodo里面能够获取,因此,修改~/store/index.js

  1. // ...
  2. export default new Vuex.Store({
  3. state: {
  4. todo: []
  5. },
  6. getters: {
  7. todo: state => state.todo.filter(number => number > 10)
  8. },
  9. mutations: {
  10. revsiseTode: (state, oneTodo) => (state.todo = oneTodo) // 修改state的值
  11. },
  12. actions: {
  13. getTodo: context => Vue.http.get('/me/gettodo', (res) => {
  14. context.commit('revsiseTode', res.body.todo)
  15. })
  16. }
  17. })

然后就可以通过触发我们的actions来提交mutations去修改state的数据了,在me.vue修改

  1. // ...
  2. // 在单独构建的版本中辅助函数为 Vuex.mapGetters
  3. import { mapGetters } from 'vuex'
  4. // 在单独构建的版本中辅助函数为 Vuex.mapMutations
  5. import { mapActions } from 'vuex'
  6. export default {
  7. computed: {
  8. ...mapGetters([
  9. // 映射 this.todo 为 store.state.todo
  10. 'todo'
  11. ])
  12. },
  13. method: {
  14. ...mapActions(
  15. [
  16. 'reviseTodo', // 将 `this.reviseTodo()` 映射为 `this.$store.dispatch('reviseTodo')
  17. ]
  18. )
  19. }
  20. }
  21. // ...

vuex目录结构

上面主要只是简单的讲了一下vuex的使用,也只是讲了一部分,不过相信看了这里之后再去官网就会有更深的理解。当然这些都是简单的使用,如果想把vuex运用到项目,必须把他们模块化更加好看,vuex官网也为我们提供了规范的项目目录结构,我这里就不多啰嗦几句了。

总结

vuex其实不难,我一开始也以为很难一直学不会,只要多使用就会觉得,其实也就只是别人都封装好了的方法,我们去使用这个简便的仓库就行了。

Vue学习日记(四)——Vue状态管理vuex的更多相关文章

  1. Vue状态管理vuex

    前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...

  2. Vue之状态管理(vuex)与接口调用

    Vue之状态管理(vuex)与接口调用 一,介绍与需求 1.1,介绍 1,状态管理(vuex) Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态 ...

  3. day 82 Vue学习三之vue组件

      Vue学习三之vue组件   本节目录 一 什么是组件 二 v-model双向数据绑定 三 组件基础 四 父子组件传值 五 平行组件传值 六 xxx 七 xxx 八 xxx 一 什么是组件 首先给 ...

  4. 状态管理Vuex

    路由Router 配置 {path:'/login',component:Login} 路由出口 router-view 传参 {path:'/login/:id',component:Login} ...

  5. day 81 Vue学习一之vue初识

      Vue学习一之vue初识   本节目录 一 Vue初识 二 ES6的基本语法 三 Vue的基本用法 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 vue初识 vue称为渐进式js ...

  6. day 80 Vue学习一之vue初识

    Vue学习一之vue初识   本节目录 一 Vue初识 二 ES6的基本语法 三 Vue的基本用法 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 vue初识 vue称为渐进式js框架 ...

  7. day 82 Vue学习二之vue结合项目简单使用、this指向问题

    Vue学习二之vue结合项目简单使用.this指向问题   本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...

  8. day 81 Vue学习二之vue结合项目简单使用、this指向问题

    Vue学习二之vue结合项目简单使用.this指向问题   本节目录 一 阶段性项目流程梳理 二 vue切换图片 三 vue中使用ajax 四 vue实现音乐播放器 五 vue的计算属性和监听器 六 ...

  9. vue中状态管理vuex的使用分享

    一.main.js中引入 store import store from './store' window.HMO_APP = new Vue({ router, store, render: h = ...

随机推荐

  1. java 重写的 几大注意点

    Single Dispatch class Parent { void print(String a) { log.info("Parent - String"); } void ...

  2. 消息中间件RabbitMq的代码使用案例

    消费者: ---------------------- 构造初始化: public RabbitMqReceiver(String host, int port, String username, S ...

  3. Second largest node in the BST

    Find the second largest node in the BST 分析: 如果root有右节点,很明显第二大的node有可能在右子树里.唯一不满足的条件就是右子树只有一个node. 这个 ...

  4. Navicat远程无法创建数据库

    Navicat远程无法创建数据库 提示报错信息如下,说明是用户创建的权限不足. Error Code: 1044. Access denied for user 'root'@'%' to datab ...

  5. PAT A1011 World Cup Betting(20)

    AC代码 #include <cstdio> #include <algorithm> const int max_n = 3; using namespace std; /* ...

  6. winform中如何使用timer控件实现欢迎(初始加载)窗口

    第一步.新建窗体项目命名为:TestWelcomeFrm,如下图: 第二步.在新项目中,增加欢迎窗口,命名为WelFrm,整个项目目录如下: 第三步.修改program.cs中启动代码如下: WelF ...

  7. 一次生产的JVM优化

    背景 生产环境有二台阿里云服务器,均为同一时期购买的,CPU.内存.硬盘等配置相同.具体配置如下: 节点 CPU 内存 硬盘 其它 A 2CPU 4G 普通云盘 Centos6.4 64位+JDK1. ...

  8. WebMvcConfigurationSupport跨域和fastjson全局替换

    @Configuration public class WarnWebMvcConfigurationSupport extends WebMvcConfigurationSupport { /** ...

  9. CSS和DOM入门

    CSS补充: - position - background - hover - overflow - z-index - opacity 示例:输入框右边放置图标 JavaScript: 局部变量 ...

  10. 牛客 158F 青蛙 (贪心)

    显然存在一个最优解满足所有青蛙在连续的一段, 每次由最左侧青蛙跳向下一格. 然后二分或者双指针即可求出答案. #include <iostream> #include <sstrea ...