详解基于vue的移动web app页面缓存解决方案


Posted in Javascript onAugust 03, 2017

现在移动web app越来越热门了,许多公司开始尝试使用angular、react、vue等MVVM框架来开发单页架构的web app。但在开发web app时,如果希望页面的导航体验也接近原生应用,那一般都会遇到这两个问题:

  • 识别前进后退行为
  • 后退时恢复之前的页面

笔者开发了一个基于vue与vue-router的导航库vue-navigation,来帮助开发者来解决这些问题,下面是问题的解决思路。

识别前进后退

先说第一个问题。和原生app不一样,浏览器中主要有这几个限制:

  • 没有提供前进后退的事件
  • 不允许开发者读取浏览记录
  • 用户可以手动输入地址,或使用浏览器提供的前进后退来改变url

解决方案是自己维护一份浏览记录,每次url改变时,通过与记录的浏览记录作对比,从而判断出前进后退行为:

  • url存在于浏览记录中即为后退
  • url不存在于浏览记录中即为前进
  • url在浏览记录的末端即为刷新

另外,应用的路由路径中可能允许相同的路由出现多次(例如A->B->A),所以给每个路由添加一个key值来区分相同路由的不同实例。

这个浏览记录需要存储在sessionStorage中,这样用户刷新后浏览记录也可以恢复。

后退时恢复之前的页面

识别出后退行为后,下一步就是像原生一样恢复之前的页面了。

一种方案是页面继续存储在DOM中,添加样式display: none来告诉浏览器不渲染该元素,但是缓存的页面多了DOM就会变得很大,会影响页面的性能,本文不讨论这个方案。

另一种方案是将数据缓存到内存中,开发者需要将页面的数据存储起来,当返回到该页面时,再根据数据将页面恢复。但是这样每个页面存储的数据不通,一般需要进行额外的编码,如果有一种更底层的方案能解决这个问题,并且对开发者是透明的,就最好了,所以尝试并开发了vue-navigation。

在vue-navigation 0.x版本的时候,借助了vue的keep-alive来缓存页面,但是keep-alive是根据组件的name或tag来决定缓存的,所以带来了很多限制。

通过拜读keep-alive的源码,了解到它的缓存机制后,就自己实现了一个管理缓存的组件,来灵活地缓存子组件,实现思路如下:

  1. 每次render时,先取到子组件的vnode(vue的虚拟dom)
  2. 计算出vnode的key,把key值赋给vnode避免vue-router复用组件实例
  3. 根据key值判断该节点是否已缓存
    1. 已缓存:将缓存的实例赋给componentInstance,这样vue就会根据这个实例来恢复组件
    2. 未缓存:将vnode存储到内存中,下次返回到该页面时可以从内存中恢复

另外还需要添加一个清除缓存的逻辑,当自己维护的浏览记录变化时,根据浏览记录清除不需要的缓存(例如当前的路由是:A->B->C,用户从C直接返回到了A,那么B和C都需要从缓存中删除)。

最后

虽然是基于vue来开发的,但是思路是不变的,使用其他框架也可以做到同样的事情。

还是安利一下vue和vue-navigation。使用插件后,再将router-view放在navigation下就有缓存功能了。

main.js

import Vue from 'vue'
import router from './router' // vue-router 实例
import Navigation from 'vue-navigation'
Vue.use(Navigation, {router})
// 启动你的应用...

App.vue

<template>
 <navigation>
  <router-view></router-view>
 </navigation>
</template>

最后欢迎大家讨论或提供更好的解决方案。

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

Javascript 相关文章推荐
理解JavaScript中的对象 推荐
Jan 09 Javascript
使用js修改客户端注册表的方法
Aug 09 Javascript
IE、FF、Chrome浏览器中的JS差异介绍
Aug 13 Javascript
无限树Jquery插件zTree的常用功能特性总结
Sep 11 Javascript
使用javascript插入样式
Mar 14 Javascript
jquery动态切换背景图片的简单实现方法
May 14 Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
Dec 21 Javascript
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
Dec 29 Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
Jan 19 Javascript
如何在JavaScript中正确处理变量
Dec 25 Javascript
vue实现拖拽交换位置
Apr 07 Vue.js
Bootstrap与Angularjs的模态框实例代码
Aug 03 #Javascript
基于 Bootstrap Datetimepicker 联动
Aug 03 #Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 #Javascript
webpack开发跨域问题解决办法
Aug 03 #Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
Aug 03 #Javascript
react-native ListView下拉刷新上拉加载实现代码
Aug 03 #Javascript
解决ionic和angular上拉加载的问题
Aug 03 #Javascript
You might like
php UBB 解析实现代码
2011/11/27 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
PHP实现C#山寨ArrayList的方法
2015/07/16 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
PHP批量修改文件名称的方法分析
2017/02/27 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
从新浪弄下来的全屏广告代码 与使用说明
2007/03/15 Javascript
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
Js放到HTML文件中的哪个位置有什么区别
2013/08/21 Javascript
CSS+jQuery实现的一个放大缩小动画效果
2013/09/24 Javascript
Js保留小数点的4种效果实现代码分享
2014/04/12 Javascript
js下将阿拉伯数字每三位一逗号分隔(如:15000000转化为15,000,000)
2014/06/02 Javascript
javascript实现复选框超过限制即弹出警告框的方法
2015/02/25 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
JS获取鼠标选中的文字
2016/08/10 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
vuex + axios 做登录验证 并且保存登录状态的实例
2018/09/16 Javascript
VUE路由动态加载实例代码讲解
2019/08/26 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
详解Vite的新体验
2021/02/22 Javascript
[02:09]EHOME夺得首届辉夜杯冠军—现场颁奖仪式
2015/12/28 DOTA
初步认识Python中的列表与位运算符
2015/10/12 Python
MySQL适配器PyMySQL详解
2017/09/20 Python
Python3一行代码实现图片文字识别的示例
2018/01/15 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
pytorch 实现将自己的图片数据处理成可以训练的图片类型
2020/01/08 Python
python statsmodel的使用
2020/12/21 Python
HTML5 离线应用之打造零请求、无流量网站的解决方法
2013/04/25 HTML / CSS
美国女性卫生用品公司:Thinx
2017/06/30 全球购物
出纳员的岗位职责
2014/02/22 职场文书
给校长的建议书
2014/03/12 职场文书
如何利用map实现Nginx允许多个域名跨域
2021/03/31 Servers
基于Python实现nc批量转tif格式
2022/08/14 Python