zoukankan      html  css  js  c++  java
  • 综合 |vuex与websoket应用

    需求是获取导出记录。特点,无论哪个路由都能访问记录;进行导出操作时,等待后台处理后会通过websocket传来下载数据并重新渲染记录

    效果

    效果

    vuex

    import { getExportLogs } from "@/api/login";
    
    const store = new Vuex.Store({
      //全局状态
      state: {
        logs:[],//导出记录
      },
        
      getters: {
        logs:state=>state.logs,
      },
      
      //改变状态
      mutations:{
        SET_LOGS(state, val) {
            state.logs = val;
        },
      },
      
      //异步事件
      actions:{
       _getLogs({ commit }) {
        return new Promise((resolve, reject) => {
          getExportLogs()//调用函数-获取导出记录
            .then(res => {
              if (res.msg == 'ok') { 
                commit("SET_LOGS", res.data);//调用成功时重置状态
                resolve(res.data);//传出导出记录数据
              } 
            .catch(error => {
              reject(error);
            });
        });
      }
        
    })
    
    
    
    

    挂载时调用:导出记录我做成了一个组件,镶嵌在页面的头部组件里。这里是指导出记录的组件挂载时

    import { mapGetters } from 'vuex'
    
    export default{
    	async mounted(){
    	    this.$store.dispatch("user/_getLogs")
    	},
    	
    	//以便数据更新时视图能实时渲染
    	computed: {
    	    ...mapGetters([
    	        'logs',
    	    ])
    	},
    }
    
    

    websocket

    流程是建立连接——绑定账号(省略)——进行了导出操作后,待后台处理完毕后会发送数据过来,这时候前端就负责弹出这个下载框

    心跳检测参考:https://www.jianshu.com/p/1141dcf6de3e

    import store from "@/store/index";
    import { Message } from "element-ui";
    
    export default function initWebsocket() {
        //心跳检测,每28秒发送一次信息,防止断开连接
        var heartCheck = {
            timeout: 28000,
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function(){
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function(){
                var self = this;
                this.timeoutObj = setTimeout(function(){
                    //这里发送一个心跳,后端收到后,返回一个心跳消息,
                    //onmessage拿到返回的心跳就说明连接正常
                    ws.send("HeartBeat");
                    self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
                        ws.close();     //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                    }, self.timeout)
                }, this.timeout)
            }
        }
    
        var lockReconnect = false;  //避免ws重复连接
        var ws = null;          // 判断当前浏览器是否支持WebSocket
        var wsUrl = "ws://url"
        createWebSocket(wsUrl);   //连接ws
    
        //创建websocket
        function createWebSocket(url) {
            try{
                if('WebSocket' in window){
                    ws = new WebSocket(url);
                }else if('MozWebSocket' in window){  
                    ws = new MozWebSocket(url);
                }else{
                    layui.use(['layer'],function(){
                      var layer = layui.layer;
                      layer.alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!"); 
                    });
                }
                initEventHandle();
            }catch(e){
                reconnect(url);
                console.log(e);
            }     
        }
    	
        //回调处理
        function initEventHandle() {
            // 成功连接
            ws.onopen = function () {
                heartCheck.reset().start();      //心跳检测重置
                console.log("连接成功"+new Date().toUTCString());
            };
            
            // 接收信息
            ws.onmessage = async function (event) {    //如果获取到消息,心跳检测重置
                heartCheck.reset().start();      //拿到任何消息都说明当前连接是正常的
                
                // 获取数据
                let data=JSON.parse(event.data)
                // 弹出下载框
                if(data.type=='down_excel'){
                    openDownloadDialog(data.url,data.file_name)
                }
                
            }
                
            ws.onclose = function () {
                reconnect(wsUrl);
                console.log("连接关闭!"+new Date().toUTCString());
            };
                
            ws.onerror = function () {
                reconnect(wsUrl);
                console.log("连接错误!");
            };
        }
    
        function reconnect(url) {
            if(lockReconnect) return;
            lockReconnect = true;
            setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
                createWebSocket(url);
                lockReconnect = false;
            }, 2000);
        }
    
        //弹框-接受到websocket传过来的下载数据时才会调用该函数
        function openDownloadDialog(url, saveName){
            //调用函数就说明后台已经异步处理完导出了,这时候派发事件重新渲染导出记录
            store.dispatch("_getLogs")
            window.open(url);
            Message.success('导出成功!')
        }
    }
    

    建立连接

    App.vue

    import initWebsocket from '@/utils/createWebSocket'
    export default {
      name: "App",
      mounted(){
        initWebsocket()
      }
    };
    
  • 相关阅读:
    css 元素垂直居中
    win7定时关机
    tabel使用总结
    Js获取当前日期时间及其它操作
    织梦dedecms自定义表单设置必填项
    css字体文本格式 鼠标样式
    css溢出文本显示省略号
    java注解学习
    自定义JSON返回字段
    Spring-解决请求中文乱码问题
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/14609752.html
Copyright © 2011-2022 走看看