思路
- 如果页面简单,只是调接口刷新数据,直接用路由刷新即可
- 如果页面复杂,需要调用多个接口或者通知多个子组件做刷新,可以采用刷新当前页面的方式
location.reload和$router.go(0)方法
通过location.reload和$router.go(0)都可以实现页面刷新,它利用浏览器刷新功能,相当于按下了f5键刷新页面
优点:足够简单
缺点:会出现页面空白或闪烁,用户体验不好
代码实现
<template>
<div id="app">
挂载点
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
}
},
methods: {
// 在需要刷新的地方,调用这方法即可
reload() {
// location.reload()
this.$router.go(0)
}
}
}
</script>
通过provide和inject
通过在父页面的<router-view\>上添加v-if的控制,来销毁和重新创建页面的方式刷新页面,并且用到provide和inject实现多层级组件通信方式,父页面通过provide提供reload方法,子页面通过inject获取reload方法,调用方法做刷新
优点:不会出现页面空白,地址栏不会出现快速切换的过程,用户体验好
缺点:实现稍复杂,涉及到provide和inject多层级组件间的通信,和v-if控制组件创建和销毁,和$nextTick事件循环的应用
一般在父组件中定义,子组件在需要刷新页面时,inject接收调用即可;
注意:如果v-if在app.vue中,及是全局刷新
代码实现
<template>
<div id="app">
<router-view v-if="isRouterAlive" />
</div>
</template>
<script>
export default {
name: 'App',
provide() { // 父组件中返回要传给下级的数据
return {
reload: this.reload
}
},
data() {
return {
isRouterAlive: true
}
},
methods: {
async reload() {
this.isRouterAlive = false
//通过this.$nextTick()产生一个微任务,在一次dom事件循环后,重新创建组件
this.$nextTick()
this.isRouterAlive = true
}
}
}
</script>
子组件使用
<template>
<div id="app">
<div v-if="isRouterAlive" @click="onlick"><div>
</div>
</template>
<script>
export default {
name: 'chidren',
inject: ['reload'],
data() {
return {
}
},
methods: {
onlick(){
this.reload()
}
}
}
</script>