vue使用eventSource请求告警数据全局弹窗组件

文章介绍了如何使用EventSource和Vue.js实现一个前端实时通知告警功能,通过与后端建立WebSocket连接,实现在浏览器中接收并显示告警信息,同时处理了跨域问题和浏览器兼容性。
摘要由CSDN通过智能技术生成
<template>
  <div class="messageInfo" :class="[isHide?'hide':'', isMesFlag?'miss':'']">
    <div class="mi-tit">
      <div class="mit-t">通知告警</div>
      <div class="mit-b">
        <span @click="clearMes"><svg-icon icon-class="cla" style="color:#1c6aff;width:16px;height:16px;margin:0 0 0 0;"></svg-icon></span>
        <span @click="isHide=true;" style="margin:0 0 0 20px;"><i class="el-icon-minus"></i></span>
      </div>
    </div>
    <div class="mi-wrap">
      <div class="mi-con" v-for="(item, inx) in mesLis" :key="inx">
        <div class="mic-des">
          <div class="micd-t">
            <svg-icon icon-class="guanbi" style="color:#f24e4e;width:24px;height:24px;margin:0 5px 0 0;"></svg-icon>{{item.taskTitle}}
          </div>
          <div class="micd-b" @click="delMes(inx)"><i class="el-icon-close"></i></div>
        </div>
        <div class="mic-info">
          <div class="mici-t" :title="item.tCode">
            编号:{{item.tCode}}
          </div>
          <div class="mici-c">
            描述:{{item.description}}
          </div>
          <div class="mici-b" @click="seeDes(item)">查看详情</div>
        </div>
      </div>
    </div>
    <div class="mi-alerm" @click="isHide=!isHide;">
      <svg-icon icon-class="yujing1" style="color:#fff;width:16px;height:16px;margin:0 0 0 0;"></svg-icon>
    </div>
  </div>
</template>

<script type="text/javascript">
import { EventSourcePolyfill } from "event-source-polyfill";
import { getToken } from "@/utils/auth";
// import $ from 'jquery';
export default {
  name: "app",
  props: [],
  components: {
  },
  data() {
    return {
      isHide: false,
      mesLis: [],
      isMesFlag: true,
      eventSource: null
    }
  },
  beforeDestroy() {
    if (this.eventSource) {
      // 关闭SSE
      this.eventSource.close();
      // 通知后端关闭连接
      this.eventSource = null
      console.log("退出登录或关闭浏览器,关闭SSE连接~")
    }
  },
  mounted() {
    this.createSSE();
  },
  methods: {
    seeDes(vl) {
      this.$router.push({ path: '/message/messageInfo' });
      this.clearMes();
    },
    createSSE() {
      const that = this
      if (window.EventSource) {
        const time = new Date().getTime();
        const eventSource = new EventSource(`/connect?uuid=${time}`, { withCredentials: true }) // 后端接口,要配置允许跨域属性
        eventSource.onopen = function (e) {
          console.log("已建立SSE连接~")
        }
        eventSource.onmessage = function (e) {
          if (e.data) {
            that.mesLis.unshift(JSON.parse(e.data));
            that.isMesFlag = false;
          }
          console.log("已接受到消息:", e.data)
        }
        eventSource.onerror = function (e) {
          console.log('error', e);
        }
        // const time = new Date().getTime();
        // this.eventSource = new EventSourcePolyfill(
        //   `/connect?uuid=${time}`, {
        //   // 设置重连时间
        //   heartbeatTimeout: 60 * 60 * 1000,
        //   // 添加token
        //   headers: {
        //     'Authorization': `Bearer ${getToken()}`,
        //   },
        // });
        // this.eventSource.onopen = (e) => {
        //   console.log("已建立SSE连接~")
        // }
        // this.eventSource.onmessage = (e) => {
        //   console.log("已接受到消息:", e.data)
        // }
        // this.eventSource.onerror = (e) => {
        //   if (e.readyState == EventSource.CLOSED) {
        //     console.log("SSE连接关闭");
        //   } else if (this.eventSource.readyState == EventSource.CONNECTING) {
        //     console.log("SSE正在重连");
        //     // 重新设置token
        //     this.eventSource.headers = {
        //       'Authorization': `Bearer ${getToken()}`
        //     };
        //   } else {
        //     console.log('error', e);
        //   }
        // };
      } else {
        console.log("你的浏览器不支持SSE~")
      }
    },
    clearMes() {
      this.mesLis = [];
      this.isHide = false;
      this.isMesFlag = true;
    },
    delMes(inx) {
      this.mesLis.splice(inx, 1);
    }
  }
}
</script>

<style lang="scss" scoped>
.messageInfo {
  position: fixed;
  bottom: 25px;
  right: 25px;
  width: 300px;
  height: 218px;
  box-shadow: 0px 2px 5px rgba(130, 125, 124, 0.2);
  background: #fff;
  z-index: 10000;
  border: 1px solid rgba(223, 227, 234, 1);
  transition: all 1s;
  &.hide {
    right: -300px;
  }
  &.miss {
    right: -400px;
  }
  .mi-tit {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 38px;
    background: rgba(237, 239, 243, 1);
    padding: 0 20px;
    color: #4b4c57;
    font-size: 14px;
    .mit-b {
      span {
        cursor: pointer;
        i {
          color: #1c6aff;
          font-size: 14px;
          font-weight: bold;
        }
      }
    }
  }
  .mi-wrap {
    height: calc(100% - 38px);
    overflow: auto;
    &::-webkit-scrollbar {
      width: 4px !important;
    }
    &::-webkit-scrollbar-thumb {
      background: #d9e2e8;
      border-radius: 4px;
      border: none;
    }
  }
  .mi-con {
    padding: 20px;
    font-size: 14px;
    .mic-des {
      display: flex;
      align-items: center;
      height: 24px;
      justify-content: space-between;
      .micd-t {
        color: #4b4c57;
        font-weight: bold;
        width: 90%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .micd-b {
        cursor: pointer;
        i {
          font-weight: bold;
        }
      }
    }
    .mic-info {
      .mici-t {
        color: #656774;
        font-size: 12px;
        margin: 15px 0 5px 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      .mici-c {
        color: #656774;
        font-size: 12px;
        line-height: 16px;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      .mici-b {
        color: #fff;
        background: rgba(28, 106, 255, 1);
        height: 24px;
        border-radius: 2px;
        font-size: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 24px 0 0 0;
        cursor: pointer;
      }
    }
  }
  .mi-alerm {
    position: absolute;
    left: -55px;
    bottom: -5px;
    width: 32px;
    height: 32px;
    background: #003ea0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值