vue路由管理-保留滚动位置功能、按需加载模块名自定义
2017-11-06 21:44
936 查看
路由管理:保留滚动位置
其实现与组件的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' */可实现自定义包名,如果不需要自定义,可将该注释删除。
相关文章推荐
- 模块管理常规功能自定义系统的设计与实现(07--form窗口的调整)
- 模块管理常规功能自定义系统的设计与实现(18--模块附件的设计[1])
- 模块管理常规功能自定义系统的设计与实现(19--模块附件的设计[2])
- Android图片加载框架最全解析(六),探究Glide的自定义模块功能
- 模块管理常规功能自定义系统的设计与实现(02--基本原理)
- 模块管理常规功能自定义系统的设计与实现(30--第二阶段总结)
- 模块管理常规功能自定义系统的设计与实现(13--Grid导航设计初步[3])
- vue2.0路由切换后页面滚动位置不变BUG
- 模块管理常规功能自定义系统的设计与实现(09--数据新增[二、单条数据导入])
- 模块管理常规功能自定义系统的设计与实现(11--Grid导航设计初步[1])
- Android图片加载框架最全解析(六),探究Glide的自定义模块功能
- Android图片加载框架最全解析(六),探究Glide的自定义模块功能
- 模块管理常规功能自定义系统的设计与实现(23--二个模块之间的关联[1])
- 模块管理常规功能自定义系统的设计与实现(26--多个模块之间的关联[2])
- 模块管理常规功能自定义系统的设计与实现(12--Grid导航设计初步[2])
- 模块管理常规功能自定义系统的设计与实现(51--功能更新[1] 对父模块的链接显示)
- 动态加载权限管理模块中的Vue组件
- 模块管理常规功能自定义系统的设计与实现(34--终级阶段 综合查询[1])
- 模块管理常规功能自定义系统的设计与实现(41--终级阶段 综合查询[8]分类汇总)
- 模块管理常规功能自定义系统的设计与实现(10--数据新增[三、批量导入数据])