场景
路由结构:
父路由组件
子路由组件
正常情况下去请求http://localhost:8080/#/,控制台会打印!
并且会自动跳转到http://localhost:8080/#/test
但是如果使用url直接访问呢?
会发现子组件打印的fatherToSon是父组件默认给的值,并不是父组件请求过后的值,这是因为父组件的请求没有请求完成就打印的是默认值
解决的方法也简单,就监听url的变化,监听用户是不是通过url访问的就重新加载这个url地址,就可以子组件就可以重新获取到请求回来的值
下面开始刷新页面的几种方法
刷新方法
一.使用this.$router.go(0)
二.使用location.reload()
上两种方法 都会出现闪屏的问题 用户体验不好
三.给<router-view>
添加if判断
使用this.$router.push('/test')
还是使用this.$router.replace('/test')
都可以,我这里就使用this.$router.replace('/test')
父组件代码
查看下控制台输出
完美解决
报错问题
在使用该方法时,可能会出现这样的报错NavigationDuplicated: Avoided redundant navigation to current location: "/test"
报错原因是因为重复请求相同的地址
由于 vue-router3.0 及以上版本回调形式改成Promise API的形式了,返回的是一个Promise 。也是说 push和replace都是Promise类型了。
而Promise的回调函数resolve和reject,必须传其中一个,否则会报错。如果路由地址跳转相同,且没有捕获到错误,控制台始终会出现上图所出现的问题。
解决方法
在router/index.js文件中添加如下代码
javascript
// 获取原型对象push函数
const originalPush = VueRouter.prototype.push
// 获取原型对象replace函数
const originalReplace = VueRouter.prototype.replace
// 修改原型对象中的push函数
VueRouter.prototype.push = function push(location){
return originalPush.call(this , location).catch(err=>err)
}
// 修改原型对象中的replace函数
VueRouter.prototype.replace = function replace(location){
return originalReplace.call(this , location).catch(err=>err)
}
使用其中一个方法就导入其中的一个就行
为什么要给<router-view>
添加if判断呢?如果不添加会出现什么问题
如果不添加if判断的话,子组件并不会重新渲染,因为vue会缓存该页面,如果使用if判断的话,只有请求完成后,fatherData为true才会渲染,子组件就可以重新执行代码,发送请求了
扩展
可以使用祖先组件(provide
)向其所有子孙后代(inject
)注入一个依赖.。或者其他组件通信的方法都可以
父组件中
kotlin
reload () {
this.fatherData = false
this.$nextTick(() => {
this.fatherData = true
})
}
kotlin
provide () {
return {
reload: this.reload
}
}
子组件
arduino
inject: ['reload'],
在合适的时机调用就行了
总结
在vue中遇见页面需要重新刷新的时候可以给<router-view>
添加if判断,通过this.$router.push
或者this.$router.replace
的方法