• uni-app下,页面跳转后wacth持续监听的问题处理


    uni-app下,页面跳转后wacth持续监听的问题处理

    好久没写博客了,最近碰到了一个uni-app(vue2)开发小程序的问题,个人觉得很典型,所以拿出来给各位做个参考。

    需求场景:

    全局轮询用户权限。简单点说,就是用户登录后,要根据其权限判断是否能进入某个页面,或者控制使用某个功能之类的。由于权限可能会发生变化,前端就需要事实的进行响应。由于我是在登录后开始轮询用户权限接口,并保存在vuex中,并通过全局注入mixins使其变为全局变量,在需要用到的地方拿出来做处理。在否定了使用websocket之后,我决定使用watch在特定的页面去进行处理。

    碰到的问题:

    在A页面监听权限数据的时候,处理对应的业务逻辑,根据不同岗位权限显示不同的功能按钮。然而在跳转到B页面之后,发现其仍在继续执行监听内容。如果B页面也有wacth监听,两者会叠加,如果监听的也是该内容,会产生冲突甚至报错;再不济也会影响性能。第一感觉是因为navitagorTo的跳转方式导致的,因为A页面并没有被销毁掉,所以其仍会继续执行。所以讲跳转方式改为redirectTo进行验证,发现经过redirectTo跳转后,由于A页面被销毁,所以没有继续触发A页面的wacth。但业务逻辑上,不能直接销毁前页面,因为要返回。

    解决思路:

    1.在wacth的handler方法中加入条件判断;但这样仍然会触发wacth,只是不执行里面的内容。也不是我们想要的。
    2.要解决这个问题,就得要在页面跳转前销毁掉wacth监听,但wact:{}写法显然不能销毁。

    解决方案:
    1.考虑到wacth是vue组件实例上挂载的一个对象方法(毕竟vue3的wacth是直接从vue中import出来的),所以决定丢弃传统的wacth:{}写法,改用**$watch**方法进行实现。
    2.在app.vue中的globalData中加入全局变量:wather,根据其状态判断是否创建或销毁监听。
    3.onShow生命周期中创建监听。onHide生命周期中移除监听。

    代码:

    // mixins中加入如下方法
    methods: {
    $createWatcher(name) {
    	getApp().globalData.watcher = this.$watch(
            '$userInfo.auth',
            val => {
              this[name](val)
            },
           { deep: true, immediate: true }
         )
       }
    }$removeWatcher() {
      // 检查是否有已存在的观察者
      if (getApp().globalData.watcher) {
        // 调用观察者返回的取消函数,即取消对特定属性的监听
        getApp().globalData.watcher()
        console.log('Watch 移除成功!')
      } else {
        console.log('没有观察者可移除!')
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    //page
      onShow() {
        // 此处传递的参数为函数名。所以methods里的函数要与此参数相同
        this.$createWatcher('changeAuth') 
      },
      onHide() {
        this.$removeWatcher()
      },
      methods: {
    	changeAuth(val) {
    	  // val为$createWatcher中$wacth传回的监听数据。以下内容与watch: {handler(val){}}的hander内的内容一致
          const authArr = val.filter(item => item.url === this.$utils.getRouter())
          const auth = authArr[0].children.filter(item => item.url === 'menu')[0].children
          this.menu = auth
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    至此,问题解决

  • 相关阅读:
    19 个高逼格 Linux 命令,赶紧拿去用!
    Python面向对象特性——多继承【Python中的mro方法搜索顺序、新式类和旧式(经典)类)】
    Spring七大组件
    jvm实践
    数据库系列:覆盖索引和规避回表
    C++【STL】【string类的模拟实现】【string类的深浅拷贝】
    linux之linux下载软件包
    QTableView、QTableWidget通过setColumnWidth改变列宽无效的问题解决
    GBase 8c V3.0.0数据类型——密态等值函数
    强化学习(1)基本概念与Q-learning模型的python简单实现
  • 原文地址:https://blog.csdn.net/qq_43156398/article/details/134465799