Vue中路由缓存及activated与deactivated的详解

目录

  • 前言
  • 一,路由缓存
    • [1.1 引子](#1.1 引子)
    • [1.2 路由缓存的方法](#1.2 路由缓存的方法)
      • [1.2.1 keep-alive](#1.2.1 keep-alive)
      • [1.2.2 keep-alive标签中的include属性](#1.2.2 keep-alive标签中的include属性)
    • [1.2.3 include中多组件的配置](#1.2.3 include中多组件的配置)
  • 二,activated与deactivated
    • [2.1 引子](#2.1 引子)
    • [2.2 介绍activated与deactivated](#2.2 介绍activated与deactivated)
    • [2.3 解决需求](#2.3 解决需求)
  • 三,整体代码
  • 总结

前言

在Vue的使用中,为了提高应用的效率,我们可以使用路由缓存这方面的相关知识来解决遇到的问题。

本博客的内容则是对路由缓存及activated与deactivated的详解。期望能对读者有所帮助。

本篇博客需要有对路由相关知识的了解,如需复习可见博客Vue2路由的详细讲解

一,路由缓存

本节内容讲解路由缓存相关知识,如果了解什么是路由缓存可以跳过引子部分。

1.1 引子

先看一下我的组件结构:

News和Messages是两个路由组件,可以在App中切换使用。

News组件:(News组件中有三个输入框,仅用作输入)

Messages组件:

了解了上述结构后,现在抛出疑问:如果我再News的输入框中输入一些数据,在我点击Messages后,输入框中的数据还在不在?

现在我们来实践一下:

输入数据:

点击messages:

如何判断输入框的数据还存不存在:如果点击News切换到News组件,输入框的内容还在,则代表数据还在,否在就是,随着路由组件的切换,组件中的内容也随之消失。

当我点击News后,数据消失了:

可以证明,如果不作过多处理,路由组件中的数据会随着路由的切换而消失。在实际的项目应用中如果我写了很多的数据,不小心切换了组件,数据消失了,这样做很影响效率。

因此,这里提出解决对策:路由缓存。

1.2 路由缓存的方法

1.2.1 keep-alive

路由缓存,需要借助一个标签:

Html 复制代码
<keep-alive></keep-alive>

这个标签中,放置相关的router-view结构:

Html 复制代码
    <keep-alive>
        <router-view></router-view>
    </keep-alive>

放置后,整个router-view中的数据都会缓存,数据不会随着组件的切换而消失。

那么再次切换路由,刚刚的引子案例中,输入框的内容不会消失。

1.2.2 keep-alive标签中的include属性

刚刚的做法,已经可以实现数据的缓存了,而且实现的是该组件中所有路由组件中数据的缓存。

但是,如果现在有十个路由组件需要切换,我只需要用到一个路由组件中的数据,可是用上述的方法存下的数据却远远多过我们需要的。这样会影响浏览器的工作效率。

所以,我们现在要做的是,只缓存个别路由组件中的数据。

方法是,在keep-alive标签中,配置include属性,include属性的内容是需要缓存数据的路由组件的组件名。

这里要注意的是,组件名是我们自己配置的name,而不是组件本身的名称。

了解做法,我们来实践,单独缓存News组件中的数据:

这里需要注意,News组件中是提前配置好了name的。News组件的组件文件名是News.vue,但是组件名是提前配置好的Name:New,如下图:

我们现在在App中的keep-alive中配置include:

做到这一步,News中的数据得到了缓存,并且只有News组件中的数据被缓存了。

1.2.3 include中多组件的配置

如果要缓存的不止一个组件中的数据,二十多个,该如何在include中配置?

其实很简单,给include一个v-bind绑定。一旦使用v-bind,则include中的数据是js语句,在include中可以配置数组类型的数据,把要缓存的组件的组件名称都写进数组即可:

二,activated与deactivated

2.1 引子

刚刚我们已经了解了路由缓存的相关知识。

现在我们有了新的需求:在上面已经写好的基础上(缓存了New和Message两个组件中的数据),利用好消息界面,写一个定时器,每隔五毫秒打印"消息来了"。当切换到别的组件时,打印停止。

现在我们先来试一下,看一下不做什么处理可不可以直接实现。

首先,这是我message的写法:

当我们打开项目时,下方还没有打印相关内容。因为,Message组件还没能被渲染:

接着,我点击Messages按钮切换出Messages组件,下方不断打印出"消息来了":

然后我切换到News组件发现下面会一直打印:

出现此现象的本质原因:Message整个组件被缓存了。

那么,我们希望的是什么呢?我们希望点击News按钮后,Message组件的定时器能够被销毁。但是数据依旧被缓存。

这里为了说明问题我在message组件中加一个类似于News中的input框。我们的需求可以通过,定时器随着切换其他组建后被销毁的同时,Message中的数据依旧存在来体现。

2.2 介绍activated与deactivated

这里要介绍两个钩子函数(生命周期函数):activated与deactivated。

这两个是专门用于路由组件的函数。

先介绍一下:

activated,可译为"激活的",路由组件从未出现到出现时运行。

deactivated:可译为"失活的",路由组件被切换走时运行。

我们可以来测试一下是不是如此,代码:

点击Messages按钮:

把Messages切换走:

回到需求,通过这两个生命周期函数,我们可以通过两个组件的生命周期函数实现:在messages组件出现时激活定时器,在messages组件被切走时销毁定时器。

2.3 解决需求

利用钩子函数,在路由组件activated(激活)时候,设置定时器,在路由组件deactivated(被切换走)的时候销毁定时器:

利用此方法,缓存不会受影响。

现在整体代码写完,我们来看一下效果:

messages未出现:

点击messages按钮后,message在激活时定时器被创建,开始打印"消息来啦!"。且此时在输入框中缓存数据。

在点击News按钮,Messages被切换走,定时器被销毁,控制台不再打印内容,但数据依旧缓存:

实现需求。

三,整体代码

读者可以使用关键代码,然后进行实践。

router中index.js的配置:

javascript 复制代码
import VueRouter from 'vue-router'

//引入一级路由
import News from '../pages/News'
import Messages from '../pages/Messages'

export default new VueRouter({
    routes: [
        {
            path: '/news',
            component: News
        },
        {
            path: '/messages',
            component: Messages
        }
    ]
})

App组件:

javascript 复制代码
<template>
  <div>
    <router-link to="/news"><button>News</button></router-link>
    <router-link to="/messages"><button>Messages</button></router-link>

    <keep-alive :include="['New', 'Message']">
        <router-view></router-view>
    </keep-alive>
  </div>
</template>

<script>
export default {
    name: 'App'
}
</script>

<style scoped>

</style>

News组件:

javascript 复制代码
<template>
  <div>
    <h1>News</h1>
    <ul><li v-for="n in news" :key="n.id">{{ n.title }} <input type="text"></li></ul>
  </div>
</template>

<script>
export default {
  name: 'New',
  data() {
    return {
      news: [
        {id: 1, title: '消息1'},
        {id: 2, title: '消息2'},
        {id: 3, title: '消息3'}
      ]
    }
  }
}
</script>

<style scoped>

</style>

Messages组件:

javascript 复制代码
<template>
  <div>
    <h1>Messages</h1>
    <input type="text">
  </div>
</template>

<script>

export default {
  name: 'Message',
  activated() {
    this.timer = setInterval(() => {
      console.log('消息来啦!')
    }, 500)
  },
  deactivated() {
    clearInterval(this.timer)
  }

}
</script>

<style scoped>

</style>

总结

本节内容讲解了路由的缓存及路由组件的两个生命周期的应用。

以下我总结几个需要注意的地方:

1.在路由的缓存时,如需使用include配置项,include内部应当是需要缓存的组件的组件名称;

2.新介绍的两个生命周期函数是针对路由组件的,普通组件无法使用。

以上内容就是对Vue中路由的缓存及两个路由组件生命周期的讲解。后续有机会会出一期关于我对生命周期的理解的博客。

最后,感谢大家的阅读,欢迎关注!

相关推荐
Daniel 大东14 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
还是大剑师兰特34 分钟前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解34 分钟前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~40 分钟前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
起飞的风筝43 分钟前
【redis】—— 环境搭建教程
数据库·redis·缓存
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
man20171 小时前
【2024最新】基于springboot+vue的闲一品交易平台lw+ppt
vue.js·spring boot·后端
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web