vuex通过getters访问数据为undefined问题及解决

目录
  • getters访问数据为undefined问题
    • 写一个类似例子
  • vuex getters(组件mounted调用)使用注意
    • 逻辑
    • 解决方案

getters访问数据为undefined问题

本篇文章可能对你的帮助不大, 只是个人开发中的一些记录。不同的业务和应用场景可能问题不同。

在通过 uni-app 开发商城时,用户快捷登录之后,服务器返回一个 token 数据,我将其同步到 vuex module下的 user 模块中。

然后从登录页返回到用户页,并发起 http 请求,获取用户的个人信息。

但是在请求时,我会在请求拦截器中获取 vuex 中的 token 数据。如果存在就携带到请求头中和服务器做 OAuth 验证。如果不存在就直接不携带 token。

用户登录成功之后,返回到用户页发起请求,但是获取用户信息接口是必须做 OAuth 验证的。问题在于在请求拦截器中 不能通过 vuex 的 getter 正确获取到 token值,而是返回 undefined。

request.js

import Http from "../xxx/http";
import store from "../sotre";
const request = new Http({
  baseURL: xxxxx,
  timeout: 50000,
  // 省略
});
request.interceptors.request.use((config) => {
  let token, g_t;
  if (
    (g_t = store.getters[`user/token`]) ||
    (g_t = Storage.get(USER_TOKEN_KEY))
  ) {
    token = g_t.token || null;
  }
  if (token) {
    config.header["Authorization"] = "Bearer " + token;
  }
  return config;
});

问题在于 g_t = store.getters[user/token] 获取的值为 undefined。

经过排查发现,vuex 中 getters 下的通过 state 获取的字段实现没有在 state 中定义。而是通过异步登录之后,才将其设置到 user 模块下的 state 中,使其变为不是响应式的。

写一个类似例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <p>姓名: {{ realName }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.3.0/dist/vuex.js"></script>
<script type="module">
  Vue.use(Vuex);
  const store = new Vuex.Store({
    state: {},
    mutations: {
      change(state, data) {
        state.name = data;
      }
    },
    getters: {
      name: state => {
        return state.name;
      }
    }
  });
  new Vue({
    el: "#app",
    store,
    data: {
      message: "Hello"
    },
    computed: {
      realName() {
        return this.$store.getters.name;
      }
    },
    created() {
      setTimeout(() => {
        this.$store.commit('change', 'zhangsan');
      })
    }
  })
</script>
</body>
</html>

异步代码执行的时候, state 中并没有 name 属性。所以一开始 getters 下的 realName 就算是 undefined。异步代码提交的 commit,在想 state 中新增 name 字段,但是它已不是响应式的。

解决方法:

就是提前在 state 中定义 getters 需要的某些字段,异步变更 state 中的字段它也是响应式的。getters 的值也会进行计算。

getters 类似于 vue 中的计算属性。

修改上面的代码为:

const store = new Vuex.Store({
    state: {
        name: ""
    },
    // 省略...
  })  

这样 getters 的值会根据 name的值改变而进行计算。

项目中的代码比上面的例子更复杂,但是问题是类似的。经过排查后才发现,所以在博客中总结一下。

小结:使用 vuex 时, getters 中需要计算的 state 属性一定要提前声明,使其成为响应式的值。

vuex getters(组件mounted调用)使用注意

逻辑

  • state存储数据(一开始为空数据,通过网络请求后更新数据)
  • 在组件mounted中先调用actions方法通过mutations更新state数据,
  • 接着组件mounted在调用getters 操作state中的数据,供组件使用
mounted(){
    // 进入组件立即发送网络请求获取商品信息
    this.$store.dispatch('detail/getCommdityInfo',this.skuId)
    console.log(this.skuInfo) //为undefined
    console.log(this.cateNav) //控制台报错
}
state: {
    commdityData:{}
  },
  mutations: {
    SET_COMMDITY_LIST(state,value){
      state.commdityData = null
      // 将商品信息存入组件内
      state.commdityData = value
      console.log('state.commdityData',state.commdityData)
    }
  },
  actions: {
    async getCommdityInfo(context,query){
      const res = await getCommdityDetail(query)
      context.commit('SET_COMMDITY_LIST',res.data.data)
    }
  },
  getters:{
    skuInfo:state => state.commdityData.skuInfo,
    cateNav:state => {
        const {category1Name,category2Name,category3Name} = state.commdityData.categoryView
        return [category1Name,category2Name,category3Name]
    },

  }

结果报错:组件在mouted 调用getters属性时,getters属性读取state数据(一开始为空),读取不到数据

**原因:**组件调用actions执行异步网络请求,通过mutations更新state数据还没有来得及执行

解决方案

更改getters中操作数据的属性,try-catch错误处理

cateNav:state => {
      // 使用情景,组件在mounted中调用,getters 的属性时,此时state未更新;解构会出错,所以要错误处理!!
      try{
        const {category1Name,category2Name,category3Name} = state.commdityData.categoryView
        return [category1Name,category2Name,category3Name]
      }
      catch{
        return {}
      }
    },

!!!注意:在组件的methods中写方法调用则可正常使用getters的数据!!

控制台输出:

1:mounted 输出

2:methods 方法的输出

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vuex中如何getters动态获取state的值

    目录 Vuex getters动态获取state的值 案例 说明 Vuex state值更改但是getters未更新 实现效果 Vuex getters动态获取state的值 在做项目时,getters里有很多冗余代码,但是仔细一看可以根据参数来解决,于是决定使用传参来进行获取,减少代码冗余. 案例 需求:在getters里能够根据值动态获取到people的元素.经过多次尝试,最终得到下面的代码. state.js代码如下: export default { people: [ { name:

  • 记一次vuex的mapGetters无效原因及解决

    目录 vuex的mapGetters无效原因 vuex mapGetters语法报错(Unexpected token) 解决方案 vuex的mapGetters无效原因 报错是(error during evaluation),见下图. 代码大概是下面这样, import store from './store.js' computed: { ...mapGetters('project', [ 'isOpenSupplyNeed', ]), a(){ return store.getters

  • VueX mapGetters获取Modules中的Getters方式

    目录 VueX mapGetters获取Modules的Getters mapGetters的使用及简单实现原理 项目中的mapGetters mapGetters简单实现原理 VueX mapGetters获取Modules的Getters 注明 : permission 是你要获取的Modules中的哪一个 (permission 即是 模块名);         ...mapGetters("permission",[             'ReturnRoutes'    

  • vuex中getters的基本用法解读

    目录 getters的基本用法解读 一.getter 定义 二.使用方法 三.mapGetters辅助函数 四.getters注意事项 getters的两种调用方法 方法一 方法二 getters的基本用法解读 一.getter 定义 Vuex允许我们在store中定义"getter" ,用于对state中存储的数据进行过滤操作. 就像vue生命周期中的computed一样,getter的返回值 会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算 二.使用方法 1.通

  • vuex中...mapstate和...mapgetters的区别及说明

    目录 ...mapstate和...mapgetters的区别 …mapstate …mapGetters vuex mapState mapGetters用法及多个module下用法 一.mapState 二.mapGetters 三.mapActions.mapMutations ...mapstate和...mapgetters的区别 …mapstate 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余.为了解决这个问题,我们可以使用 mapState 辅助函数帮

  • vuex通过getters访问数据为undefined问题及解决

    目录 getters访问数据为undefined问题 写一个类似例子 vuex getters(组件mounted调用)使用注意 逻辑 解决方案 getters访问数据为undefined问题 本篇文章可能对你的帮助不大, 只是个人开发中的一些记录.不同的业务和应用场景可能问题不同. 在通过 uni-app 开发商城时,用户快捷登录之后,服务器返回一个 token 数据,我将其同步到 vuex module下的 user 模块中. 然后从登录页返回到用户页,并发起 http 请求,获取用户的个人

  • vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据操作

    在vue项目中组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的话,有必要考虑引入vuex来管理这些凌乱的状态,今天这边博文用来记录这一整个的过程,后台api接口是使用webpack-server模拟的接口,这个前面的文章中有提到,需要的可以去翻阅. 整个的流程是在组件的created中提交dispatch,然后通过action调用一个封装好的axios然后再触发mutation来提交状态改变state中的数据,然后在组件的计算属性中获取state的数据并渲染在页面上 首先新需要在项

  • vuex结合session存储数据解决页面刷新数据丢失问题

    目录 前言 一.原因: 二.解决思路: 1.本地存储方法: 2.实现步骤: 3.优化: 前言 在项目中表单筛选项里,选择完之后刷新页面数据就变了,没有保留在自己选择的选项上. 在项目中是使用vuex保存数据,但是网页刷新后,store中保存的数据丢失了. 提示:以下是本篇文章正文内容,下面案例可供参考 一.原因: vuex作为全局的数据状态管理机制,store中的数据是保存在运行内存中,当页面刷新时,页面会重新加载vue实例,store里边的数据就会被重新赋值变成初始化状态. 二.解决思路: 将

  • 详解Vuex中getters的使用教程

    目录 简介 说明 官网 getters概述 说明 来源 用法 示例 测试 简介 说明 本文用示例介绍Vuex的五大核心之一:getters. 官网 Getter | Vuex API 参考 | Vuex getters概述 说明 getters 是Store的计算属性,可以对State进行计算操作.就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算. 虽然组件内也可以做计算属性,但getters 可以在多组件之间复用.如果一个状态只在一个

  • 采用ngxtop实现nginx实时访问数据统计

    对于nginx的实时访问数据统计可采用ngxtop实现监控web server的访问情况 .ngxtop 允许你对 NGINX 的访问日志 (access log) 进行实时解析, 并输出类似 top 的有用信息. ngxtop 是 python 脚本安装包,需要python支持. 对于python的包和库文件我们一般喜欢pip管理,没有安装的可以: wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py python get

  • ajax获取json数据为undefined原因分析

    Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术.Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索.使用 XMLHttpRequest 函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器.Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序. 一般处理服务器传来的json值

  • 对vuex中getters计算过滤操作详解

    getter这个概念其实我们写的时候感觉好像和Mutations修改状态一样,实际上它们是有区别的: getters比较死板,如果你的百度钱包只有在金额为100才能提现,那么你在写提现页面,它是早已固定好的,而Mutation不一样,当你点击百度钱包提现,你哪怕是一元,它只要你点击了便可以提现,而且getters它是不需要什么点击,它就存在,只要你写了,这是什么意思,就是说假设你百度钱包为0,你存在了getter它就有100元,而你如果写许多百度经验,百度再次发红包0.5元时它就是100+0.5

  • 关于ajax异步访问数据的问题

    在js中,处理数据固然很快,sososo就能完成所有的数据处理,我们似乎不需要使用异步传输数据 跨洋数据传输就出现了问题,一来2s过去了一回2s过去了,这对于访问者来说,这就是卡 再者 我输入了密码 提示密码错误 于是要重新输入,返回了一个网页 这时候输入的数据就会被清空,非常让人抓狂. 为了解决这个问题ajax孕育而生 Ajax全名Asynchronous JavaScript and XML 名为异步的JavaScript和XML Ajax使用方式非常简单 1.创建实例 xhttp = ne

  • vuex 第三方包实现数据持久化的方法

    目的: 让在vuex中管理的状态数据同时存储在本地.可免去自己存储的环节. 在开发的过程中,像用户信息(名字,头像,token)需要vuex中存储且需要本地存储. 如果有别的模块也需要持久化,也存储在本地 1)首先:我们需要安装一个vuex的插件vuex-persistedstate来支持vuex的状态持久化. npm i vuex-persistedstate 2)然后:在src/store 文件夹下新建 modules 文件,在 modules 下新建 user.js  和 cart.js

  • Vuex中getters和actions的使用补充说明

    前置说明 1.Vue2.x 和 Vue3.x区别: 在Vue3.x中, 没有辅助函数. 其他关于Vuex的使用没有区别. 2. 此处只对于Vuex的几个属性中的使用做扩展补充. getters补充 当getters写在子模块中时, getters属性中的方法, 全参共有4个参数 getters: { /** * 形参说明: * state: 表示当前模块中的satate * getters: 表示当前模块中的getters对象, 一般是操作同级的其他方法 * rootState: 表示主模块的s

随机推荐