本解决方案原理是利用 Keep-Alive、 监听滚动事件 与 watch 中监听 $route 实现。
应用 watch 监听 $route 的计划实用于 滚动区域在子组件中 的状况。
因为,beforeRouteLeave 路由导航守卫,只能作用在 路由组件内 ,不能被 路由组件内的子组件 所触发。
vue-router 文档截图如下:
本样例应用 element-ui 下的 el-table 表格组件,原生或其余 UI 组件思路同理。
router.js
{
path: '/dispatchDetail',
name: 'dispatchDetail',
component: () => import('@/views/dispatchDetail/index.vue'),
meta: {title: '日调度状况查问', keepAlive: true} // 须要缓存
},
App.vue
<keep-alive>
// 缓存组件跳转的页面
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
// 不须要缓存组件的页面
<router-view v-if="!$route.meta.keepAlive"></router-view>
dispatchDetail.vue
<template>
<el-table ref="listBox"> // 在 el-table 标签上 增加 ref 属性 用于获取滚动区域 dom
...
</el-table>
</template>
<script>
export default {data() {
return {
listBox: '',
scrollTop: 0,
}
}
// 进入缓存组件时监听滚动事件
activated() {this.$refs.listBox.bodyWrapper.addEventListener('scroll', this.scrollToTop)
},
// 来到缓存组件时监听滚动事件
deactivated() {this.$refs.listBox.bodyWrapper.removeEventListener('scroll', this.scrollToTop)
},
watch: {$route(to, from) {
// 如果是来自指标页 并且 this.scrollTop > 0 则给滚动区域设置来到时缓存的距顶部高度值
if (from.name == 'schedulingDetails') {if (this.scrollTop > 0) {setTimeout(() => {this.$refs.listBox.bodyWrapper.scrollTo(0, this.scrollTop)
}, 0)
}
}
// 如果不是去指标页 则将 this.scrollTop 复原为 0
if (to.name !== 'schedulingDetails') {this.scrollTop = 0}
},
},
methods: {
// 定义获取 距顶部滚动高度 办法
scrollToTop() {
const scrollTop = this.$refs.listBox.bodyWrapper.scrollTop // 实时获取 el-table 组件以后滚动地位,距顶部的滚动高度
this.scrollTop = scrollTop // 赋值给 this.scrollTop 用于下次进入时调用
},
}
}
</script>