vue+vuex+echarts+websocket(基于websocket和vuex状态管理实现echarts图表数据的实时响应大数据平台)

1.实现效果

推大数据平台echarts等图表动态数据展示(用websocket实现实时数据刷新),首屏的数据加载是用的post从后台请求。

1.1 依赖


    "axios": "^0.19.0",  //用来封装自己的请求类API
    "countup.js": "^2.0.4", //数据大屏上的数字滚动
    "echarts": "^4.5.0", // 可视化图表
    "sweetalert2": "^9.10.0", // 一款弹框插件 
    "vue": "^2.6.10",
    "vue-router": "^3.1.3",
    "vuex": "^3.1.2" // 状态管理

1.2 实现思路

我的整体模块如图:
vue+vuex+echarts+websocket(基于websocket和vuex状态管理实现echarts图表数据的实时响应大数据平台)_第1张图片
数据定位推送问题:
如果按照大类->小类->小板块->板块123来定位推送指定的数据,则前端在数据定位的过程中比较繁重(至少3级或更多的层级判断,且不考虑需求、页面布局改变造成的影响)
我的思路:
比较暴力,我与后端的方案是约定好每一个需要实时刷新的小模块(蓝色框[可结合你自己的业务划分来再细分])以及它的唯一id。举个例子,D模块的两个小板块,type为1,2,数字为约定的唯一值,websocket推给我的数据type为1我就把数据更新到D模块1去。
整体思路:
需要登录获取服务端的token,然后在socket请求时后缀带上?token="****",监听socket的onmessage事件,成功返回数据后用vuex的action来提交具体mutation,实现数据的更新,然后每个模块只需要监听自己模块的getter,在触发你需要的操作(这里还待优化,看如何直接触发页面更新,因为echarts全都封装了一遍init,setOption,clear等)

1.3 开始整

  1. 用vue的脚手架搭个简单框架(我就的cli4,选上vue全家桶router+vuex,其他的看自己),装上1.1的依赖。主要讲我的vuex和socket的结合方案,下图是我vuex的结构
    vue+vuex+echarts+websocket(基于websocket和vuex状态管理实现echarts图表数据的实时响应大数据平台)_第2张图片
    举个例子:
// liveData.js
export default {
     
  state: {
     
    data1: {
     }, //每一个 data* 属性对应着页面的一个数据块,
    data2: {
     },
  },
  getters: {
     
    getData1: state => state.data1,
    getData2: state => state.data2,
  },
  mutations: {
     
    setData1(state, data) {
     
      state.data1 = data;
    },
    setData2(state, data) {
     
      state.data2 = data;
    },
  },
  actions: {
     },
};
// index.js
import Vue from 'vue';
import Vuex from 'vuex';

import user from './module/user';
import liveData from './module/liveData';
import center from './module/center';
import statistic from './module/statistic';

Vue.use(Vuex);

export default new Vuex.Store({
     
  state: {
     
    //
  },
  mutations: {
     
    //
  },
  actions: {
     
    // 根据type commit不同mutation   ,这里是重点,从websocket派发到vuex对应模块的对应state属性中
    patchData({
      commit }, data) {
     
      commit(`setData${
       data.type}`, data);
    },
  },
  modules: {
     
    user,
    liveData,
    center,
    statistic,
  },
});

最后将store封装完在main.js里引入使用,到这基本上就差不多了。

1.4 使用

首屏的数据加载封装在每个组件里的,这里是websocket的连接和状态处理(未做心跳包,未用二进制数据流),

created() {
     
    this.handleSubmit(); //开局先模拟登录
  },
  beforeDestroy() {
     
    // 服务器端将断开连接
    this.webSocketObj.close();
    console.log('断开ws');
  },
  methods: {
     
    ...mapActions(['handleLogin', 'patchData']),
    handleData(data) {
     
      const da = JSON.parse(data);
      if (da.type) {
     
        if (da.type !== 0) {
     
          this.patchData(da);
        } else {
     
          // 服务器端将断开连接
          this.webSocketObj.close();
        }
      }
    },
    handleSubmit() {
     
      console.log('模拟登录!');
      const _self = this;
      this.handleLogin({
      userName: 'admin', pwd: '123456' })
        .then((res) => {
     
          if (res.data.success) {
     
            if ('WebSocket' in window) {
     
              _self.webSocketObj = _self.MyApi.MySocket(); // 这是我封装的socket方法
              console.log('[readyState]:', _self.webSocketObj.readyState); // 0

              _self.webSocketObj.onopen = () => {
     
                // Web Socket 已连接上,使用 send() 方法发送数据
                _self.webSocketObj.send('{data:"连接中"}');
                console.log('数据发送中...', _self.webSocketObj.readyState);
              };

              _self.webSocketObj.onmessage = (evt) => {
     
                const received_msg = evt.data;
                console.log('数据已接收数据', _self.webSocketObj.readyState);
                _self.handleData(received_msg);
              };

              _self.webSocketObj.onclose = () => {
     
                // 关闭 websocket
                console.log('连接已关闭...');
              };

              _self.webSocketObj.onerror = () => {
     
                console.log('connect error, [readyState]:', _self.webSocketObj.readyState); // 3
              };
            } else {
     
              // 浏览器不支持 WebSocket
              alert('您的浏览器不支持 WebSocket,请换用谷歌浏览器');
            }
          }
        }).catch((e) => {
     
          console.log(e);
        });
    },

我这方案核心是约定idpatchData(),然后就没了。恩。我拉出来再处刑一遍,大佬请轻喷,有其他好方案请一定告诉我啊,ballballu

patchData({
      commit }, data) {
     
	//根据type commit不同mutation   ,这里是重点,从websocket派发到vuex对应模块的对应state属性中
      commit(`setData${
       data.type}`, data);
    },

监听到数据更新后触发页面数字的更新函数(数字滚动我用的countUp)
vue+vuex+echarts+websocket(基于websocket和vuex状态管理实现echarts图表数据的实时响应大数据平台)_第3张图片
over,如果对你有一定启发,点个赞就nice了

你可能感兴趣的:(echarts,vuex,countup,vue,websocket)