vue2中的keep-alive使用总结及注意事项


Posted in Javascript onDecember 21, 2017

keep-alive 是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。结合vue-router中使用,可以缓存某个view的整个内容。

基本使用如下:

<keep-alive>
 <component>
 <!-- 该组件将被缓存! -->
 </component>
</keep-alive>

一般有这样的需求,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页

有两个情况:

1. 直接点击浏览器的后退返回按钮。

2. 点击导航栏中的 /list的链接返回。

那么针对第一种情况下,我们直接通过后退按钮时,返回到列表页(/list) 是不需要请求数据。

针对第二种情况下,我们通过链接返回到列表页是需要请求数据。

所以这边有三种情况:

1. 默认进来列表页需要请求数据。

2. 进入详情页后,通过浏览器默认后退按钮返回,是不需要ajax的请求的。

3. 进入详情页后,通过点击链接返回到列表页后,也是需要发ajax请求的。

配置如下:

1. 入口文件 app.vue 的配置如下:

<!-- 缓存所有的页面 -->
<keep-alive>
 <router-view v-if="$route.meta.keep_alive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keep_alive"></router-view>

2. 在router中设置meta属性,设置 keepAlive: true 表示需要使用缓存,false的话表示不需要使用缓存。且添加滚动行为 scrollBehavior

router/index.js 的配置如下:

import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';
Vue.use(Router);
const router = new Router({
 mode: 'history', // 访问路径不带井号 需要使用 history模式,才能使用 scrollBehavior
 base: '/page/app', // 配置单页应用的基路径
 routes: [
 {
  path: '/',
  name: 'list',
  component: resolve => require(['@/views/list'], resolve), // 使用懒加载
  meta: {
  keepAlive: true // true 表示需要使用缓存
  }
 },
 {
  path: '/list',
  name: 'list',
  component: resolve => require(['@/views/list'], resolve), // 使用懒加载
  meta: {
  keepAlive: true // true 表示需要使用缓存 false表示不需要被缓存
  }
 },
 {
  path: '/detail',
  name: 'detail',
  component: resolve => require(['@/views/detail'], resolve) // 使用懒加载
 }
 ],
 scrollBehavior (to, from, savedPosition) {
 // 保存到 meta 中,备用
 to.meta.savedPosition = savedPosition;
 if (savedPosition) {
  return { x: 0, y: 0 };
 }
 return {};
 }
});
export default router;

3. list.vue 代码如下:

<template>
 <div class="hello">
 <h1>vue</h1>
 <h2>{{msg}}</h2>
 <router-link to="/detail">跳转到detail页</router-link>
 </div>
</template>

<script>
export default {
 name: 'helloworld',
 data () {
 return {
  msg: 'Welcome to Your Vue.js App'
 };
 },
 methods: {
 ajaxRequest() {
  const obj = {
  'aa': 1
  };
  Promise.all([this.$store.dispatch('testUrl', obj)]).then((res) => {
  console.log(res);
  });
 }
 },
 beforeRouteEnter(to, from, next) {
 next(vm => {
  /*
  如果 to.meta.savedPosition === undefined 说明是刷新页面或可以叫第一次进入页面 需要刷新数据
  如果savedPosition === null, 那么说明是点击了导航链接;
  此时需要刷新数据,获取新的列表内容。
  否则的话 什么都不做,直接使用 keep-alive中的缓存
  */
  if (to.meta.savedPosition === undefined) {
  vm.ajaxRequest();
  }
  if (to.meta.savedPosition === null) {
  vm.ajaxRequest();
  }
 })
 }
};
</script>

4. detail.vue 代码如下:

<template>
 <div class="list">
 <h1>{{msg}}</h1>
 <router-link to="/list">返回列表页</router-link>
 </div>
</template>
<script>
export default {
 name: 'list',
 data () {
 return {
  msg: 'Welcome to Your Vue.js App'
 };
 },
 created() {
 this.ajaxRequest();
 },
 methods: {
 ajaxRequest() {
  const obj = {
  'aa': 1
  };
  Promise.all([this.$store.dispatch('withdary', obj)]).then((res) => {
  console.log(res);
  });
 }
 }
};
</script>

二:使用router.meta 扩展

假设现在有3个页面,需求如下:

1. 默认有A页面,A页面进来需要一个请求。

2. B页面跳转到A页面,A页面不需要重新请求。

3. C页面跳转到A页面,A页面需要重新请求。

实现方式如下:

在 A 路由里面设置 meta 属性:

{
 path: '/a',
 name: 'A',
 component: resolve => require(['@/views/a'], resolve),
 meta: {
 keepAlive: true // true 表示需要使用缓存
 }
}

所以router/index下的所有代码变为如下:

import Vue from 'vue';
import Router from 'vue-router';
// import HelloWorld from '@/views/HelloWorld';

Vue.use(Router);

const router = new Router({
 mode: 'history', // 访问路径不带井号 需要使用 history模式,才能使用 scrollBehavior
 base: '/page/app', // 配置单页应用的基路径
 routes: [
 {
  path: '/',
  name: 'list',
  component: resolve => require(['@/views/list'], resolve), // 使用懒加载
  meta: {
  keepAlive: true // true 表示需要使用缓存
  }
 },
 {
  path: '/list',
  name: 'list',
  component: resolve => require(['@/views/list'], resolve), // 使用懒加载
  meta: {
  keepAlive: true // true 表示需要使用缓存 false表示不需要被缓存
  }
 },
 {
  path: '/detail',
  name: 'detail',
  component: resolve => require(['@/views/detail'], resolve) // 使用懒加载
 },
 {
  path: '/a',
  name: 'A',
  component: resolve => require(['@/views/a'], resolve),
  meta: {
  keepAlive: true // true 表示需要使用缓存
  }
 },
 {
  path: '/b',
  name: 'B',
  component: resolve => require(['@/views/b'], resolve)
 },
 {
  path: '/c',
  name: 'C',
  component: resolve => require(['@/views/c'], resolve)
 }
 ],
 scrollBehavior (to, from, savedPosition) {
 // 保存到 meta 中,备用
 to.meta.savedPosition = savedPosition;
 if (savedPosition) {
  return { x: 0, y: 0 };
 }
 return {};
 }
});
export default router;

在 B 组件里面设置 beforeRouteLeave

beforeRouteLeave(to, from, next) {
 // 设置下一个路由meta
 to.meta.keepAlive = true; // 让A缓存,不请求数据
 next(); // 跳转到A页面
}

B组件所有代码如下:

<template>
 <div class="list">
 <h1>{{msg}}</h1>
 <router-link to="/a">返回a页面</router-link>
 </div>
</template>

<script>
export default {
 name: 'list',
 data () {
 return {
  msg: 'Welcome to B Page'
 };
 },
 created() {},
 methods: {
 },
 beforeRouteLeave(to, from, next) {
 // 设置下一个路由meta
 to.meta.keepAlive = true; // 让A缓存,不请求数据
 next(); // 跳转到A页面
 }
};
</script>

在 C 组件里面设置 beforeRouteLeave:

beforeRouteLeave(to, from, next) {
 // 设置下一个路由meta
 to.meta.keepAlive = false; // 让A不缓存,重新请求数据
 console.log(to)
 next(); // 跳转到A页面
}

c组件所有代码如下:

<template>
 <div class="list">
 <h1>{{msg}}</h1>
 <router-link to="/a">返回a页面</router-link>
 </div>
</template>

<script>
export default {
 name: 'list',
 data () {
 return {
  msg: 'Welcome to B Page'
 };
 },
 created() {},
 methods: {
 },
 beforeRouteLeave(to, from, next) {
 // 设置下一个路由meta
 to.meta.keepAlive = false; // 让A不缓存,重新请求数据
 console.log(to)
 next(); // 跳转到A页面
 }
};
</script>

a组件内的所有的代码如下:

<template>
 <div class="hello">
 <h1>vue</h1>
 <h2>{{msg}}</h2>
 <router-link to="/b">跳转到b页面</router-link>
 <router-link to="/c">跳转到c页面</router-link>
 </div>
</template>

<script>
export default {
 name: 'helloworld',
 data () {
 return {
  msg: 'Welcome to A Page'
 };
 },
 methods: {
 ajaxRequest() {
  const obj = {
  'aa': 1
  };
  Promise.all([this.$store.dispatch('testUrl', obj)]).then((res) => {});
 }
 },
 beforeRouteEnter(to, from, next) {
 next(vm => {
  /*
  如果 to.meta.savedPosition === undefined 说明是刷新页面或可以叫第一次进入页面 需要刷新数据
  如果to.meta.keepAlive === false, 那么说明是需要请求的;
  此时需要刷新数据,获取新的列表内容。
  否则的话 什么都不做,直接使用 keep-alive中的缓存
  */
  if (to.meta.savedPosition === undefined) {
  vm.ajaxRequest();
  }
  if (!to.meta.keepAlive) {
  vm.ajaxRequest();
  }
 })
 }
};
</script>

注意 b组件到a组件不重新请求数据 (包括点击链接和浏览器后退按钮),c组件到a组件请求数据(包括点击链接和浏览器后退按钮).

查看github上的代码

总结

以上所述是小编给大家介绍的vue2中的keep-alive使用总结及注意事项,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
IE 下的只读 innerHTML
Aug 21 Javascript
在javascript中关于节点内容加强
Apr 11 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
Sep 03 Javascript
JavaScript实现自动弹出窗口并自动关闭窗口的方法
Aug 06 Javascript
利用Vue.js指令实现全选功能
Sep 08 Javascript
bootstrap table复杂操作代码
Nov 01 Javascript
js实现倒计时效果(小于10补零)
Mar 08 Javascript
JS回调函数基本定义与用法实例分析
May 24 Javascript
ComboBox(下拉列表框)通过url加载调用远程数据的方法
Aug 06 Javascript
vue.js项目中实用的小技巧汇总
Nov 29 Javascript
微信小程序实现倒计时补零功能
Jul 09 Javascript
elementUI select组件value值注意事项详解
May 29 Javascript
webpack写jquery插件的环境配置
Dec 21 #jQuery
基于Vue 2.0的模块化前端 UI 组件库小结
Dec 21 #Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
Dec 21 #Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
Dec 20 #Javascript
代码详解Vuejs响应式原理
Dec 20 #Javascript
详解Javascript 中的 class、构造函数、工厂函数
Dec 20 #Javascript
在一个页面实现两个zTree联动的方法
Dec 20 #Javascript
You might like
PHP实现定时生成HTML网站首页实例代码
2008/11/20 PHP
php 删除数组元素
2009/01/16 PHP
DW中链接mysql数据库时,建立字符集中文出现乱码的解决方法
2010/03/27 PHP
解析php中die(),exit(),return的区别
2013/06/20 PHP
zf框架的Filter过滤器使用示例
2014/03/13 PHP
ThinkPHP标签制作教程
2014/07/10 PHP
去除链接虚线全面分析总结
2006/08/15 Javascript
jQuery 过滤not()与filter()实例代码
2012/05/10 Javascript
『JavaScript』限制Input只能输入数字实现思路及代码
2013/04/22 Javascript
禁止ajax缓存获取程序最新数据的方法
2013/11/19 Javascript
JavaScript中的alert()函数使用技巧详解
2014/12/29 Javascript
JS实现简单的二维矩阵乘积运算
2016/01/26 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
微信小程使用swiper组件实现图片轮播切换显示功能【附源码下载】
2017/12/12 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
JQuery 实现文件下载的常用方法分析
2019/10/29 jQuery
VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析
2019/12/02 Javascript
微信小程序swiper左右扩展各显示一半代码实例
2019/12/05 Javascript
[02:27]DOTA2英雄基础教程 莱恩
2014/01/17 DOTA
Python计算三维矢量幅度的方法
2015/06/15 Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
2016/01/20 Python
python简单验证码识别的实现方法
2019/05/10 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
python传到前端的数据,双引号被转义的问题
2020/04/03 Python
Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】
2020/05/29 Python
Pytorch 图像变换函数集合小结
2021/02/01 Python
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
天逸系统(武汉)有限公司Java笔试题
2015/12/29 面试题
求高于平均分的学生学号及成绩
2016/09/01 面试题
乡镇庆八一活动方案
2014/02/02 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
节约用电通知
2015/04/25 职场文书
2019年中,最受大众欢迎的6本新书
2019/08/07 职场文书
Python中使用ipython的详细教程
2021/06/22 Python
python中tkinter复选框使用操作
2021/11/11 Python
Java后端 Dubbo retries 超时重试机制的解决方案
2022/04/14 Java/Android