场景:vue-router
路由钩子 beforeRouteEnter
能够用来在初始进入页面前,http 异步获取数据mockData
,预先判断是进入 A 页、仍是 B 页,仍是留在本页;而若是留在本页的话,还须要在mounted
根据mockData
来判断显示哪一种状态(能够在本页面实例建立后,从新发起 http 请求获取mockData
,可是没有必要,形成代码冗余);vue
执行顺序:git
async beforeRouteEnter(to, from, next) { let res = await gameData() console.log('beforeRouteEnter start'); next(vm => { console.log("vm start") vm.is_exchange = res.is_exchange vm.is_finish = res.is_finish }) }, beforeCreate() { console.log("beforeCreate start") }, mounted(){ console.log('mounted start'); if(this.is_finish){ this.modalMsg="活动已结束" return; } if(this.is_exchange){ this.modalMsg="您已兑换奖品" return; } }
打印结果以下:github
beforeRouteEnter start beforeCreate start mounted start vm start
由打印结果,咱们能够总结 beforeRouteEnter
钩子确实在 vue 实例建立前执行,可是其 next
函数中 vm
回调不是同步执行,而是等到 mounted
执行完以后,才执行。vue-router
症结: 由于咱们要根据mockData
中的is_exchange
和is_finish
参数来判断决定页面初始状态,此过程须要在mounted
中执行;可是 mounted
执行时,vm
还未执行,即 mounted
拿不到is_exchange
和is_finish
这两个值,这样就形成了冲突;异步
解决: 在 next
中 打印 vm
,发现 vm
就是当前 vue 实例对象,便可以使用 vm
调用全部当前实例的变量和方法;那依次,可否将判断逻辑写入 methods
中一个方法中,使用 vm
来调用呢?async
async beforeRouteEnter(to, from, next) { let res = await gameData() console.log('beforeRouteEnter start'); next(vm => { console.log("vm start") vm.is_exchange = res.is_exchange vm.is_finish = res.is_finish vm.judge();//赋值以后,此处调用判断方法 }) }, beforeCreate() { console.log("beforeCreate start") }, mounted(){ console.log('mounted start'); }, methods:{ judge(){// 将判断逻辑写入judge方法 if(this.is_finish){ this.modalMsg="活动已结束" return; } if(this.is_exchange){ this.modalMsg="您已兑换奖品" return; } } }
至此,问题解决。有同窗可能会问,在 vm
中调用 judge
方法时,mounted
已执行,此时页面已渲染,再去判断初始状态,会不会有闪烁问题?本人通过测试,发现不会,据此推断,在 mounted
执行结束以后,页面没有开始更新动做,而是在执行完 vm
回调以后,再去渲染。这样的话,逻辑上就行得通了,可是这个只是推断,还须要在源码层面找到依据才能够。函数
github地址测试