vue-router 页面跳转后如何记录返回后的位置

前两种方法需要设置路由history模式,后两种方法貌似更合适。

方法一:

1.在router.js里面(即路由文件中),此时模式为 history

const router = new VueRouter({
  mode: 'history',
  routes,
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      if (from.meta.keepAlive) {
        from.meta.savedPosition = document.body.scrollTop
      }
      return { x: 0, y: to.meta.savedPosition || 0 }
    }
  }
})


2.在router.js里面需要记录位置的单页面里面

let routes = [
  {
    path: '/',
    name: 'home',
    component: home,
    meta: {
      title: 'home',
      keepAlive: true
    }
  }


3.App.vue里面<div id="app">  这样写的意义就是不缓存所有页面,哪个地方写了 keepAlive:true,哪个地方就记录位置(加缓存)

<keep-alive >
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>


4.位置确实记录上了(加缓存,返回不刷新页面),也就是说,返回不触发created,所以有些页面需要返回触发的东西都写在activated里面。其实整个过程很简单,代码也很干练,因为这是路由自带的功能,只不过之前没有发现罢了


方法二:scrollBehavior方法

1.router文件中设置为 mode: 'history', 模式
2.router设置

scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}

3.详情页返回列表页时, 用 history.back() 返回


方法三:用默认的hash模式的
一个list页点击进入detail页,我在这时记录下list页滚动条的位置,然后在detail页返回到list页时设置滚动条位置为刚才保存那个值。

// list页route中的data钩子
route : {
  data : function () {
    var _this = this;
    // 返回同一个位置
    var scrollTop = sessionStorage.getItem("scrollTop");
    if (scrollTop) {
      _this.$nextTick(function () {
              $(".abuild-record-layout").scrollTop(scrollTop);
      });
    }
  }
}


$nextTick将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

方法四:

beforeRouteLeave(to, from, next){
  let position = window.scrollY()
  this.$store.commit('SAVE_POSITION', position) //离开路由时把位置存起来
  next()
}

在页面中取值

updated () {
  this.$nextTick(function(){
    let position = this.$store.state.position //返回页面取出来
    window.scroll(0, position)
  }) 
}


用updated 或者 beforeUpdate 钩子都可以  代码都写在要保存滑动距离的界面如果data在进入页面被更新,那update可能不那么合适,这个时候,可以使用组件内守卫
 

//组件内的守卫
  beforeRouteEnter (to, from, next) {
    next(vm => {
      // 通过 `vm` 访问组件实例
      vm.$nextTick(function(){
        let position = vm.$store.state.position //返回页面取出来
        console.log("beforeRouteEnter moments update: ", position);
        window.scroll(0, position)
        // setTimeout(function(){window.scroll(0, position)},1000)
      })
    })
  }

参考:

https://router.vuejs.org/zh/guide/advanced/scroll-behavior.html#%E5%BC%82%E6%AD%A5%E6%BB%9A%E5%8A%A8

修改时间 2018-06-22

真诚赞赏,手留余香
赞赏
随机推荐
thinkcmf 2 获取所有兄弟栏目, 并高亮当前栏目
npm install 生成的package-lock.json是什么文件?
Git命令文本手册
macOS中禁止Adobe CC的无用启动项
CentOS 8 源码编译安装 PHP 和设置 php-fpm
DedeCMS 如何使用文章列表序号
Javascript高级选择器querySelector和querySelectorAll
thinkphp 3.1.3 添加项目分组
如何选择开源许可证?
gps纠偏及大陆地图偏移原因