详解vue-router数据加载与缓存使用总结


Posted in Javascript onOctober 29, 2018

之前开发了一个单页面应用,按照深度,分为三层:目录页、一级子页(标签页、故事页等)、二级子页(故事编辑页)。

这三类页面都共享一个完整的数据model,从上级页面进入下一级页面时,能够加载相应数据;回到上一级时,数据有更新。举个栗子,从故事页点击“编辑”按钮,进入故事编辑页则默认填充点击的“编辑”按钮所对应的故事数据;而当在故事编辑页更新数据,返回到故事页时,刚刚更新的信息也能在故事页展示。

详解vue-router数据加载与缓存使用总结

对于这项需求,我们需要解决如下几个问题:

  • 三层页面共享数据;
  • 进入或退回当前路由时,数据更新;
  • 对于故事列表页,返回时保留之前浏览位置;

本文后面内容,将对如上问题一一提出解决方案。

共享数据

多个路由共享数据,可以使用vuex做数据中心,由于需求对数据处理并不复杂,为了简便就使用window全局对象作为路由间传递数据的工具。
核心数据我们可以设计为如下结构,以故事为例:

window.profileData = {
 storyList: [{
  content: 'xxx',
  type: 0,
  picList: [...],
 }, ...],
 description: {...}, // 其他字段数据
}

注意到,如果需要更新storyList,则应该使用能够被检测到的方法,如push, splice等。

数据更新与缓存

数据更新与缓存大致有两种方案:

第一种,利用vue-router的导航守卫(见文档:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html),主要使用路由组件内导航 beforeRouteEnter 和 beforeRouteLeave;

第二种,在路由组件中监听$route,每次路由变化就会调用其中方法加载数据,需要注意的是第一次进入路由组件$route的监听不会触发,我们需要在mounted方法中调用相同加载数据的方法;

我们在代码中使用的是方法一,以故事列表进入到故事编辑页为例,从列表传递index给编辑页,利用beforeRouteEnter进入路由时就加载新的数据。

编辑页中关键代码,即加载数据、更新本地共享数据:

export default {
 // 编辑页中, 进入路由前加载数据
 beforeRouteEnter(to, from, next) {
  next(vm => {
   const index = vm.$route.params.storyIndex
   vm.storyIndex = index
   vm.storyData = window.profile.storyList[index]
  })
 },

 methods: {
  // 提交成功后,更新本地共享数据
  submit() {
   Adapter.post('...').then(result => {
    window.profile.storyList.splice(this.storyIndex, 1, result)
   }) 
  },
 },
}

列表页中关键代码,即返回时更新数据:

export default {
 beforeRouteEnter(to, from, next) {
  next(vm => {
   vm.storyList = window.profileData.storyList
  })
 },
}

这部分需要注意的有两点:

  • beforeRouteEnter中无法调用组件实例,因为执行时还在组件生命周期的beforeCreate之前,而其中的next方法是在组件mounted之后执行,如需引用可在next方法中,引用其参数,该参数就是组件实例;
  • 如果发现你的next方法无法执行,请升级到2.6+版本,之前的版本这部分有些问题;

保留浏览位置

从故事编辑页回到故事列表页,我们希望可以保存之前浏览的位置。思路也很简单,进入编辑页时保存scrollTop,返回时scrollTo即可。而且vue-router对象有属性可以实现这个功能,这就简洁多了。

由于我们过渡动画中间,有将路由组件定位成fixed的操作,所以,动画结束后再手动滚动到目标位置:

new VueRouter({
 routes,
 scrollBehavior (to, from, savedPosition) {
  const y = savedPosition && savedPosition.y || 0
  setTimeout(() => { window.scrollTo(0, y) }, 300)
 }
})

总结

vue-router我们在偏B端的场景中经常用到,尤其是分步骤填写表单的页面。前期在使用过程中总是不太顺畅,摸索几次后,最终找到比较“舒适”的使用方法,索性就梳理成文。
当然,还有其他一些特殊场景的用法,这里暂时不说了,等项目中用过后再另起一文,继续研究。

参考文献

1. 《官方文档》
2. 《滚动行为》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery中add实现同时选择两个id对象
Oct 22 Javascript
javascript:void(0)是什么意思示例介绍
Nov 17 Javascript
JavaScript生成的动态下雨背景效果实现方法
Feb 25 Javascript
js实现网页图片延时加载 提升网页打开速度
Jan 26 Javascript
浏览器复制插件zeroclipboard使用指南
Mar 26 Javascript
使用 stylelint检查CSS_StyleLint
Apr 28 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
Sep 21 Javascript
javascript 内置对象及常见API详细介绍
Nov 01 Javascript
vue安装遇到的5个报错及解决方法
Jun 12 Javascript
vue 组件中使用 transition 和 transition-group实现过渡动画
Jul 09 Javascript
vue 清空input标签 中file的值操作
Jul 21 Javascript
在react项目中使用antd的form组件,动态设置input框的值
Oct 24 Javascript
vue mounted 调用两次的完美解决办法
Oct 29 #Javascript
Electron中实现大文件上传和断点续传功能
Oct 28 #Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
Oct 28 #Javascript
Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
Oct 28 #Javascript
深入浅析javascript函数中with
Oct 28 #Javascript
微信小程序动画(Animation)的实现及执行步骤
Oct 28 #Javascript
又拍云 Node.js 实现文件上传、删除功能
Oct 28 #Javascript
You might like
PHP添加图片水印、压缩、剪切的封装类
2015/08/17 PHP
详解WordPress中过滤链接与过滤SQL语句的方法
2015/12/18 PHP
如何正确配置Nginx + PHP
2016/07/15 PHP
php批量修改表结构实例
2017/05/24 PHP
CutePsWheel javascript libary 控制输入文本框为可使用滚轮控制的js库
2010/02/07 Javascript
Javascript面向对象设计一 工厂模式
2011/12/20 Javascript
jquery struts 验证唯一标识(公用方法)
2013/03/27 Javascript
利用CSS、JavaScript及Ajax实现高效的图片预加载
2013/10/16 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
2016/04/01 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
Angular-Ui-Router+ocLazyLoad动态加载脚本示例
2017/03/02 Javascript
jQuery Masonry瀑布流布局神器使用详解
2017/05/25 jQuery
简单实现js拖拽效果
2017/07/25 Javascript
详解JS中的柯里化(currying)
2017/08/17 Javascript
angular2中使用第三方js库的实例
2018/02/26 Javascript
Vue 中mixin 的用法详解
2018/04/23 Javascript
浅析js中mvvm模式实现的原理
2018/10/06 Javascript
微信小程序云开发 搭建一个管理小程序
2019/05/17 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
[01:08:30]DOTA2-DPC中国联赛 正赛 Ehome vs Elephant BO3 第一场 2月28日
2021/03/11 DOTA
python排序方法实例分析
2015/04/30 Python
python实现的守护进程(Daemon)用法实例
2015/06/02 Python
Python对数据库操作
2016/03/28 Python
pandas ix &iloc &loc的区别
2019/01/10 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
2019/02/26 Python
python程序文件扩展名知识点详解
2020/02/27 Python
如何基于Django实现上下文章跳转
2020/09/16 Python
详解h5页面在不同ios设备上的问题总结
2019/03/01 HTML / CSS
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
全球领先的在线cosplay服装商店:RoleCosplay
2020/01/18 全球购物
内科护士实习自我鉴定
2013/10/17 职场文书
厂长助理岗位职责
2013/12/27 职场文书
《邮票齿孔的故事》教学反思
2014/02/22 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
超市店长竞聘书
2015/09/15 职场文书
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python