vue2的keep-alive的总结
vue2的keep-alive的总结
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组件请求数据(包括点击链接和浏览器后退按钮).
vue2的keep-alive的总结的更多相关文章
- vue2.0实践的一些细节
最近用vue2.0做了个活动.做完了回头发现,好像并没有太多的技术难点,而自己好像又做了比较久...只能说效率有待提升啊...简单总结了一些比较细节的点. 1.对于一些已知肯定会有数据的模块,先用一个 ...
- 用FSM一键制作逐帧动画雪碧图 Vue2 + webpack
因为工作需要要将五六十张逐帧图拼成雪碧图,网上想找到一件制作工具半天没有找到,就自己用canvas写了一个. 写成之后就再没有什么机会使用了,因此希望有人使用的时候如果遇到bug了能及时反馈给我. 最 ...
- vue2.0构建淘票票webapp
项目描述 之前一直用vue1.x写项目,最近为了过渡到vue2.0,特易用vue2.0栈仿写了淘票票页面,而且加入了express作为后台服务. 前端技术栈:vue2.0 + vue-router + ...
- Vuex2.0+Vue2.0构建备忘录应用实践
一.介绍Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,适合于构建中大型单页应用. ...
- 一步步构造自己的vue2.0+webpack环境
前面vue2.0和webpack都已经有接触了些(vue.js入门,webpack入门之简单例子跑起来),现在开始学习如何构造自己的vue2.0+webpack环境. 1.首先新建一个目录vue-wk ...
- Vue2.0组件间数据传递
Vue1.0组件间传递 使用$on()监听事件: 使用$emit()在它上面触发事件: 使用$dispatch()派发事件,事件沿着父链冒泡: 使用$broadcast()广播事件,事件向下传导给所有 ...
- 基于Vue2.0+Vue-router构建一个简单的单页应用
爱编程爱分享,原创文章,转载请注明出处,谢谢!http://www.cnblogs.com/fozero/p/6185492.html 一.介绍 vue.js 是 目前 最火的前端框架,vue.js ...
- vue2.0实战
学了几周的vue2.0,终于有时间去做一个应用了. 为了全面联系相关知识,所以用到了vue-router,以及作者最新推荐的axios,组件库用的是饿了么的mint-ui2.0. 项目构建使用官方vu ...
- vue DatePicker vue2.0的日期插件
一个用vue2.0写的日期控件,可以支持简单的年月日选择.地址:https://github.com/Stevenzwzhai/vue-datepicker. 首先是关于日期对象的使用,基本就是日期的 ...
- vue2/vuex2的那点坑
说是坑,其实大部分是我们自己的过错! vuex官方demo在1.0可以运行,在2.0报错?此类问题,应该很常见吧? 还有顺溜的利用1.0搭建的webpack编译环境到了vue2.0突然失效了,报错了? ...
随机推荐
- no device found for connection ‘ System eth0′问题
我用的是centos6 在ping 百度的时候ping不通 提示错误no device found for connection ' System eth0′ 解决方法:虚拟机右上角有一个小电脑的标志 ...
- js 函数声明和函数表达式
在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,因为ECMA规范只明确了一点:函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省 ...
- 获取标签的src属性兼容性
获取节点如script标签的src属性时,针对非IE6,IE7可以直接使用src属性,但在IE6-7中存在问题,可以借助getAttribute方法 getAttribute(attr,iflag) ...
- 原生promise
你应该会用事件加回调的办法来处理这类情况: var img1 = document.querySelector('.img-1'); img1.addEventListener('load', f ...
- [java基础] java 左移和右移
今天搜到一个比较好用的在线编译器,希望和大家分享. 除了java还有c++....,地址是http://www.tutorialspoint.com/compile_java_online.php 另 ...
- Nginx实现负载均衡&Nginx缓存功能
一.Nginx是什么 Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambl ...
- 6. ZooKeeper访问控制列表
ZooKeeper的数据模型提供了ACL机制来控制访问znode. 在创建znode时,ACL将确定你可以在znode上执行的各种操作的权限. ZooKeeper ACL模型与Unix / Linux ...
- ASP.Net Controls 用法大全
The FindControl method of the System.Web.UI.Control class appears simple enough to use. In fact, the ...
- 修改 Sublime 按快捷键 ctrl+s 自动格式化(reindent lines)的问题
Sublime 工具自带代码格式化的功能,但在某些场景下格式化代码后并不是我们想要的代码格式,且是点击保存ctrl+s才触发的格式代码事件,so,为关闭点击ctrl+s格式代码,我们需要改命令 sav ...
- [转]Oracle High Water Level高水位分析
PLSQL_性能优化系列14_Oracle High Water Level高水位分析 http://www.cnblogs.com/eastsea/p/4005814.html 一.摘要 PLSQL ...