最近在开发中遇到了这样的一个问题:

A、B、C三个页面,有如下这样的场景:

(1)从页面A离开进入B或C的时候,缓存A页面的数据,并且返回到A后,能保持A页面的跳转前职位

(2)离开B进入C的时候,缓存B

(3)离开B进入A的时候,不缓存

现在开始分步解决:

方案一:

从场景中可是看出A、B是需要缓存的,

首先修改app.vue

<template>
<div id="app">
<keep-alive :include="['Index', 'List']">
<router-view/>
</keep-alive>
</div>
</template>

include是A、B页面中的name值,注意,include接受的是数组字符串

然后就是A页面进入B页面的时候刷新,即离开B进入A的时候不缓存,那么就需要用到beforeRouteEnter(),此函数在mounted()执行后执行,不是methods中的自定义函数

export default {
name: "List",
beforeRouteEnter(to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
if (from.fullPath == '/' && to.fullPath.indexOf('/list') > -1) { //一定是从A进到B页面才刷新
vm.initFn(); //initFn是本来写在mounted里面的各种, 执行顺序是:先执行mounted,然后是此处
}
})
},
  methods: {
    initFn() {
      ... //获取数据
    }
  }
}

返回到原来的位置用到的是router中的scrollBehavior():

router.js:

new Router({
routes: [],
scrollBehavior(to, from, savedPosition) {
  // keep-alive 返回缓存页面后记录浏览位置
  if (savedPosition && to.meta.isKeepAlive) {
  return savedPosition;
  }
  // 异步滚动操作
  return new Promise((resolve) => {
  setTimeout(() => {
  resolve({ x: 0, y: 1 });
  }, 0);
  });
}
})
有时候会有返回不回去的情况,可做延时处理:
new Router({
routes: [],
scrollBehavior(to, from, savedPosition) {
  // keep-alive 返回缓存页面后记录浏览位置
  if (savedPosition && to.meta.isKeepAlive) {
  setTimeout(() => { //延时
   window.scrollTo(savedPosition.x, savedPosition.y)
  }, 10);
  }
  // 异步滚动操作
  return new Promise((resolve) => {
  setTimeout(() => {
  resolve({ x: 0, y: 1 });
  }, 0);
  });
}
})

除了使用keep-alive的include属性,可通过给router中添加mate参数控制

app.vue:

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

注意此处if判断中的meta后的值要与router中的一致

router.js

const router = new Router({
routes: [
{
path: '/',
name: 'Index',
component: Index,
meta: {
isKeepAlive: true
}
},
{
path: '/list/:id',
name: 'List',
component: List,
meta: {
isKeepAlive: true
}
}
],
scrollBehavior(to, from, savedPosition) {
// keep-alive 返回缓存页面后记录浏览位置
if (savedPosition && to.meta.isKeepAlive) {
return savedPosition;
}
// 异步滚动操作
return new Promise((resolve) => {
setTimeout(() => {
resolve({ x: 0, y: 1 });
}, 0);
});
}
});
export default router;

当然还有其他的解决方法,如destory()。

方案二:

利用$destroy()销毁:

beforeRouteLeave (to: any, from: any, next: any) {
// 导航离开该组件的对应路由时调用
// 判断是否是去往页面 C
if (to.name !== 'C') {
// 不是去 C 页面,不缓存
this.$destroy()
}
next()
}

但bug是销毁后将永远不会再次缓存。

网上还有给出其他方案,查看源码可以发现缓存是通过添加cache属性存储vnode的,如通过源码的cache属性,强制移除某个对象,缺点是没有彻底销毁依旧占内存,不过我没有实验,具体的就不知道了。

还有就是动态设置router.js中的keepAlive值,通过beforeRouteLeave(to, from, next)中的to,from判断url,动态设置keepAlive是true还是false,但设置为true缓存后,即使再设置为false也不会清除缓存,那么会出现bug,列表页不同id的进入,始终是第一次进入时的数据。

经过多次测试,发现方案一的两种写法均是可行且没出现bug的,记录下,方便以后复习

vue 后退不刷新,前进刷新 keep-alive的更多相关文章

  1. vue 后退不刷新页面

    使用 this.$router.push({path: '/aichat'})路由跳转方式跳转页面 要实现 home => chat  chat页面刷新: chat => report, ...

  2. [one day one question] Vue数组变更不能触发刷新

    问题描述:Vue数组变更不能触发刷新,特别是数组的每个元素都是对象的时候,对象中某个属性的值发生变化,根本无法触发Vue的dom刷新,这怎么破? 解决方案:this.$set(array, index ...

  3. vue 缓存的keepalive页面刷新数据

    用到这个的业务场景是这样的: a页面点击新建列表按钮进入到新建的页面b,填写b页面并点击b页面确认添加按钮,把这些数据带到a页面,填充到列表(数组),可以添加多条, 点击这条的时候进入到编辑页面,确认 ...

  4. vue 首次加载缓慢/刷新后加载缓慢 原因及解决方案

    # vue 首次加载缓慢/刷新后加载缓慢 原因及解决方案 最近做项目发现一个问题,页面每次刷新后加载速度都非常慢,20s左右,在开发环境则非常流畅,几乎感觉不到,本文参考望山的各种方案优化 1,关闭打 ...

  5. vue mint-ui 框架下拉刷新上拉加载组件的使用

    安装 npm i mint-ui -S 然后在main.js中引入 import MintUI from 'mint-ui' import 'mint-ui/lib/style.css' Vue.us ...

  6. Vue build打包之后,刷新页面出现404解决方案

    Vue build打包之后,刷新页面出现404,HTML5 History 模式 原因分析: vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于 ...

  7. VUE 路由参数改变重新刷新数据

    VUE 路由参数改变重新刷新数据 App.vue 里面使用路由,然后通过App.vue文件中的搜索功能搜索刷新路由文件中的列表. 修改 index.js 文件 首先在路由文件 index.js 文件中 ...

  8. vue 在nginx下页面刷新出现404问题解决和在nginx下页面加载了js但是页面显示空白问题解决

    一.vue 在nginx下页面刷新出现404 在网上翻遍了所有这样问题的解决办法,全都是一个解决办法也是正确的解决办法,(后来在vue官网上关于history方式出现404解决方法也是这样说的),只是 ...

  9. Mui 下拉刷新,刷新完成功能实现

    Mui中,正在刷新后,就直接回弹了,没有刷新完成这个过程,然后我就在中间添加了一个过程.   代码如下:   //-----------日期格式化------------- function form ...

  10. UICollctionView 刷新 item 刷新 消失

    在需要局部刷新的时候,可能出现的问题: 当时采用的局部刷新,第一次刷新没问题,当多次刷新的时候 item 就会消失 NSIndexSet *]; [collectionView reloadSecti ...

随机推荐

  1. PTA(Advanced Level)1048.Find Coins

    Eva loves to collect coins from all over the universe, including some other planets like Mars. One d ...

  2. Vue.directive()的用法和实例

    官网实例: https://cn.vuejs.org/v2/api/#Vue-directive https://cn.vuejs.org/v2/guide/custom-directive.html ...

  3. Python基础学习路径

    1. Python数据结构 1. 基本数据类型(整数.小数.字符) 1.基本数据类型有5种:int bool float complex long 2.每一种数据类型该如何定义 3.数据类型之间可以强 ...

  4. php常用扩展有哪些

    bcmath(精确数值处理) bz2 calendar Core ctype curl date dom ereg exif fileinfo filter ftp gettext hash icon ...

  5. [python]近日 用3种库 实现简单的窗口 的回顾~

    最近任务:利用python 实现以下4个窗口弹窗. 信息提示框 文本输入框(需在窗口消失后,返回 用户输入的值) 文件选择(需在窗口消失后, 返回 用户选择的文件名的全路径) 文件夹选择(需在窗口消失 ...

  6. 12.如何设置ulimit

    ulimit -a用来显示当前的各种用户进程限制 修改所有 linux 用户的环境变量文件:vi /etc/profileulimit -u 10000              #用户的最大进程数u ...

  7. echarts 根据经纬度坐标在地图上描点

    var mapData = [ {'latitude':30.67, 'longitude':104.07}, {'latitude':34.76, 'longitude':113.65}, {'la ...

  8. 怎样在Chrome浏览器上安装 Vue Devtools 扩展程序

    第一步: 前往 GitHub 下载 Vue Devtools 项目文件 https://github.com/vuejs/vue-devtools 注意: 1. 将分支切换为 master 2. 下载 ...

  9. JAVA学习篇--静态代理VS动态代理

    本篇博客的由来,之前我们学习大话设计,就了解了代理模式,但为什么还要说呢? 原因: 1,通过DRP这个项目,了解到了动态代理,认识到我们之前一直使用的都是静态代理,那么动态代理又有什么好处呢?它们二者 ...

  10. promise, async和await

    最开始实现异步的方法:回调函数 method1(function(err, result) { if (err) { throw err; } method2(function(err, result ...