这是我参与更文挑战的第20天,活动详情查看: 更文挑战
两种滚动条
滚动条有两种:
-
整体页面滚动条:
通过
vue-router
以及activated
方法保存和恢复页面级别的滚动条位置。 -
页面内部某个组件,如
table
或者列表的滚动条位置:通过
deactivated()/activated()
保存组件内部某个组件的滚动条位置
组件整体的滚动条
keep-alive
包裹的内部组件添加id标识,以便后期设置属性或值,比如滚动条位置scrollTop
:
<!-- AppMain.vue -->
<keep-alive :include="cachedViews">
<router-view :id="id" :key="key" />
</keep-alive>
- 路由组件添加暂存
scrollTop
字段
下面的关键代码在于增加scrollTop: 0:
{
path: 'order_summary',
component: () => import('@/views/ordermanage/OrderSummary'),
name: 'OrderSummary',
meta: { title: '订单数据汇总', icon: 'tab', noCache: false, roles: ['admin'], scrollTop: 0 },
hidden: false
}
- 离开此页面/路由时,将调用
deactivated()
,在方法内部,保存当前组件的scrollTop
值到路由的scrollTop
中,即上述代码的scrollTop
中。但我们也可以写在vue-router的beforeEach中,这样就不需要针对每个页面的deactivated()
都重写了。
其他代码...
router.beforeEach(async(to, from, next) => {
if (from.meta.noCache === false) {
// 启用缓存
const $content = document.querySelector('#' + 'md5_' + md5(from.path))
const scrollTop = $content ? $content.scrollTop : 0
from.meta.scrollTop = scrollTop
}
// 其他代码....
}
- 对应组件
activated()
方法设置scrollTop
只有用<keep-alive>...</keep-alive>
包裹的组件才会有activated
, deactivated
生命周期
import md5 from 'js-md5'
activated() {
const scrollTop = this.$route.meta.scrollTop
const $content = document.querySelector('#md5_' + md5(this.$route.path))
if (scrollTop && $content) {
$content.scrollTop = scrollTop
}
}
备注:其中的md5是为了避免path中的非法id值字符,md5引用于js-md5 (package.json添加js-md5依赖,引用import md5 from 'js-md5')
二、组件内部的滚动条
例如某页面内部含有table,list等组件:
<el-table ref="table" ...>
...
</el-table>
data() {
return {
tableScrollTop: 0
}
},
activated() {
// 激活后重新设置滚动条
this.activateScroll()
},
mounted() {
// 监听滚动条的位置
this.$refs.companyTable.bodyWrapper.addEventListener('scroll', (res) => {
const height = res.target
this.tableScrollTop = height.scrollTop
}, false)
},
beforeDestroy() {
this.$refs.companyTable.bodyWrapper.removeEventListener('scroll', (res) => {
const height = res.target
this.scrollTop = height.scrollTop
}, false)
},
methods: {
activateScroll() {
this.$nextTick(() => {
setTimeout(() => {
var scrollTop = this.$el.querySelector('.el-table__body-wrapper')
scrollTop.scrollTop = this.tableScrollTop
}, 13)
})
// var scrollTop = this.$el.querySelector('.el-table__body-wrapper')
// scrollTop.scrollTop = this.tableScrollTop
}
.....
}