关于 Vue2.0-Spa 单页应用如何实现历史位置记录问题

网上搜索比较多的解决方案就是,类似 vue-router 开启 HTML5history 模式,Nginx 配置解决这个历史位置记录问题,因为个人觉得很麻烦,所以没采用。

 

相关文章我在这里提供下,有兴趣可以去了解:

https://segmentfault.com/q/1010000006177894/a-1020000006619306

https://router.vuejs.org/zh-cn/essentials/history-mode.html

http://www.cnblogs.com/guazi/p/6759323.html?utm_source=itdadao&utm_medium=referral

 

以上方式我都没采纳,因为太麻烦了,而且设置 HTML5history 模式就会把 # 去掉,还得配置服务器……

 

我的解决思路就是,每次退出页面之前把当前的 fullPathscrollTop 为一组记录到数组缓存到 sessionStorage,下次进来获取 sessionStorage 匹配 fullPath 然后调用 window.body.scrollTop 滚动到历史位置。

 

【PS】大前提是你的 router-view 必须在 keep-alive 条件下才能实现此方案!!!

 

在你配置路由的地方,一般在 src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
 
const Index = r => require.ensure([], () => r(require('@/views/index.vue’)));//异步引入 index 页面
const Index = r => require.ensure([], () => r(require('@/views/Iist.vue’)));//异步引入 list 页面
const Index = r => require.ensure([], () => r(require('@/views/details.vue’)));//异步引入 details 页面
 
Vue.use(VueRouter);
 
const router = new VueRouter({
    { path: '/', component: index },
    { path: '/list', component: list },
    { path: '/details', component: details },
});
 
let $body = window.document.getElementById("body");
 
router.beforeEach((to, from, next) => {
    let _saveScroll = []; //声明历史记录数组对象
    let _currentPath = from.fullPath;   //获取跳出页的全路径
    let _currentPosition = $body.scrollTop;  //记录跳出页的滚动距离
    let _current = {};  //声明当前单个记录对象
    
    //给当前记录对象赋值
    _current.path = _currentPath;
    _current.position = _currentPosition;
    
    //是否记录到数组的开关
    let flag = true; 
    //遍历匹配,去重记录
    for(var i = 0; i < _saveScroll.length; i++) {
       if(_saveScroll[i].path == _currentPath) {
         _saveScroll[i] = _current;
         flag = false;
       }
    }
    if(flag) {
      _saveScroll.push(_current);
    }
    
    //缓存到本地会话存储 sessionStorage
    _saveScroll = JSON.stringify(_saveScroll);
    window.sessionStorage.setItem("_saveScroll", _saveScroll);
 
    console.log("前页路由:",_currentPath+"; 滚动位置:",_currentPosition);
 
    next();
    //重要的是设置跳转的时机,过早的话页面还没加载完成,高度不够导致不能滚动,过晚的话会造成页面的闪烁。
    router.app.$nextTick(() => {
        let _saveScroll = [];
        let _prePosition = 0;
        let _currentPath = window.location.hash.split("#")[1];  //获取当前页面全路径
 
        //获取本地会话存储 sessionStorage
        if(window.sessionStorage.getItem("_saveScroll")) {
          _saveScroll = JSON.parse(window.sessionStorage.getItem("_saveScroll"));
        }else {
          _saveScroll = [];
        }
 
        //遍历匹配对应值获取历史记录位置
        for(var i = 0; i < _saveScroll.length; i++) {
           if(_saveScroll[i].path == _currentPath) {
            _prePosition = parseInt(_saveScroll[i].position);
           }
        }
 
        //滚动到历史缓存的位置
        $body.scrollTop = _prePosition;
 
       console.log("当前路由:",_currentPath+"; 初始位置: "+_prePosition);
    });
});
 
// 输出router
export default router;

 

然后就这么愉快的解决了,目前项目尝试还可以,暂时没用到什么坑,如果有,欢迎及时指正与互相学习。

posted @ 2017-08-08 11:56  JorsonWong  阅读(539)  评论(0编辑  收藏  举报