详解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升级新版本后选择器的语法问题
Jun 02 Javascript
jQuery编写widget的一些技巧分享
Oct 28 Javascript
JavaScript异步调用定时方法并停止该方法实现代码
Mar 16 Javascript
JS小功能(onmouseover实现选择月份)实例代码
Nov 28 Javascript
Javascript变量作用域详解
Dec 06 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
Jul 01 Javascript
小心!AngularJS结合RequireJS做文件合并压缩的那些坑
Jan 09 Javascript
JS 清除字符串数组中,重复元素的实现方法
May 24 Javascript
超详细的JS弹出窗口代码大全
Apr 18 Javascript
Javascript中for循环语句的几种写法总结对比
Jan 23 Javascript
Node.js 使用AngularJS的方法示例
May 11 Javascript
JavaScript监听触摸事件代码实例
Dec 30 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生成HTML静态页面实例代码
2008/08/31 PHP
用php制作简单分页(从数据库读取记录)的方法详解
2013/05/04 PHP
解析Ubuntu下crontab命令的用法
2013/06/24 PHP
PHP延迟静态绑定示例分享
2014/06/22 PHP
php生成固定长度纯数字编码的方法
2015/07/09 PHP
jquery不支持toggle()高(新)版本的问题解决
2016/09/24 PHP
PHP+Mysql+Ajax实现淘宝客服或阿里旺旺聊天功能(前台页面)
2017/06/16 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
javaScript - 如何引入js代码
2021/03/09 Javascript
JS中==与===操作符的比较
2009/03/21 Javascript
基于jquery的仿百度搜索框效果代码
2011/04/11 Javascript
Javascript中string转date示例代码
2013/11/01 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
2014/03/05 Javascript
js实现适用于素材网站的黑色多级菜单导航条效果
2015/08/24 Javascript
基于javascript简单实现对身份证校验
2021/01/25 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
vue2.0移除或更改的一些东西(移除index key)
2017/08/28 Javascript
vue.js2.0 实现better-scroll的滚动效果实例详解
2018/08/13 Javascript
vue中v-for循环给标签属性赋值的方法
2018/10/18 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
2018/11/02 Javascript
Javascript实现一朵从含苞到绽放的玫瑰
2019/03/30 Javascript
[50:21]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第二场
2018/08/19 DOTA
[35:29]Secret vs VG 2018国际邀请赛淘汰赛BO3 第三场 8.23
2018/08/24 DOTA
[48:11]完美世界DOTA2联赛 Magma vs GXR 第二场 11.07
2020/11/10 DOTA
python实现在图片上画特定大小角度矩形框
2018/10/24 Python
python 实现图片旋转 上下左右 180度旋转的示例
2019/01/24 Python
Python学习笔记之集合的概念和简单使用示例
2019/08/22 Python
python 对xml解析的示例
2021/02/27 Python
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
初中英语教学反思
2014/01/25 职场文书
信息科学与技术专业求职信范文
2014/02/20 职场文书
个人培训自我鉴定
2014/03/28 职场文书
小学生环保演讲稿
2014/04/25 职场文书
升职演讲稿范文
2014/05/23 职场文书
[有人@你]你有一封绿色倡议书,请查收!
2019/07/18 职场文书
pytorch MSELoss计算平均的实现方法
2021/05/12 Python