本解决方案原理是利用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>