Vue组件优雅的使用Vuex异步数据

Vue组件优雅的使用Vuex异步数据

前端:Vue+element

项目为前后端分离项目,通过Ajax交换数据。

更新时间:2020-09-10 19:11:42

0x1 缘起

今天在检查代码的时候发现了一个平时都忽略的问题,就是在组件使用vuex数据时,组件使用都是同步取的vuex值。关于vuex的使用可以查看官网文档:https://vuex.vuejs.org/zh/ ,如果我们需要的vuex里面的值是异步更新获取的,在网络和后台请求特别快的情况下不会有什么问题。但是网络慢或者后台数据返回较慢的情况下问题就来了。

0x2 案例

${app}代表你的项目根目录,项目目录结构同大部分Vue项目。

需求

我需要实现这样一个效果,我需要在foo.vue,bar.vue,两个不同的页面建立一个使用相同信息的socket连接,当我离开foo.vue页面的时候断开连接,在bar.vue页面的时候重新连接。而且我的socket连接信息(连接地址,端口等)来自于接口请求。

初次实现

App.vue初始化的时候dispatch一个action去获取socket的连接信息,然后在foo.vue或者bar.vue页面mounted的时候进行连接。

Vuex

${app}/src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

import api from '@/apis'
import handleError from '@/utils/HandleError'

Vue.use(Vuex)

export default new Vuex.Store({
   
  strict: process.env.NODE_ENV !== 'production',
  state: {
   
    socketInfo: {
   
      serverName: '',
      host: '',
      port: 8080
    }
  },
  mutations: {
   
    // Update token
    UPDATE_SOCKET_INFO(state, {
    socketInfo }) {
   
      // state.socketInfo = socketInfo
      // Update vuex token
      Object.assign(state.socketInfo, socketInfo)
    }
  },
  actions: {
   
    // Get socket info
    async GET_SOCKET_INFO({
    commit }) {
   
      // Rquest socket info
      try {
   
        const res = await api.Common.getSocketUrl()
        // Success
        if (res.success) {
   
          commit('UPDATE_SOCKET_INFO', {
   
            socketInfo: res.obj
          })
        }
      } catch (e) {
   
        // Handle api request exception
        handleError.handleApiRequestException(e)
      }
    }
  }
})
App.vue

${app}/src/App.vue

<!-- App -->
<div id="app"></div>
export default {
   
  name: 'App',
  mounted() {
   
    // Get socket info
    this.$store.dispatch('GET_SOCKET_INFO')
  }
}
foo.vue

${app}/src/views/foo/foo.vue

import io from 'socket.io-client'
export default {
   
  name: 'Foo',
  mounted() {
   
    const {
    serverName, host, port } = this.$store.state.socketInfo
    const socket = io(`ws://${
     host}:${
     port}`, {
   
      path: `/${
     serverName}`,
      transports: ['websocket', 'polling']
    })
  }
}

❓ 问题

问题很显而易见,当我直接访问foo.vue页面的时候,如果我的后台api或者网络请求慢的情况下,我的vuexstore还未更新,也就是App.vue的请求还未回来,这个时候foo.vue页面的mounted生命周期函数已经执行,很显然,我需要的socket连接信息拿不到,这个时候控制台就会飘红。

WebSocket connection to 'ws://%27%27/''/?EIO=3&transport=websocket' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED

✅ 第一次解决

既然是需要等到请求回来在连接,那么好办了,我在foo.vue页面也获取一次socket的连接信息获取成功了在进行连接,此时foo.vue代码变成了如下这样

foo.vue

${app}/src/views/foo/foo.vue

import io from 'socket.io-client'

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值