一、Vue scrollBehavior 滚动行为
测试中Google浏览器不存在该问题。
通常我们很少会对页面回退或前进进行操作,在浏览器用户界面上提供有前进、回退按钮,页面跳转到离开页面之前的位置,而不是重新刷新页面,这个功能是由浏览器引擎(与渲染引擎、解析引擎概念不同)来完成的。当用户进入一个页面的时候,会往 history 栈中放入当前的记录,对页面级别的操作通过操作内置对象 history 可以满足一些需求。
vue 路由跳转就是通过对 history.pushState() 和 history.replaceState() 方法的模拟来实现,会往 history 栈中存放一条记录,这也是为什么 vue 的 router.push 方法只能在支持 history.pushState() 方法的浏览器中使用,当调用 router.go() 或者 router.back() 方法的时候就和 history.go()、history.back() 效果一样,都是对 history 栈中的记录进行访问,上述行为与通过浏览器的回退和前进效果也是一样。
但是,在不加处理的情况下,组件的滚动行为会跟我们想象的不同。
- vue组件滚动行为
设置三个路由 /home、/list、/about,即对应三个不同的组件:
1) 路由:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import List from '@/views/List'
import About from '@/views/About'
Vue.use(Router)
//创建路由对象
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/List',
name: 'List',
component: List
},
{
path: '/About',
name: 'About',
component: About
}
]
})
2)主页:
<template>
<div class="container">
<h2>主页</h2>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
<style scoped>
</style>
3)列表:
<template>
<div class="container">
<h2>列表</h2>
</div>
</template>
<script>
export default {
name: 'List'
}
</script>
<style scoped>
</style>
4)关于我们;
<template>
<div class="container">
<h2>关于我们</h2>
</div>
</template>
<script>
export default {
name: 'About'
}
</script>
<style scoped>
</style>
回退功能与浏览器的回退功能相同。
4)给Home组件与List组件添加内容。
//Home组件
<template>
<div class="container">
<ul >
<li class="list_content" v-for="i in 10" :key="i">{{ i }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Home"
};
</script>
<style scoped>
.list_content{
background-color: gold;
width: 300px;
height: 90px;
list-style: none;
}
</style>
//List组件
<template>
<div class="container">
列表
<ul >
<li class="list_content" v-for="i in 10" :key="i">{{ i }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'List'
}
</script>
<style scoped>
.list_content{
background-color:green;
width: 300px;
height: 90px;
list-style: none;
}
</style>
请注意,现在开始滚动首页位置至第 5 屏的位置,当切换到列表以及关于页面的时候,会发现这两个页面的滚动行为和浏览前滚动行为一致。
添加回到顶部功能:
二、常见问题:
- 问题:使用keep-alive标签后部分安卓机返回缓存页位置不精确问题
解决方案:
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
const router = new Router({
scrollBehavior(to, from, savedPosition) {
if (savedPosition && to.meta.keepAlive) {
return savedPosition;
}
return { x: 0, y:0 };
},
});
- 不能返回到原有浏览位置
当我们从A页面跳转到B页面,然后在B页面浏览一篇很长的文章,但是这时候我们讲页面滚动到某个位置的时候,我们不小心按了一下浏览器的后退键,这时候我们再按浏览器的前进键的时候会发现,该文章又要从头开始阅读了。
在route后面加上scrollBehavior这个函数。该scrollBehavior函数接收to和from路由对象。第三个参数savedPosition仅在这是popstate导航(由浏览器的后退/前进按钮触发)时才可用该函数可以返回滚动位置对象。
如果返回假值或空对象,则不会进行滚动。
Vue.use(Router)
//创建路由对象
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/List',
name: 'List',
component: List
},
{
path: '/About',
name: 'About',
component: About
}
],
scrollBehavior(to, from, savedPosition) {
if (savedPosition && to.meta.keepAlive) {
return savedPosition;
}
return { x: 0, y: 0 };
}
})