Procházet zdrojové kódy

将 MessageStream.vue 页面修改为 websocket 实时数据推送

reghao před 2 roky
rodič
revize
9bbe993b82
4 změnil soubory, kde provedl 151 přidání a 173 odebrání
  1. 0 1
      src/App.vue
  2. 3 3
      src/router/index.js
  3. 0 169
      src/views/home/ArticleStream.vue
  4. 148 0
      src/views/home/MessageStream.vue

+ 0 - 1
src/App.vue

@@ -43,7 +43,6 @@ export default {
     })
   },
   methods: {
-
   }
 
 }

+ 3 - 3
src/router/index.js

@@ -14,7 +14,7 @@ const ImageIndex = () => import('views/home/Image')
 const ImagePage = () => import('views/home/ImagePage')
 const ArticleIndex = () => import('views/home/Article')
 const ArticlePage = () => import('views/home/ArticlePage')
-const ArticleStream = () => import('views/home/ArticleStream')
+const MessageStream = () => import('views/home/MessageStream')
 const Search = () => import('views/home/Search')
 const UserHome = () => import('views/user/Home')
 const UserVideo = () => import('views/user/Home')
@@ -159,8 +159,8 @@ const routes = [
   },
   {
     path: '/stream',
-    name: 'ArticleStream',
-    component: ArticleStream
+    name: 'MessageStream',
+    component: MessageStream
   },
   {
     path: '/article/:articleId',

+ 0 - 169
src/views/home/ArticleStream.vue

@@ -1,169 +0,0 @@
-<template>
-  <div>
-    <el-row v-if="totalSize !== 0" class="movie-list">
-      <el-col :md="12">
-        <div v-for="(item, index) in dataList" :key="index" class="infinite-list-wrapper" style="overflow:auto" :md="6" :sm="12" :xs="12">
-          <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-            <el-card class="box-card">
-              <el-row>
-                <el-col :md="20">
-                  <el-row>
-                    <div style="padding: 14px">
-                      <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.excerpt }}</span>
-                    </div>
-                  </el-row>
-                </el-col>
-              </el-row>
-            </el-card>
-          </el-row>
-        </div>
-      </el-col>
-      <el-col :md="12">
-        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-          <el-card class="box-card">
-            <div slot="header" class="clearfix">
-              <el-row>
-                <span>热门文章</span>
-              </el-row>
-            </div>
-            <div class="text item">
-              <el-row />
-            </div>
-          </el-card>
-        </el-row>
-      </el-col>
-    </el-row>
-    <el-row v-else class="not-result">
-      <el-col :span="12" :offset="6">
-        <img src="@/assets/img/icon/not-result.png">
-        <div>没有文章数据</div>
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import { getArticles } from '@/api/article'
-import SocketInstance from '@/utils/ws/socket-instance'
-
-export default {
-  name: 'ArticleStream',
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 50
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
-  components: {},
-  data() {
-    return {
-      // 屏幕宽度, 为了控制分页条的大小
-      screenWidth: document.body.clientWidth,
-      currentPage: 1,
-      pageSize: 12,
-      totalSize: 0,
-      dataList: []
-    }
-  },
-  created() {
-    document.title = '文章主页'
-
-    this.getArticlesWrapper(this.currentPage)
-    SocketInstance.connect()
-    /* if (window.Notification.permission === 'granted') {
-      this.sendNotification()
-    } else if (window.Notification.permission !== 'denied') {
-      window.Notification.requestPermission(function(permission) {
-        this.sendNotification()
-      })
-    }*/
-  },
-  mounted() {
-    // 当窗口宽度改变时获取屏幕宽度
-    window.onresize = () => {
-      return () => {
-        window.screenWidth = document.body.clientWidth
-        this.screenWidth = window.screenWidth
-      }
-    }
-  },
-  methods: {
-    sendNotification() {
-      new Notification('通知标题:', {
-        body: '通知内容',
-        icon: 'https://pic1.zhuanstatic.com/zhuanzh/50b6ffe4-c7e3-4317-bc59-b2ec4931f325.png'
-      })
-    },
-    handleCurrentChange(currentPage) {
-      this.currentPage = currentPage
-      this.getArticlesWrapper(this.currentPage)
-      // 回到顶部
-      scrollTo(0, 0)
-    },
-    getArticlesWrapper(page) {
-      getArticles(page).then(resp => {
-        if (resp.code === 0) {
-          const respData = resp.data
-          this.dataList = respData.list
-          this.totalSize = respData.totalSize
-        }
-      })
-    },
-    refresh() {
-      this.$notify({
-        message: '接口未实现',
-        type: 'info',
-        duration: 3000
-      })
-    }
-  }
-}
-</script>
-
-<style scoped>
-/*处于手机屏幕时*/
-@media screen and (max-width: 768px) {
-  .movie-list {
-    padding-top: 8px;
-    padding-left: 0.5%;
-    padding-right: 0.5%;
-  }
-
-  .coverImg {
-    height: 120px !important;
-  }
-}
-
-.movie-list {
-  padding-top: 15px;
-  padding-left: 6%;
-  padding-right: 6%;
-}
-
-.coverImg {
-  width: 100%;
-  height: 120px;
-  display: block;
-}
-
-.clearfix:before,
-.clearfix:after {
-  display: table;
-  content: "";
-}
-
-.clearfix:after {
-  clear: both;
-}
-
-.not-result {
-  padding-top: 100px;
-  padding-bottom: 100px;
-  text-align: center;
-}
-
-</style>

+ 148 - 0
src/views/home/MessageStream.vue

@@ -0,0 +1,148 @@
+<template>
+  <el-row class="movie-list">
+    <el-col :md="18">
+      <div class="movie-list" style="height: 100vh;">
+        <!-- 注意需要给 el-scrollbar 设置高度,判断是否滚动是看它的height判断的 -->
+        <el-scrollbar style="width: 100%; height: 70%;">
+          <el-row class="movie-list">
+            <div
+              v-for="(item, index) in dataList"
+              :key="index"
+              :md="6"
+              :sm="12"
+              :xs="12"
+            >
+              <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+                <el-card class="box-card">
+                  <el-row>
+                    <el-col :md="20">
+                      <el-row>
+                        <div style="padding: 14px">
+                          <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.content }}</span>
+                        </div>
+                      </el-row>
+                    </el-col>
+                  </el-row>
+                </el-card>
+              </el-row>
+            </div>
+          </el-row>
+        </el-scrollbar>
+      </div>
+    </el-col>
+    <el-col :md="6">
+      <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <el-row>
+              <span>热门文章</span>
+            </el-row>
+          </div>
+        </el-card>
+      </el-row>
+    </el-col>
+  </el-row>
+</template>
+
+<script>
+export default {
+  name: 'MessageStream',
+  filters: {
+    ellipsis(value) {
+      if (!value) return ''
+      const max = 50
+      if (value.length > max) {
+        return value.slice(0, max) + '...'
+      }
+      return value
+    }
+  },
+  data() {
+    return {
+      dataList: [],
+      websocket: null
+    }
+  },
+  created() {
+    document.title = 'MessageStream'
+    this.initWebSocket()
+  },
+  methods: {
+    // 滚动到顶部
+    handleScrollTop() {
+      this.$nextTick(() => {
+        const scrollElem = this.$refs.msgstream
+        scrollElem.scrollTo({ top: 0, behavior: 'smooth' })
+      })
+    },
+    // 滚动到底部
+    handleScrollBottom() {
+      this.$nextTick(() => {
+        const scrollElem = this.$refs.msgstream
+        scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' })
+      })
+    },
+    initWebSocket: function() {
+      var url = 'wss://api.reghao.cn/ws/log?token=1234567890'
+      this.websock = new WebSocket(url)
+      this.websock.onopen = this.websocketOnopen
+      this.websock.onerror = this.websocketOnerror
+      this.websock.onmessage = this.websocketOnmessage
+      this.websock.onclose = this.websocketOnclose
+    },
+    websocketOnopen: function() {
+      console.log('WebSocket连接成功')
+      // 心跳检测重置
+      // this.heartCheck.reset().start();
+    },
+    websocketOnerror: function(e) {
+      console.log('WebSocket连接发生错误')
+      this.reconnect()
+    },
+    websocketOnmessage: function(e) {
+      const evtData = JSON.parse(e.data)
+      const payload = evtData.payload
+      this.dataList.push(payload)
+    },
+    websocketOnclose: function(e) {
+      console.log('connection closed (' + e.code + ')')
+      this.reconnect()
+    },
+    websocketSend(text) { // 数据发送
+      try {
+        this.websock.send(text)
+      } catch (err) {
+        console.log('send failed (' + err.code + ')')
+      }
+    },
+    reconnect() {
+      var that = this
+      if (that.lockReconnect) return
+      that.lockReconnect = true
+      // 没连接上会一直重连,设置延迟避免请求过多
+      setTimeout(function() {
+        console.info('尝试重连...')
+        that.initWebSocket()
+        that.lockReconnect = false
+      }, 5000)
+    }
+  }
+}
+</script>
+
+<style scoped>
+/*处于手机屏幕时*/
+@media screen and (max-width: 768px) {
+  .movie-list {
+    padding-top: 8px;
+    padding-left: 0.5%;
+    padding-right: 0.5%;
+  }
+}
+
+.movie-list {
+  padding-top: 15px;
+  padding-left: 6%;
+  padding-right: 6%;
+}
+</style>