在app.vue中,修改this.$route.meta,watch设置了deep: true,没有监听到变化?

新手上路,请多包涵

在app.vue中,修改this.$route.meta,watch设置了deep: true,没有监听到变化,页面也没有渲染?

// App.vue中
watch: {
    $route: {
      deep: true,
      handler(to, from) {
        console.log(6666666666, to); // 执行modify方法无法打印
      }
    }
},
methods: {
    modify() {
      console.log(777777);
      this.$route.meta.navName = "修改";
      // this.$set(this.$route.meta, "navName", "修改"); // 用这个也无效
    },
}

如何才能监听到meta的更新?

阅读 6.2k
2 个回答

手动给 this.$route.meta 添加双向监听

// *.vue 中
created(){
  this.watcher(this.$route.meta, 'navName', this.callback)
},
methods:{
  watcher(obj, name, callback){
    let value = obj[name]
    Object.defineProperty(obj, name, {
      set:function(e){
        value = e
        callback && callback(e)
      }.bind(this),
      get:function(){
        return value
      }.bind(this)
    })
  },
  callback(){
    console.log(event)
  }
}
新手上路,请多包涵
  Vue.mixin({
    beforeCreate () {
      if (isDef(this.$options.router)) {
        this._routerRoot = this
        this._router = this.$options.router
        this._router.init(this)
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      } else {
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this, this)
    },
    destroyed () {
      registerInstance(this)
    }
  })
  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })

  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })

读源码可知$route其实就是根组件$root_route属性, 他并没有定义在data里, 而是调用Vue.util.defineReactive(this, '_route', this._router.history.current), 该方法只会监听_route这个对象的最表层, 也就是_route被赋值=xxx, 才会触发响应式监听被watch到.
相反,定义在data里的数据在组件被实例化时

initData (vue.esm.js?115c:4762)
initState (vue.esm.js?115c:4668)
Vue._init (vue.esm.js?115c:5015)

initData时会被深度地响应式化

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题