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 相关文章推荐
php上传图片并给图片打上透明水印的代码
Jun 07 Javascript
javascript 窗口加载蒙板 内嵌网页内容
Nov 19 Javascript
利用js读取动态网站从服务器端返回的数据
Feb 10 Javascript
Javascript 赋值机制详解
Nov 23 Javascript
基于JavaScript实现 网页切出 网站title变化代码
Apr 03 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
May 30 Javascript
js导出excel文件的简洁方法(推荐)
Nov 02 Javascript
浅谈React深度编程之受控组件与非受控组件
Dec 26 Javascript
vue router 配置路由的方法
Jul 26 Javascript
JavaScript JSON数据处理全集(小结)
Aug 15 Javascript
JS数据类型(基本数据类型、引用数据类型)及堆和栈的区别分析
Mar 04 Javascript
JavaScript实现捕获鼠标坐标
Apr 12 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
Javascript与PHP验证用户输入URL地址是否正确
2014/10/09 PHP
Aster vs Newbee BO5 第一场2.19
2021/03/10 DOTA
jquery blockUI 遮罩不能消失与不能提交的解决方法
2011/09/17 Javascript
js自定义事件及事件交互原理概述(一)
2013/02/01 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
2014/05/19 Javascript
《JavaScript DOM 编程艺术》读书笔记之DOM基础
2015/01/09 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
实例剖析AngularJS框架中数据的双向绑定运用
2016/03/04 Javascript
js停止冒泡和阻止浏览器默认行为的简单方法
2016/05/15 Javascript
JavaScript中的事件委托及好处
2016/07/12 Javascript
jquery+CSS3实现3D拖拽相册效果
2016/07/18 Javascript
bootstrap下拉列表与输入框组结合的样式调整
2016/10/08 Javascript
原生js实现中奖信息无间隙滚动效果
2017/01/18 Javascript
老生常谈JavaScript面向对象基础与this指向问题
2017/10/16 Javascript
微信小程序icon组件使用详解
2018/01/31 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
微信小程序wx.navigateTo方法里的events参数使用详情及场景
2020/01/07 Javascript
ES6箭头函数和扩展实例分析
2020/05/23 Javascript
判断网页编码的方法python版
2016/08/12 Python
python dict 字典 以及 赋值 引用的一些实例(详解)
2017/01/20 Python
机器学习python实战之决策树
2017/11/01 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
2017/11/06 Python
python实现在多维数组中挑选符合条件的全部元素
2019/11/26 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
python根据字典的键来删除元素的方法
2020/08/16 Python
PacSun官网:加州生活方式服装、鞋子和配饰
2018/03/10 全球购物
DNA测试:Orig3n
2019/03/01 全球购物
经典大学生求职信范文
2014/01/06 职场文书
星级党支部申报材料
2014/05/31 职场文书
五五普法心得体会
2014/09/04 职场文书
企业党建工作总结2015
2015/05/26 职场文书
幼儿园安全管理制度
2015/08/05 职场文书
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
python图像处理基本操作总结(PIL库、Matplotlib及Numpy)
2021/06/08 Python