第一步:在vuex新建websocket.js文件:

export default {
  namespaced: true,
  state: {
    websock: null,
    url: '',
    lockReconnect: false, //是否真正建立连接
    timeout: 30 * 1000, //30秒一次心跳
    timeoutObj: null, //心跳心跳倒计时
    serverTimeoutObj: null, //心跳倒计时
    timeoutnum: null, //断开 重连倒计时
    message: {}
  },
  getters: {
    message(state) {
      return state.message
    }
  },
  mutations: {
    // 初始化
    WEBSOCKET_INIT(state, url) {
      var that = this
      state.websock = new WebSocket(url)
      state.url = url
      state.websock.onopen = function () {
        //发送心跳包
        that.commit('websocket/start')
      }
      state.websock.onmessage = function (res) {
        if (res.data.indexOf('connectionHolding') > -1 || res.data.indexOf('Connection holding') > -1) {
          // console.log('心跳响应', new Date().getHours() + ':' + new Date().getMinutes() + ':' + new Date().getSeconds())
        }
        //重置心跳
        that.commit('websocket/reset')
        if (res.data == 'heartCheck' || res.data == 'Connection holding') {
          return
        }

        state.message = res
      }
      state.websock.οnerrοr = function () {
        that.commit('websocket/reconnect')
      }
      state.websock.onclose = function () {
        that.commit('websocket/reconnect')
      }
    },
    WEBSOCKET_SEND(state, message) {
      state.websock.send(message)
    },
    //重连
    reconnect(state) {
      var that = this
      if (state.lockReconnect) {
        return
      }
      state.lockReconnect = true
      //没连接上会一直重连,设置延迟避免请求过多
      state.timeoutnum && clearTimeout(state.timeoutnum)
      state.timeoutnum = setTimeout(() => {
        //新连接
        that.commit('websocket/WEBSOCKET_INIT', state.url)
        state.lockReconnect = false
      }, 5000)
    },
    //重置心跳
    reset(state) {
      clearTimeout(state.timeoutObj)   //清除时间
      clearTimeout(state.serverTimeoutObj)
      this.commit('websocket/start')
    },
    //开启心跳
    start(state) {
      var that = this
      state.timeoutObj && clearTimeout(state.timeoutObj)
      state.serverTimeoutObj && clearTimeout(state.serverTimeoutObj)
      state.timeoutObj = setTimeout(() => {
        //这里发送一个心跳,后端收到后,返回一个心跳消息,
        if (state.websock.readyState == 1) {    //如果连接正常
          state.websock.send('')

          //检测后台心跳响应
          state.serverTimeoutObj = setTimeout(() => {
            state.websock.close()
          }, state.timeout)
        } else {
          //否则重连
          that.commit('websocket/reconnect')
        }
      }, state.timeout)
    }
  },
  actions: {
    WEBSOCKET_INIT({ commit }, url) {
      commit('WEBSOCKET_INIT', url)
    },
    WEBSOCKET_SEND({ commit }, message) {
      commit('WEBSOCKET_SEND', message)
    }
  }
}

第二步:主文件index.vue里面:

 mounted() {
    // 长连接
    let userId = localStorage.getItem('userid')
    const baseURL =
      process.env.VUE_APP_BASE_API === ''
        ? `ws:${window.location.hostname}:${window.location.port}/ws/client_${userId}_2`
        : `ws:${process.env.VUE_APP_BASE_API.split('//')[1]
        }/ws/client_${userId}_2`
    this.$store.dispatch('websocket/WEBSOCKET_INIT', baseURL)
  },
  computed: {
      listenWebsocket() {
        return this.$store.state.websocket.message
      }
  },
   watch: {
     // 监听长连接返回数据的变化
     listenWebsocket(data) {
       let mess = JSON.parse(data.data)
     // 需要执行的操作
       console.log(mess)
     }
   }