零、前言

  最近参与了一个立足 seo 的移动端项目,公司前端工程主栈 vue,所以理所当然的用上了 nuxt,UI 主要选择了 Vant。
 

一、公共列表页的缓存

  公共列表页由于数据量较大,故需要滚动触发分次加载以模拟分页,当客户端加载到了一定页数之后(>= 2),点击某条数据进去查看详情,然后返回列表页,这时候如果没有缓存的话,列表页会按照初始参数(即从分页 1 开始)发请求拉数据,并且丢失浏览位置。一方面,浪费请求资源,另一方面,用户体验不佳。因此,针对这两个问题,最后决定开启缓存。
  vue 中的缓存直接使用 <keep-live> 组件即可,配合上 vue-router 中的 scrollBehavior 往往能比较容易地实现。当然这里容易有忽略:“scrollBehavior 只在支持 history.pushState 的浏览器中可用。” 接受三个参数,to, from, savedPosition, 而 savedPosition “当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。” 这意味这个参数着只有 this.$router.go(...) 有效,this.$router.push() 时是无效的!并且,我们在使用 <keep-live> 时,通常会在自定义的路由中添加某些字段,但 nuxt 的路由是自动生成的,这里是最大的限制。
  这里有一个前置,在 nuxt.js 的 1.x 某个更新中, <nuxt> 和 <nuxtChild> 组件添加了 keepAlive 属性。于是我们可以在 default.vue 中定制这个属性:

<nuxt :keep-alive='viewCache' :keepAliveProps="{include: includeArr}"/>

data() {
return {
cache: false,
includeArr: ['list-name-1', 'list-name-2'] // 组件的 name
}
} watch: {
'$route': function(new, old) {
if (...) {
this.cache = true;
} else {
this.cache = false;
}
}
}
然后,在跳转进入列表页的组件上绑定相应的参数,从而控制是否需要缓存,如:

this.$router.push({
name: 'list-name-1',
params: {
cache: true
}
})
最后,绑定 keepAliveProps 是为了避免多余组件的缓存.
另外,从列表页跳转详情页的时候,也需要加上控制字段,如:

this.$router.push({
name: 'details-name-1',
params: {
details_id: xxxxx,
cache: true
}
})
并且,从详情页返回时,也需要加上控制字段,如
this.$router.push({
name: 'list-name-1',
params: {
cache: true
}
})
  至此,可以解决请求浪费,列表数据缓存的问题,同时,缺点也比较明显,需要在父组件/列表页/详情页同时添加控制字段才能实现,耦合度较高,并且,用户在列表页刷新一下即失效。
  其次,对于滚动条位置记录,在多番尝试之后,也没有一个较便捷的方法。原因除上文中提到的 savedPosition 的限制以外,与列表数据的缓存也有关系:整个页面的高度需要由数据撑开,然后才能进行滚动。下面是我的解决方案,依赖上文中的组件(数据)缓存:
  
  由于列表页不进行 ssr, 故在使用 keepAlive 时同时可以使用 vue 的 activated/deactivated 这两个生命周期:

activated() {
setTimeout(() => {
window.scrollTo(0, this.scrollPosition);
// window.scrollTo({
// top: this.scrollPosition,
// behavior: "smooth"
// });
}, 0)
},
deactivated(){
this.scrollPosition = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
}
 
  这里需要注意的是要使用 setTimeout (或者this.$nextTick(),不过我尝试的时候没有效果),否则不会滚动。
  当然,这里也存在一定的问题, window.scrollTo(x, y) 动作是瞬间完成的,因此可能会存在一定的闪烁情况,而使用 window.scrollTo({..., behavior: "smooth" }) 则在每次用户返回的时候都会有个明显的下滑动作,所以,如何取舍,应当依据实际情况。
 
附上对列表数据缓存的实践和资料:
* (未尝试) 使用服务器缓存 - https://juejin.im/post/5b2b62096fb9a00e61494b0b
* ✗ 使用 van-popup/dialog 组件 - 但是会引起 asyncData 中的传值收值
* ✗ this.$router.go 函数 - 无法缓存
* ✗ 使用 $store + van-popup/dialog,_details 是页面级组件,如果使用 import 导入将不会触发 asyncData 方法,从而导致某些依赖性数据为 undefinded, 最终在 rendering 过程报错。
 

二、动态路由

  同一个文件夹下不应该存在两个及以上的 _xxx.vue (动态)组件。
 

三、生命周期

  nuxt.js 的服务端渲染过程基于 node,所以其某些周期是运行在服务端的,在引入第三方插件,或者直接在代码中使用 window 和 document 时,控制台会给出警告:window 未定义。

  解决办法有两种:

    1、使用 process.browser 来区分环境,如:

if (process.browser) {
// 修改window对象下某一属性
window.mbk = ...
}

    2、在 mounted 以及之后的周期中使用;

Nuxt.js 踩坑笔记 - 缓存向的更多相关文章

  1. Nuxt.js 踩坑记录,(1)引入fs包报错

    今天又是码农的一天. 但是写着写着,不知道为啥就页面就报错了, 如图所示,我在db/app.js下引入了fs这个模块,提示我npm install,我也照做了,但是仍然报错. 通过各种百度,踩坑,最终 ...

  2. Nuxt.js 踩坑记录(2) 使用sequelize时,提示install mysql2,安装了仍然不能解决问题

    打算写一个nuxt.js+sequelize+mysql的个人博客,遇到了挺多坑,还是坚持了下来,终于解决了这个bug. 今天不知道我做了什么,页面就报错了,定位到了使用sequelize的JS文件里 ...

  3. nuxt.js踩坑之 - SSR 与 CSR 显示不一致问题

    [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This ...

  4. Nuxt.js 踩坑记录(3) Net.connection xxxx

    浏览器报的是Net.connection啥的错误 项目运行时报错这个 [HPM] Error occurred while trying to proxy request article from l ...

  5. react基础学习和react服务端渲染框架next.js踩坑

    说明 React作为Facebook 内部开发 Instagram 的项目中,是一个用来构建用户界面的优秀 JS 库,于 2013 年 5 月开源.作为前端的三大框架之一,React的应用可以说是非常 ...

  6. EntityFramework CodeFirst SQLServer转Oracle踩坑笔记

    接着在Oracle中使用Entity Framework 6 CodeFirst这篇博文,正在将项目从SQLServer 2012转至Oracle 11g,目前为止遇到的问题在此记录下. SQL Se ...

  7. CAS5.3服务器搭建与客户端整合SpringBoot以及踩坑笔记

    CAS5.3服务器搭建与客户端整合SpringBoot以及踩坑笔记 cas服务器的搭建 导出证书(1和2步骤是找了课程,随便写了一下存记录,不过对于自己测试不投入使用应该不影响) C:\Users\D ...

  8. 微信小程序使用pako.js的踩坑笔记

    问题 今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串).第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之 ...

  9. vue.js 踩坑第一步 利用vue-cli vue-router搭建一个带有底部导航栏移动前端项目

    vue.js学习 踩坑第一步 1.首先安装vue-cli脚手架 不多赘述,主要参考WiseWrong 的 Vue 爬坑之路(一)-- 使用 vue-cli 搭建项目 2.项目呈现效果 项目呈现网址:w ...

随机推荐

  1. 论 <解方程>

    题面: 求n次整系数方程\(\sum_{i=1}^{n} a_ix^i = 0\)在区间\([1,m]\)上的整数解 解法: 1.暴力 O(NM) 暴力枚举+解方程 2.假设只要求一个解 瞎搞做法 引 ...

  2. fatal error C1189: #error: "You must define TF_LIB_GTL_ALIGNED_CHAR_ARRAY for your compiler."

    使用VS开发tensorflow的C++程序的时候,就可能会遇上这个问题,解决方法是在引入tensoflow的头文件之前添加: #define COMPILER_MSVC #define NOMINM ...

  3. goahead(web服务器)分析

    一.参考网址 1.源码的github地址 二.网页是采用文件读写方式,还是转换为数组方式? 1)其通过宏定义“WEBS_PAGE_ROM”来区分,我是在websPageReadData()(page. ...

  4. offer(背包问题、DP)

    蒜头君很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的.蒜头君没有多少钱,总共只攒了n万元 ...

  5. javaweb学习——session和Cookie实现购物车功能

    1.创建Book类,实现对图书信息的封装. package cn.it.sessionDemo.example1; import java.io.Serializable; /** * 该类实现对图书 ...

  6. mysql 创建帐号出现 Access denied for user 'root'@'localhost'错误(转载)

    从供应商那边接手一个MySQL数据库(数据库版本为5.7.21 MySQL Community Server (GPL)),在创建账号时遇到了“ERROR 1044 (42000): Access d ...

  7. NGDC|BIGD

    生命组学 生命起源经过复杂演化诞生了大量生物体及其基因组. 现今NCBI最大的基因组: 植物:糖松27.6G 动物:墨西哥蝾螈32.4G 大数据能做什么? 大数据时代如同大航海时代一样,需要具有与时代 ...

  8. ZJNU 1538 - YN!ngC的取子游戏--高级

    Nim博弈 因为移动到第0阶会消失 所以可以得到从最后一个人操作必定是把第1阶所有子全部移动到第0阶 递推可得,最后一个能把奇数阶的子移动到偶数阶上的人将会必胜 所以这个必胜条件就是奇数阶上的子全部为 ...

  9. sql server2008 装上后,总是出现machine.config line136,或者 出现 配置错误 无法识别的配置节 system.serviceModel 。

    怀疑问题是vs 和 sql server2008安装冲突的问题造成, 有一个这样的说法: 用win8.1的64位 的系统,如果先装vs2010,再装sql server 2008 r2,根本就不行,一 ...

  10. js实际应用

    -----------------------------获取select选中的值------------------------- 原生JS获得选中select值 var obj = documen ...