美文网首页
Vue利用visibilitychange事件刷新数据,应对浏览

Vue利用visibilitychange事件刷新数据,应对浏览

作者: microkof | 来源:发表于2021-03-03 17:24 被阅读0次

    前言

    在前端开发中,用户经常需要及时收到最新数据,根据紧急程度,有这样的方案:

    1. 实时获取数据:一般是通过WebSocket,比如股市动态,比如聊天,比如2台手机面对面互动,等等。

    2. 每次切回网页,要看到最新数据:这就用到今天说到的visibilitychange事件。

    3. 每隔固定时间获取新数据:定时器就搞定,不多说。

    4. 手动触发更新数据:这个不多说。

    什么场景需要“切回网页,就刷新数据”?

    现代浏览器对于机能优化都比较苛刻,比如我们做Vue开发的时候,你肯定要打开一个窗口预览,此时你再新建一个浏览器窗口,让原窗口成为后台窗口,接着,你再修改一下Vue项目代码,等几秒,然后让原窗口切回前台,你会发现预览页有跳动,也就是说,尽管原窗口已经收到了DOM修改,但是它只要在后台,就会憋着不改,直到原窗口转为前台,才会对DOM修改,于是就被你看见了修改过程。

    这个节能机制听起来不错,但是也有坑,比如setInterval函数,这个定时器就不准了!因为它在后台的时候被挂起了!

    另外,对于手机网页,这个问题就更严重了,手机对节能要求更甚,而且浏览器切到后台、锁屏都是极高概率事件!

    有些数据无所谓,比如新闻列表,你不需要看到最新的新闻,你只需要在每天固定的时间点刷新下页面就好。但是,比如实时显示服务器时间,就必须要非常准确才行,这时候,我们就用visibilitychange事件好了。

    环境

    本次测试我用的HBuilderX的wap2app开发的APP,浏览器的话道理都是一样的。

    wap2app本身支持显示和隐藏事件

    是的,它从APP层级支持这两个事件,但是,这里(https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/12806)说的很清楚:

    app.js里写的js代码,运行在本地一个独立的、不可见的Webview中(注意不是运行在首页Webview里)。
    如果开发者要操作某个Webview里的dom,那么应该通过plus.webview的evalJS的api,给目标Webview注入一段js代码进行dom操作。

    注入代码等于侵入代码,不如js原生开发舒服,所以,咱们还是用visibilitychange事件。

    1. 变量docmentVisibility放到Vuex里

    代码摘抄,假设我放在了app模块里:

    docmentVisibility: false,
    
      SET_DOCUMENT_VISIBILITY: (state, docmentVisibility) => {
        state.docmentVisibility = docmentVisibility
      },
    

    2. 监听放到App.vue

      created() {
        document.addEventListener('visibilitychange', () => {
          this.$store.commit('app/SET_DOCUMENT_VISIBILITY', document.hidden ? false : true);
        });
      }
    

    3. 找到负责获取服务器时间的组件,改它

    最终结果,hour负责保存时钟,minute保存分钟:

    import timeApi from '@/api/system/time';
    
    export default {
      data() {
        return {
          timer: null,
          hour: null,
          minute: null,
        };
      },
      computed: {
        docmentVisibility() {
          return this.$store.state.app.docmentVisibility;
        },
      },
      watch: {
        docmentVisibility(newVal) {
          if (!newVal) return;
          clearInterval(this.timer);
          this.getServerTime();
        },
      },
      created() {
        this.getServerTime();
      },
      beforeDestroy() {
        clearInterval(this.timer);
      },
      methods: {
        calcTime(timestamp) {
          this.hour = String(dayjs(timestamp).hour()).padStart(2, '0');
          this.minute = String(dayjs(timestamp).minute()).padStart(2, '0');
        },
        getServerTime() {
          timeApi.serverTimestamp().then((response) => {
            let serverTimestamp = response.data;
            this.calcTime(serverTimestamp);
            this.timer = setInterval(() => {
              serverTimestamp += 1000;
              this.calcTime(serverTimestamp);
            }, 1000);
          });
        },
      },
    };
    

    总结

    一些业务需要防范浏览器节能挂起,这时候就一定要利用visibilitychange事件刷新数据。

    相关文章

      网友评论

          本文标题:Vue利用visibilitychange事件刷新数据,应对浏览

          本文链接:https://www.haomeiwen.com/subject/sgoqqltx.html