Xin's blog Xin's blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
    • 组件与插件
    • CSS扩展语言
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架面试题汇总
  • 基本面试题
  • 进阶面试题
  • 其它
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 前后端联调
  • mock.js
  • 奇技淫巧
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

Xin

英雄可不能临阵脱逃啊~
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
    • 组件与插件
    • CSS扩展语言
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架面试题汇总
  • 基本面试题
  • 进阶面试题
  • 其它
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 前后端联调
  • mock.js
  • 奇技淫巧
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

  • Vue

    • 知识点

      • filters过滤器的使用
      • watch的使用
      • createElement函数创建虚拟DOM
      • mixin的使用
      • 插槽
      • vuex的基本使用
        • 什么是vuex
        • vuex的核心概念
        • 安装
        • 使用
        • store中变量的定义、管理、派生(getter)
        • vuex刷新页面丢失问题处理
        • 实例
      • 路由传参
      • 组件通信之 $attrs 和 $listeners
      • 组件通信之 $parent 和 $children
      • 组件通信之 provide 和 inject
      • 使用vue的model选项实现组件通信
      • v-on监听多个方法
      • axios的基本使用
      • vue中的鼠标事件、鼠标滚轮事件、键盘事件
      • Vue为什么要求组件模板只能有一个根元素
      • Vue中data为什么必须是一个函数?
      • Vue中的scoped和scoped穿透
      • vue-router传参,在页面刷新后数据格式改变的问题
      • 相同的组件,vue会直接复用
      • Vue项目使用mock数据的几种方式
      • Vue CLi3 修改webpack配置
    • 方法

    • vue API

  • 组件与插件

  • css扩展语言

  • 学习笔记

  • 前端
  • Vue
  • 知识点
ctrlwin
2021-03-24

vuex的基本使用

# 什么是vuex

Vuex 是专门为 Vue.js 设计的状态管理库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

简单地说就是采用全局单例模式,将组件的共享状态抽离出来管理,使组件树中的每一个位置都可以获取共享的状态(变量)或者触发行为。

或者更直白的说就是响应式的全局变量

# vuex的核心概念

方法 作用
state 共享状态(即变量)
Getter 基于state的派生状态,可理解为组件中的计算属性
Mutation 更改vuex的store中状态的唯一方法,通过提交mutation修改状态,同步操作(规则上是不允许异步操作的,虽然异步也可以执行,但是对devtool调试的状态跟踪或多个状态更改操作相互依赖是很不好的,所以不要觉得只要不报错我就可以这么用,还是尽量按照规则来比较好)
Action 类似mutation,不同之处,1.通过提交mutation修改状态 2.支持异步操作
Module 模块,在大型项目中为了方便状态的管理和协作开发将store拆分为多个子模块(modules),每个子模块拥有完整的state、mutation、action、getter

# 安装

npm install vuex --save

# 使用

新建store文件夹并新建index.js,引入vue和vuex

image-20201229171816800

在main.js中注册sotre

image-20201229171851383

# store中变量的定义、管理、派生(getter)

  1. state--状态

    我们在state中定义属性name,给一个初始值 “张三”;在store实例中注册state;

    在组件中使用$store.state.name使用定义的属性name

    image-20201229172231316
  2. mutations--更改store中状态的唯一方法

    之所以说唯一,是因为vuex中规定只能通过提交mutation的方式去更改store中的状态,包括action中的操作,也是通过提交mutation去修改。

    另外一点就是vuex中规定mutation中不能包含异步操作。

image-20201229172246611

总结:

✦.mutation下事件的调用是通过 this.$store.commit 传入对应的type调用,关于辅助函数 mapMutations 的使用在后面一期讲解

✦.mutation下事件的定义分为无参的和有参的两种形式

✦.mutation事件的调用有两种形式,载荷和对象

  1. action--异步更改状态

上面在mutation的介绍中我们提到了,mutation中规则上是不允许异步操作的,那如果我们需要异步的进行更改状态怎么办?于是vuex为我们提供了action。

image-20201229172704136

总结:

✦.action中不能直接更改状态,它是通过提交mutation来实现操作

✦.它的参数是一个与 store 实例具有相同方法和属性的 context 对象,所以可以通过context.state来获取store中的状态,可以通过context.commit来提交更改等

✦.action的调用使用 $.store.dispatch

✦.action事件的定义分为有参和无参两种

✦.action事件的触发同样可以使用载荷和对象两种方式

  1. getter--store中state的派生状态

    getter,我们可以理解为是对store中state的一些派生状态,也可以理解为一种计算属性,因为它像计算属性一样,返回值会根据它的依赖被缓存起来,且依赖对象发生改变的时候它才会被重新计算。

    getter的使用对我来讲就是将对store中某个属性相同的处理操作抽出出来,做了一个公共的处理

    例如,我们使用store中name的时候,需要做一个判断:如果是张三,返回“张三最棒”,其它的原样返回,我们可以这样做

img

页面上将 this.$store.state.name 改为 formatterName即可。但是,如果我们这个操作不只这一个组件使用,那我们就需要在每一个组件中去定义这样一个计算属性,且不说代码冗余的问题,后期如果要更新后缀,想想吧,挨着一个一个组件的去巴拉。。。

而使用getter则可以很好的解决这个问题,不仅代码简洁,也利于维护,不多说,上getter使用代码:

image-20201229173032418

总结:

✦.getter类似计算属性,是对store中state的一些派生状态,可以简化代码、便于维护

✦.getter的使用方法 $.store.getters.属性名

✦.getter的定义可以带参可以不带参

关于module,它是对store的一个分割,将store分割成一个个小的模块,每个模块中又具有store完整的功能。

  1. vuex辅助函数

vuex的辅助函数有:mapState、mapMutations、mapGetters、mapActions

  • state的辅助函数需要映射到计算属性中computed,映射的名称一定要相同,然后就可以通过this访问到state。
  • mutation的辅助函数mapMutations把mutations里面的方法映射到methods中。映射的名称一定要相同,然后就可以通过this调用mutaition的方法。
  • mapAcions:把actions里面的方法映射到methods中
  • mapGetters:把getters属性映射到computed身上

它们的使用我们可以配合ES6的展开运算符将其与局部计算属性或方法混合使用。使用辅助函数后我们对state、mutation、getter、actiopn的使用可以改成以下这样:

img

# vuex刷新页面丢失问题处理

vuex在页面刷新后,store中的状态将被重新初始化,赋值的数据丢失,针对这个问题怎么处理呢?

我们可以这样处理,在页面刷新或离开之前将store中的数据保存到sessionStorage 或 localStorage中,在页面重新加载后再将数据取出,通过vuex的$store.replaceState 将数据替换到store中,上代码

created () {
    var store = require('store');

    //在页面加载时读取sessionStorage里的状态信息
    if (sessionStorage.getItem("storedata") ) {
        this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("storedata"))))
    }
    //在页面刷新时将vuex里的信息保存到sessionStorage里
    window.addEventListener("beforeunload",()=>{
        sessionStorage.setItem("storedata",JSON.stringify(this.$store.state))
    });
    // 兼容iphone手机
    window.addEventListener("pagehide",()=>{
        sessionStorage.setItem("storedata",JSON.stringify(this.$store.state))
    });
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 实例

遇到一个bug如下:

通过tabbar底部导航栏从首页切出去以后再切回来,首页数据就请求不到了

原因是:首页数据是根据上一个页面路由携带的id来请求的,如果从其他页面切换到首页没有携带id,那么首页就会请求不到数据

解决办法:可以在首页请求完数据以后保存一个变量到vuex,然后在路由跳转时,将vuex中保存的变量通过query传入。

在首页中

import {mapMutations} from 'vuex'
...
methods:{
// 通过mapMutations获取mutations中的方法
...mapMutations(['SAVE_GEOHASH']),
// 将geohash保存到vuex中
this.SAVE_GEOHASH(this.geohash)
}
1
2
3
4
5
6
7
8

在vuex中

// mutations
import {SAVE_GEOHASH} from "./mutation-types";

export default {
    // 保存geohash
    [SAVE_GEOHASH](state, geohash) {
        state.geohash = geohash
        console.log(state.geohash)
    }
}
1
2
3
4
5
6
7
8
9
10

在tabbar中

import {mapState} from 'vuex'
...
methods: {
    // 通过mapState获取保存在vuex中的geohash
    ...mapState(['geohash']),
    itemClick(geoHash) {
  	  // 当回到esite页时需要重新传递geoHash
   	  if (this.path === '/esite') {
  	       this.$router.push({path: this.path, query: {geoHash}})
 	  } else {
           this.$router.push(this.path)
      }
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
在GitHub上编辑 (opens new window)
#vue
上次更新: 2/23/2022, 5:36:03 PM

← 插槽 路由传参→

最近更新
01
createElement函数创建虚拟DOM
05-26
02
clipboard 剪切板属性
05-26
03
vue的权限管理
05-16
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Xin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×