二十.导航守卫,滚动位置记录函数

本文介绍Vue.js中Router的导航守卫与滚动行为配置。包括全局守卫、路由独享守卫及组件级守卫的使用方法,以及如何通过scrollBehavior实现路由切换时的滚动位置保存。

导航守卫 、 导航钩子函数

监听甚至 拦截 路由变化

  • 全局守卫 (拦截所有的路由)
// 全局前置 守卫
router.beforeEach((to,from,next)=>{
  // to 目标路由 
  // from 从哪来路由
  // next 拦截器 不调用next()路由无法进入,next参数同router-link to属性的值,重定向地址
  next()
})
// 全局后置守卫
router.afterEach((to,from)=>{
  //只有to,from,没有next,不能做鉴权
})
  • 路由独享的 (定义在路由规则中,只拦截这个路由)
const routes = [
  {
    path:"/news",
    beforeEnter(to,from,next){
      //使用方法与全局守卫相同,需要放行
    },
    component:News
  }
]
  • 组件内部
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

// 面试题  如何 监听 动态路由参数的变化
{
  watch:{
    '$route'(to,from){

    }
  },
  beforeRouteUpdate(to,from,next){

  },
}

滚动位置

记录上次页面的位置

const router = new VueRouter({
  mode,
  routes,
  scrollBehavior (to, from, savedPosition) {
    // savedPosition切换路由时,切出路由的 滚动条位置 {x:number,y:number}
    if (savedPosition) {
      return savedPosition
    } else {
      return { x: 0, y: 0 }
    }
  }
})
<think>首先,用户的问题是关于在 Vue 框架中实现页面返回时保存并恢复滚动位置的功能。用户提供了几个引用,我需要参考这些引用来构建回答。 用户的问题:"我想在使用 Vue 框架开发应用时,希望实现页面返回时保存并恢复滚动位置的功能 请问vue 页面返回时如何保存滚动位置" 系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1] 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。 - 参考站内引用:引用[1]到[4]。 分析引用: - 引用[1]: 使用beforeRouteLeave和beforeRouteEnter导航守卫。在离开页面时保存滚动位置,进入页面时恢复。 - 引用[2]: 类似引用[1],但使用sessionStorage保存位置。 - 引用[3]: 使用watch监听$route变化,并在特定路由时保存和恢复滚动位置。 - 引用[4]: 使用滚动行为(scroll behavior)和事件监听器。 用户的需求是实现页面返回时保存滚动位置Vue.js 中常见的方法包括: 1. 使用 Vue Router 的导航守卫(如 beforeRouteLeave 和 beforeRouteEnter)。 2. 使用 Vue Router 的滚动行为(scrollBehavior)。 3. 使用事件监听器或状态管理(如 Vuex)结合本地存储。 关键步骤: - 保存滚动位置:在用户离开页面时,记录当前的滚动位置(如 window.scrollY 或元素.scrollTop)。 - 恢复滚动位置:在用户返回页面时,设置滚动位置到保存的值。 结构回答: - 介绍问题:解释为什么需要保存滚动位置。 - 提供解决方案:列出几种方法,逐步解释。 - 代码示例:给出示例代码。 - 注意事项:提到可能的兼容性问题(如手机上)。 - 生成相关问题:基于主题生成相关问题。 确保使用中文。 生成相关问题: - 例如:1. 如何在 Vue 中处理移动端滚动位置恢复?2. 使用 Vuex 保存滚动位置的方法?3. 滚动行为在 Vue Router 中的具体配置? 参考引用: - 在回答中,当提到特定方法时,添加引用标识如[^1]。 最终回答结构: 1. 引言:简述问题。 2. 方法一:使用导航守卫(基于引用[1]和[2])。 3. 方法二:使用 watch $route(基于引用[3])。 4. 方法三:使用 Vue Router 的 scrollBehavior(基于引用[4]和标准知识)。 5. 注意事项:手机兼容性等。 6. 代码示例。 7. 相关问题。</think>### Vue 页面返回时保存滚动位置的实现方法 在 Vue.js 应用中,当用户从子页面(如详情页)返回列表页时,浏览器默认会重置滚动位置到顶部,影响用户体验。这通常由 Vue Router 的路由切换机制导致。以下提供三种可靠方法实现滚动位置保存与恢复,参考了站内引用并结合最佳实践。每种方法均适用于 PC 端,并特别说明移动端兼容性。 #### 方法一:使用 Vue Router 导航守卫(推荐) 导航守卫(`beforeRouteLeave` 和 `beforeRouteEnter`)是 Vue Router 提供的钩子函数,直接在路由切换时操作滚动位置。 **实现步骤**: 1. **离开页面时保存滚动位置**:在 `beforeRouteLeave` 中记录当前滚动位置。 2. **进入页面时恢复位置**:在 `beforeRouteEnter` 中通过 `next(vm => {})` 访问组件实例并设置滚动位置。 **代码示例**: ```javascript export default { data() { return { scrollTop: 0 // 存储滚动位置 }; }, beforeRouteLeave(to, from, next) { // 保存滚动位置(兼容不同浏览器) this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop; next(); }, beforeRouteEnter(to, from, next) { next(vm => { // 恢复滚动位置 window.scrollTo(0, vm.scrollTop); }); } }; ``` **优点**: - 直接集成到路由生命周期,无需额外依赖。 - PC 端兼容性好,移动端需额外处理(见注意事项)。 **注意事项**: - 移动端可能因浏览器差异失效,需添加 `setTimeout` 延迟恢复(如 `setTimeout(() => window.scrollTo(0, vm.scrollTop), 0)`)[^1][^2]。 #### 方法二:结合 sessionStorage 持久化存储 当页面刷新或应用重启时,导航守卫无法保留状态。使用 `sessionStorage` 可跨会话保存位置。 **实现步骤**: 1. 离开页面时存储滚动位置到 `sessionStorage`。 2. 进入页面时从 `sessionStorage` 读取并恢复。 **代码示例**: ```javascript export default { beforeRouteLeave(to, from, next) { // 存储位置(JSON 序列化确保数据类型) const position = document.querySelector('.scroll-container').scrollTop; window.sessionStorage.setItem('scrollPosition', JSON.stringify(position)); next(); }, beforeRouteEnter(to, from, next) { next(vm => { // 读取并恢复位置 const position = JSON.parse(window.sessionStorage.getItem('scrollPosition')) || 0; document.querySelector('.scroll-container').scrollTop = position; }); } }; ``` **优点**: - 支持页面刷新后位置恢复。 - 适用于长列表等复杂场景[^2][^3]。 #### 方法三:监听路由变化与滚动事件 对于动态组件或非标准路由,可通过 `watch` 监听 `$route` 变化并结合滚动事件处理。 **实现步骤**: 1. 在 `mounted` 中注册滚动事件监听器。 2. 通过 `watch` 检测路由变化,在离开时保存位置,返回时恢复。 **代码示例**: ```javascript export default { data() { return { scrollTop: 0 }; }, mounted() { // 监听滚动事件实时保存位置 window.addEventListener('scroll', this.handleScroll); }, beforeDestroy() { // 移除监听避免内存泄漏 window.removeEventListener('scroll', this.handleScroll); }, methods: { handleScroll() { this.scrollTop = window.scrollY; } }, watch: { $route(to, from) { if (from.path === '/detail') { // 假设从详情页返回 // 恢复滚动位置 window.scrollTo(0, this.scrollTop); } } } }; ``` **优点**: - 灵活控制特定路由的滚动行为。 - 适合嵌套路由或条件渲染场景[^3][^4]。 #### 注意事项与最佳实践 - **移动端兼容性**:部分移动浏览器(如 iOS Safari)可能因渲染延迟导致恢复失效。解决方法:在恢复位置时添加 `setTimeout` 或使用 `window.requestAnimationFrame`。 - **性能优化**:避免频繁操作 DOM,优先使用 `window.scrollTo` 而非元素级滚动。 - **Vue Router 高级方案**:可直接配置 `scrollBehavior`(需启用 Vue Router 的 history 模式): ```javascript const router = new VueRouter({ routes, scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition; // 自动恢复浏览器历史记录位置 } return { x: 0, y: 0 }; } }); ``` 此方法简化流程但需浏览器支持历史记录 API[^4]。 ### 相关问题 1. 如何解决 Vue 在移动端返回时滚动位置恢复失效的问题? 2. 使用 Vuex 管理全局滚动状态有哪些优缺点? 3. Vue Router 的 `scrollBehavior` 方法在 SPA 中如何配置以实现平滑滚动? [^1]: vue返回上一页面时记忆回到原先滚动位置。这样在index.vue中,mounted方发只走一次,在浏览器上实现了返回原来滚动位置的目的。但是在手机上测试,发现没用,解决手机上实现目的的方法: //在页面离开时记录滚动位置 beforeRouteLeave (to, from, next) { this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop next() }, //进入该页面时,用之前保存的滚动位置赋值 beforeRouteEnter (to, from, next) { next(vm => { document.body.scrollTop = vm.scrollTop }) }。 [^2]: vue实现返回页面时回到原来的位置。使用vue中的导航守卫beforeRouteEnter与beforeRouteLeave beforeRouteEnter(to, from, next) { next(vm => { // 回到原来的位置 const position = JSON.parse(window.sessionStorage.getItem('position')) document.querySelector('.list-row').scrollTop = position }) }, beforeRouteLeave(to, from, next) { // 保存离开页面时的位置 const position = document.querySelector('.list-row').scrollTop window.sessionStorage.setItem('position', JSON.stringify(position)) next() }。 [^3]: vue进入一个新页面时返回本页面滚动条高度保持原来位置。有时候选项很多时并且单个选项文字很多时使用下拉选项的组件就不合适了,这时就需要打开一个页面把选项列出来,用户选完后再返回原来的页面把值回填,但是发现返回时就直接置顶了。 解决 <div id="box" ref="Box" :style="'height:'+ statusBarHeight +'px' " class="aui-content">......</div> data () { return { scrollTop: '', /*保存当前滚动条*/ } }, watch: { $route: { handler: function (val, oldVal) { if (oldVal.path === '/admissionServices/chooseArea') { /*给滚动条赋值*/ eventHub.$on('chooseAreaChange', this.chooseArea) this.$refs.Box.scrollTop = this.scrollTop } else { this.scrollTop = this.$refs.Box.scrollTop /*保存当前滚动位置*/ } }, // 深度观察监听 deep: true } }。 [^4]: vue通过滚动行为实现列表到详情,返回列表原位置的方法。同时在策略超市里监听滚动事件:在data内定义scrollTop属性来存储用户每次滚动位置 mounted() { window.addEventListener("scroll", this.handlescroll); }。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值