路由管理:保留滚动位置

其实现与组件的keep-alive相关,仅设置了keep-aive的页面,实施保留回退位置能力。

keep-alive介绍

作用

把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染,提升切换性能。

相关的生命周期

created() {
console.log('created')
},
activated() {
console.log('activated')
},
deactivated() {
console.log('deactivated')
},
mounted() {
console.log('mounted')
}

执行结果

  • 首次执行该keep-alive组件:

    • 进入:created-> mounted-> activated
    • 离开:deactivated
  • 第二次执行该keep-alive组件:
    • 进入:activated
    • 离开:deactivated
  • 对于没有设置keep-alive的组件:
    • 进入:created-> mounted
    • 离开:空

activated和deactivated为keep-alive组件特有的生命周期,有什么作用呢?

由于keep-alive对单页路由生效,不论是后退操作,还是跳转操作,当非首次访问组件时,mounted、created不执行,其中的数据请求也不会发起,所以,其数据不会进行相应更新。这种设定,符合回退操作的数据状态,但对于大多数的单页跳转操作,会出现数据问题。此时,可利用ativated,发起数据请求,更新数据状态。由于是数据驱动的视图,所以,在数据请求到达前,组件使用旧的数据状态,仍然能给用户不错的视觉体验(不会出现白屏之类的)。

保留滚动位置功能的实现方法

vue-router中有提供scrollBehavior方法,设置回退位置。但由于本项目中vue的基础布局限制,使得scroll在window or document中无效,因此需要自定义方法。

相关条件

仅用户进行回退操作,且设置了router为keep-alive属性的方法,才可进行实际的回退。

思路

  • a、确认回退操作:通过判断scrollBehavior的savedPosition是否存在;
  • b、是否为keep-alive的组件:通过router上的meta.keepAlive属性判断;
  • c、获取页面离开时的位置:beforeEach钩子(该钩子的生命周期:离开前页面,进入下一页面前)

实现代码

// app.vue
<div class='view-frame'>
<keep-alive>
<router-view class="view" v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view class="view" v-if="!$route.meta.keepAlive"></router-view>
</div> // router.js
let routerList = [{
...
meta: {
keepAlive: true
}
}] const router = new VueRouter({
mode: 'history',
...
// 设置返回对应位置的操作
scrollBehavior(to, from, savedPosition) {
if (savedPosition && to.meta.keepAlive) {
let scrollTop = store.state.common.scrollPos[to.name] || 0
if (!scrollTop) {
return
}
// 对scroll元素进行设置
setTimeout(() => {
let documentElem = document.querySelector('.v-content')
if (documentElem) {
documentElem.scrollTop = scrollTop
}
}, 0)
}
}
}) router.beforeEach((to, from, next) => {
// 记录上一个页面的scroll位置
if (from.name) {
let contentElem = document.querySelector('.v-content')
let scrollTop = contentElem ? contentElem.scrollTop : '0'
store.state.common.scrollPos[from.name] = scrollTop
}
next(
})

按需加载的优化,提升缓存性能

了解webpack打包配置的童鞋都知道,webpack提供模块方法,实现按需加载的功能,使得单页应用的首屏性能更高。但打包的方法,常常会影响浏览器缓存,当访问一个资源时,如果其已经加载过,将缓存下来,再次访问时,只需从缓存中取,从而省去了再次请求的时间。因此,有效的打包策略应如是:当文件没有改动时,保持其文件名不变。

webpack提供两种打包方式

  • a、require():将按照webpack的打包id,进行命名;
  • b、require.ensure():可自定义打包名。

方法1:

  • 优点:打包名不会重复;
  • 缺点:其打包名受包的前后顺序,数量影响,即使文件没发生变化,也可能改变包名.

方法2:

  • 优点:仅内容变化才改变包名;便于调试、错误跟踪;可读性强;
  • 中性点:可能出现打包名重复,从而使得两个模块打包到一个文件当中。

第二种方式更佳,相关代码如下:

// webpack.js
output: {
....
chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
} // router.js
const home = r => require.ensure([], () => r(require('src/views/home')), 'home')
let routerList = [{
...
component: home
}]

如此,会出现包合并的问题,因此需要根据路由模块,对包名进行管理。

******更新*******

打包名的命名第三种方式,采用ES6的import实现,需要进行对应的设置:

step1:.babelrc文件,删除“comments”配置;如图:

step2: 如果有eslint检测,则需要在eslint中增加配置;如图:

step3:修改包的加载方式(require.ensure => import):

将 const home = r => require.ensure([], () => r(require('src/views/home')), 'home')

替换成:const home = () => import(/* webpackChunkName: 'home' */ 'src/views/home')

/* webpackChunkName: 'home' */可实现自定义包名,如果不需要自定义,可将该注释删除。

vue路由管理-保留滚动位置功能、按需加载模块名自定义的更多相关文章

  1. 仿ElementUI构建自己的Vue组件库用babel-plugin-component按需加载组件及自定义SASS主题

    最近使用ElementUI做项目的时候用Babel的插件babel-plugin-component做按需加载,使得组件打包的JS和CSS包体积大大缩小,加载速度也大大提升,所有想模仿做一个组件库也来 ...

  2. vue使用H5实现滚动到页面底部时加载数据

    使用原生vue实现瀑布流,发现无法实现小程序那种滚动到地步触发加载效果,只能自己研究了 实现效果: 实现代码: 首先添加监听滚动事件 mounted() { window.addEventListen ...

  3. vue如何实现代码打包分离(按需加载)

    在vue中使用import()来代替require.ensure()实现代码打包分离 一.require.ensure() 方法来实现代码打包分离 require.ensure() 是 webpack ...

  4. vue项目实现路由按需加载的3种方式

    vue异步组件技术 ==== 异步加载vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件 /* vue异步组件技术 */ { ...

  5. 深入浅出的webpack4构建工具---webpack+vue+router 按需加载页面(十五)

    1. 为什么需要按需加载? 对于vue单页应用来讲,我们常见的做法把页面上所有的代码都打包到一个bundle.js文件内,但是随着项目越来越大,文件越来越多的情况下,那么bundle.js文件也会越来 ...

  6. 优雅的写好Vue项目代码 — 路由拆分、Vuex模块拆分、element按需加载

    目录 路由的拆分 VUEX模块拆分 Element UI库按需加载的优雅写法 路由的拆分 项目较大路由较多时,路由拆分是一个不错的代码优化方案,按不同业务分为多个模块,结构清晰便于统一管理. requ ...

  7. vue中路由按需加载的几种方式

    使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,如: import Hello from '@/components/Hello' import ...

  8. vue 动态路由按需加载的三种方式

    在Vue项目中,一般使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,如: import Hello from '@/components/Hell ...

  9. vue学习指南:第十二篇(详细) - Vue的 路由 第二篇 ( 路由按需加载(懒加载))

    各位朋友 因 最近工作繁忙,小编停更了一段时间,快过年了,小编祝愿 大家 事业有成 学业有成 快乐健康 2020开心过好每一天.从今天开始 我会抽时间把 Vue 的知识点补充完整,以及后期会带给大家更 ...

随机推荐

  1. 一篇谈Flink不错的文章

    精华 : 在执行引擎这一层,流处理系统与批处理系统最大不同在于节点间的数据传输方式.对于一个流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一 ...

  2. 运行批处理文件怎么不显示DOS命令窗口

    运行批处理文件怎么不显示DOS命令窗口   BAT没法不显示DOS窗口.你可以考虑用脚本保持以下到文本文件,重命名为AutoUp_ddyy.vbs set WshShell = WScript.Cre ...

  3. Delphi XE3写DLL,用Delphi7调用,报错!

    http://bbs.csdn.net/topics/390870532 用delphi xe3写的DLL,delphi7调用,参数都是PAnsiChar,DLL里的函数接收delphi7传的入参,没 ...

  4. Beta版本冲刺准备

    1. 介绍小组新加入的成员,Ta担任的角色. 姓名 王华俊 爱好 PS ,听音乐等等 编程方向 Java小程序,GUI 团队内担任的角色 美工 让他担任这个角色的理由:不同于别人的直男审美 2. 讨论 ...

  5. 从NetCore报错到MySql安全

    之前项目在测试服务器上的一些接口时不时会报出下面的错误:(采用Abp框架) "SocketException: 你的主机中的软件中止了一个已建立的连接. STACK TRACE: at My ...

  6. .netcore-FreeSql的使用-搭建context

    之前用netcore搭建了一个小项目,数据库操作用的是要手写sql语句的connection和command,一直想调个EFCore或者类似SOA那样的框架 今天看到了DotNet公众号提到的.NET ...

  7. PHP eval函数

    代码: eval("echo'hello world';"); 上边代码等同于下边的代码: echo"hello world"; 在浏览器中都输出:hello ...

  8. scanf的拓展用法——匹配特定字符

    scanf的基本用法除了常规的输入操作外还有一些特殊的用法,使用这些用法可以很方便的在输入中读取想要的数据 1.限制输入数据的长度 这个应该算不上拓展用法,大多数读者应该都曾经使用过,这里简单提一下 ...

  9. 文件上传下载、socketserver(并发)、解读socketserver源码

    1.文件上传/下载 学习了socket套接字,我们现在可以写一个文件上传/下载的程序,如下示例: 分析上边代码,我们发现,client发送上传文件相关信息的字典序列化之后,server又给client ...

  10. Java并发编程总结2——慎用CAS

    一.CAS和synchronized适用场景 1.对于资源竞争较少的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源:而CAS基于硬件实 ...