详解keep-alive + vuex 让缓存的页面灵活起来


Posted in Javascript onApril 19, 2019

引入

在使用vue + vue-router开发SPA的时候,有没有遇到过这样的情况:当我们在列表页和详情页之间切换的时候,如果列表页不做缓存,会导致每次从详情页返回时,列表页都会重新加载。如下图:

详解keep-alive + vuex 让缓存的页面灵活起来

细心的朋友已经发现了,当从详情页返回列表页的时候,列表页重载了,这样的体验显然不好,这时我们可以对列表页进行缓存处理。

keep-alive实现页面缓存

我们的项目不一定所有页面都需要做缓存处理,所以这里介绍两种按需缓存的方法:

方法一:

首先在定义路由的时候配置 meta 字段,自定义一个KeepAlive字段作为该页面是否缓存的标记:

routes:[{
 path: '/search',
 name: 'search',
 component: search,
 meta: {
  title: '搜索列表页',
  keepAlive: true // 标记列表页需要被缓存
 }
},
{
 path: '/detail',
 name: 'detail',
 component: detail,
 meta: {
  title: '详情页',
  // 详情页不需要做缓存,所以不加keepAlive标记
 }
}]

由于<keep-alive>组件不支持v-if指令,所以我们在App.vue中采用两个<router-view>的写法,通过当前路由的keepAlive字段来判断是否对页面进行缓存:

<div id="app">
 <keep-alive>
  <router-view v-if="$route.meta.keepAlive" />
 </keep-alive>
 <router-view v-if="!$route.meta.keepAlive" />
</div>

方法二

使用<keep-alive>提供的 exclude 或者 include 选项,此处我们使用 exclude ,在App.vue中:

<div id="app">
 <keep-alive exclude="detail">
  <router-view />
 </keep-alive>
</div>

需要注意的是,一定要给页面组件加上相应的name,例如在detail.vue中:

<script>
export default {
 name: 'detail', // 这个name要和keep-alive中的exclude选项值一致
 ...
}
</script>

这么写就代表了在项目中除了name为detail的页面组件外,其余页面都将进行缓存。

特殊情况优化:

如果详情页也做了keep-alive,那么列表页和详情页切换时,滚动位置可能会相互影响,这时需要在 Router 实例中提供一个 scrollBehavior 方法:

export default new Router({
 scrollBehavior (to, from, savedPosition) {
 	if (savedPosition) {
 		return savedPosition
 	} else {
 		return { x: 0, y: 0 }
 	}
 },
 routes: [...],
})

效果展示

详解keep-alive + vuex 让缓存的页面灵活起来

效果看似很不错,实现了列表页的缓存。但这其实并不灵活,比如返回首页再进入这个搜索页的时候,由于没做任何处理,所以这个搜索页它仍处于之前的状态:

详解keep-alive + vuex 让缓存的页面灵活起来

然而,我希望凡是从首页进入搜索页,页面数据都需要重置回初始状态,有没有什么方可以灵活控制页面数据是否需要重置呢?这时我的脑海里浮现了vue生态系统中的状态管理库vuex。

借助vuex使页面更灵活

需求分析: 我们需要一个全局的flag来控制每次进入缓存页时,数据是否需要重置,正好vuex能做到。

vuex搞起来

安装

npm install vuex --save

 配置vuex

为了方便日后维护,可以创建一个store目录专门存放vuex的模块代码,目录结构参考下图:

详解keep-alive + vuex 让缓存的页面灵活起来

state.js:

const state = {
 refreshSearch: true // 标记是否刷新搜索页
}

export default state

mutation.js

const matutaions = {
 setRefreshSearch(state, flag) {
  state.refreshSearch = flag
 }
}
 
export default matutaions

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'

Vue.use(Vuex)

export default new Vuex.Store({
 state,
 mutations
})

在入口文件main.js中:

import store from './store' //这里是指向store目录中的index.js
new Vue({
 router,
 store,
 render: h => h(App)
}).$mount('#app')

这样,我们就相当于用vuex创建了一个用来判断页面是否需要重置的标记了。

为所欲为地重置你的缓存页中的数据

在哪里重置

keep-alive的组件有个特有的生命周期钩子activated()。activated()会在keep-alive的组件每次激活时调用,而created()只有创建的时候会被调用一次,再次激活就不会被调用了。所以这里我们需要在activated()钩子中重置我们的页面数据。

 在activated()中想重置就重置

这里要借助vuex中的refreshSearch标记来判断是否需要重置

search.vue:(这个是需要缓存的页面)

<script>
import {mapState, mapMutations} from 'vuex' //vuex提供的映射函数,用来简化代码的
export default {
  activated() {
    if (this.refreshSearch) {
      // 若为true,则执行重置页面等相关操作
      this.fetchData();
    } else {
      this.reset(true);
    }
  },
  methods:{
    fetchData() {
      // 获取页面数据
    },
    ...mapMutations({
      reset: 'setRefreshSearch' // 将 `this.reset()` 映射为 `this.$store.commit('setRefreshSearch')`
    })
  },
  computed: {
    ...mapState([
      'refreshSearch' // 映射 this.refreshSearch 为 this.$store.state.refreshSearch
    ]),
  }
}
</script>

当我们从搜索页去详情页时,希望搜索页缓存,只需要把标记设为false:

methods: {
  goDetail() {
    this.reset(false) // 这样返回搜索页的时候,搜索页就不会重置数据了
    this.$router.push({path: '/detail'})
  },
  ...mapMutations({
    reset: 'setRefreshSearch'
  })
}

当我们从首页去搜索页时,希望搜索页数据重置,只需把标记设为true:

methods: {
  goSearch() {
    this.reset(true) // 这样去搜索页时数据就会被重置了
    this.$router.push({path: '/search'})
  },
  ...mapMutations({
    reset: 'setRefreshSearch'
  })
}

效果预览

详解keep-alive + vuex 让缓存的页面灵活起来

总结

本文介绍了按需使用keep-alive,以及借助vuex来控制keep-alive的组件页面的数据是否需要重置刷新,希望对大家有帮助。

附送相关知识传送门:

vue内置组件keep-alive

vue-router滚动行为

生命周期钩子activated

vuex状态管理库

以上所述是小编给大家介绍的keep-alive + vuex 让缓存的页面灵活起来详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
animate动画示例(泪奔的小孩)及stop和delay的使用
May 06 Javascript
js获取当月最后一天实例代码
Nov 19 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
Jul 04 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
Sep 03 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
浅析函数声明和函数表达式——函数声明的声明提前
May 03 Javascript
JavaScript的字符串方法汇总
Jul 31 Javascript
Vue.js常用指令之循环使用v-for指令教程
Jun 27 Javascript
浅谈Vue.js 1.x 和 2.x 实例的生命周期
Jul 25 Javascript
微信小程序 swiper组件构建轮播图的实例
Sep 20 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 Javascript
JavaScript实现简单计时器
Jun 22 Javascript
一个Java程序猿眼中的前后端分离以及Vue.js入门(推荐)
Apr 19 #Javascript
基于javascript的拖拽类封装详解
Apr 19 #Javascript
Bootstarp在pycharm中的安装及简单的使用方法
Apr 19 #Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
Apr 19 #Javascript
详解vue-cli+es6引入es5写的js(两种方法)
Apr 19 #Javascript
vue中使用vue-cli接入融云实现即时通信
Apr 19 #Javascript
浅谈Javascript中的对象和继承
Apr 19 #Javascript
You might like
PHP安装攻略:常见问题解答(一)
2006/10/09 PHP
php的zip解压缩类pclzip使用示例
2014/03/14 PHP
基于JQuery+PHP编写砸金蛋中奖程序
2015/09/08 PHP
使用Composer安装Yii框架的方法
2016/03/15 PHP
php判断用户是否关注微信公众号
2016/07/22 PHP
php多文件打包下载的实例代码
2017/07/12 PHP
PHP封装XML和JSON格式数据接口操作示例
2019/03/06 PHP
js或css文件后面跟参数的原因说明
2010/01/09 Javascript
jQuery EasyUI 的EasyLoader功能介绍
2010/09/12 Javascript
JavaScript中实现依赖注入的思路分享
2015/01/15 Javascript
11种ASP连接数据库的方法
2015/09/18 Javascript
jquery.cookie.js实现用户登录保存密码功能的方法
2016/04/15 Javascript
快速掌握jQuery插件WebUploader文件上传
2016/11/07 Javascript
jQuery Tree Multiselect使用详解
2017/05/02 jQuery
详解webpack2+node+react+babel实现热加载(hmr)
2017/08/24 Javascript
vue-cli脚手架config目录下index.js配置文件的方法
2018/03/13 Javascript
环形加载进度条封装(Vue插件版和原生js版)
2019/12/04 Javascript
JavaScript设计模型Iterator实例解析
2020/01/22 Javascript
js实现贪吃蛇小游戏(加墙)
2020/07/31 Javascript
[01:03:47]VP vs NewBee Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
python实现机器学习之元线性回归
2018/09/06 Python
python绘制彩虹图
2019/12/16 Python
基于SQLAlchemy实现操作MySQL并执行原生sql语句
2020/06/10 Python
python用tkinter实现一个gui的翻译工具
2020/10/26 Python
css3实现顶部社会化分享按钮示例
2014/05/06 HTML / CSS
澳大利亚牛仔裤商店:Just Jeans
2016/10/13 全球购物
美国睫毛、眉毛精华液领导品牌:RevitaLash Cosmetics
2018/03/26 全球购物
垃圾回收的优点和原理
2014/05/16 面试题
单位领导证婚词
2014/01/14 职场文书
爷爷追悼会答谢词
2014/01/24 职场文书
简历自我评价模版
2014/01/31 职场文书
护理人员的自我评价分享
2014/03/15 职场文书
党员对照检查材料思想汇报
2014/09/16 职场文书
小学三年级语文教学反思
2016/03/03 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书