VIP用户交流群:462197261 收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
在线客服:78895949
tonglan
  • 当前位置:
  • vue中keep-alive组件的入门使用教程

    一、问题触发并解决

    最近自己在写vue练习,内容相对简单,主要是对vue进行熟悉和相关问题发现,查漏补缺。简单说下练习的项目内容及问题的产生:

    练习使用的vue-cli 2.0脚手架搭建,内容就是简单的仿音乐播放app,功能也相对简单,大体就是单页router切换各个专辑列表,点击进入专辑内容页面,单击歌曲名称可以进行播放、暂停、下一曲功能。

    简单的背景介绍完了,说下问题产生的情形:在从整个歌曲列表页点击跳转到单个专辑列表页,然后点击返回按钮返回歌曲列表页时,页面保存了之前的浏览位置,但是接口重新请求了数据,因为歌曲列表页有滚动加载效果,所以数据获取在vuex里用了数组的concat方法,导致返回请求的数据重新加载了列表里,而v-for循环由于key值有了重复,导致控制台报错;说起来可能比较难懂,上一些基本的代码部分:

    vuex里获取列表数据:
    GET_COLLECTION_LIST(state, val) { state.collectionList = state.collectionList.concat(val)}
    
    歌曲列表里created获取数据,mounted监听滚动事件滚动加载,destroyed取消监听:
    created(){ this.collectionListMethod({limit: this.limit, offset: this.offset})},
    mounted(){ window.addEventListener('scroll', this.isScrollBot)}
    destroyed(){ window.removeEventListener('scroll', this.isScrollBot)}
    
    专辑列表页返回使用的是 this.$router.go(-1)

    有问题就要解决问题,通过查询了解到keep-alive可以对数据进行缓存,路由切换的时候可以使用缓存不用重新触发接口请求,貌似可以很完美解决问题,实践出真知,在代码里添加:

    首先在歌曲列表路由里添加meta:{keepAlive: true}为后面的router-view是否需要缓存提供标识
    { path: '/songLis', component: SongLis, meta: { keepAlive: true }}
    然后在router-view外层添加keep-alive,并根据meta参数判断是否所有路由都需要缓存
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive" />
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"/>

    添加完毕,回到页面看效果!可喜可贺的是控制台不报错了,说明keep-alive起作用了,撒花庆祝~~~ 但是事情并没有那么简单,当我们从专辑列表切到其他路由,滚动鼠标会发现滚动加载的监听事件没有取消,组件destroyed的时候明明取消监听了啊!而且再切回到专辑列表页的时候,滚动加载反而不执行了,表示一脸懵~

    经过查看vue文档,发现文档有这么一句话:

    <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

    也就是说使用keep-alive的组件不会触发destroyed钩子方法,这就是取消监听失败的原因。根据文档介绍,keep-alive切换时,会触发自己的activeted和deactiveted两个钩子函数,可以理解为vue的created和destroyed两个钩子,因此需要修改代码,在deactivated时候取消监听,同时在activated的时候恢复监听,否则切回去的时候滚动监听也不会有效果:

    //keep-alive钩子函数,组件恢复时触发
    activated(){ window.addEventListener('scroll', this.isScrollBot)},
    //keep-alive钩子函数,组件变为不可用时触发
    deactivated(){ window.removeEventListener('scroll', this.isScrollBot)}

    修改后的效果完全符合预期,切换路由页面保留当位置,不会重复请求接口而且也不会在专辑列表组件外部触发滚动加载。

    二、关于keep-alive

    既然用到了keep-alive,就通过文档简单总结下相关使用:

    上面已经说过,通过keep-alive包裹的组件,在不活动时会缓存组件实例,不会对组件进行销毁,再次处于活动状态时,会读取缓存的内容并保存组件状态,不用重复请求接口获取数据。

    (1)最基本使用基本用法:

    基本用法:
    <keep-alive>
     <component :is="view"></component>
    </keep-alive>
    
    也可以根据条件判断:
    <keep-alive>
     <comp-a v-if="a > 1"></comp-a>
     <comp-b v-else></comp-b>
    </keep-alive>
    这个时候触发两个组件切换时,组件内的数据和状态都会得到保存,如果有input输入框,输入框内容会保留

    (2)有条件的缓存

    keep-alive提供了include、exclude、max三个参数,前两个允许组件有条件的进行缓存,两者都可以接受字符串、正则、数组形式;max表示最多可以缓存多少个组件,接受一个number类型。

    <keep-alive include="a,b">
     <component :is="view"></component>
    </keep-alive>
    此时只有a、b两个组件会触发keep-alive,此处的名字是组件内部name对应名字,如果name不存在,会查找父组件里components里注册的名字,如果也不存在则不会匹配。
    正则和数组方法同上,但是需要用v-bind:include=''方式。
    
    <keep-alive :max="10">
     <component :is="view"></component>
    </keep-alive>

    (3)钩子函数

    两个钩子函数activated和deactivated,上面已经说过,分别在组件恢复活动状态和组件失去活动状态时触发,可以起到类似created和destroyed钩子作用。

    以上是对keep-alive的个人使用和理解,如有不足还望指正~

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对北冥有鱼的支持。

    您可能感兴趣的文章:

    • vue的keep-alive中使用EventBus的方法
    • 详解keep-alive + vuex 让缓存的页面灵活起来
    • vue使用keep-alive保持滚动条位置的实现方法
    • vue里如何主动销毁keep-alive缓存的组件
    • vue的keep-alive用法技巧

    广而告之:
    热门推荐:
    织梦DEDECMS系统首页sql调用disucuz2.5内容怎么解决?

    注明:如果你安装在不同的数据库,需要在sql中指定数据库,我这边是jtb,与公司的织梦dedecms不是安装在同库中。  调用图文帖子的方法:  {dede:sql sql="SELECT jtb.pre_forum_threadimage.tid, jtb.pre_forum_threadimage.attachment, jtb.pre_fo···

    CMS中PHP判断系统是否已经安装的方法示例

    当今很多常用的CMS系统都带有安装程序,为了用户的使用方便,新下载的系统在使用前,都会判断该CMS系统是否已经安装过,若安装了则就给出提示,不需要重复安装,若未安装则进入安装界面,指导用户按步骤顺利安装CMS,那么基于PHP环境的CMS到底是如何用代码来实现这种判断机制呢···

    PHP实现简单汉字验证码

    现在越来越多的网站都开始使用汉字验证码了,既增加了我们国人的亲切感,同时也增加了机器破解的难度,这里我就简单粗暴的说一下。。。 创建背景画布 $image = imagecreatetruecolor(200, 60); $background = imagecolorallocate($image, 255, 255, 255); imagefill($image, 0···

    textarea布局时文字在左下边且不能改变大小尺寸的解决方法

    两个小问题,但是困扰了很久 第一个问题 textarea文本域左边的文字一直都是在textarea的左下边,看起来不美观 设置一个属性就可以搞定 复制代码代码如下: <label style="vertical-align:top" >备注信息:</label><textarea rows="5" cols="65"><···

    php session劫持和防范的方法

    session 数据暴露会话数据常会包含一些个人信息和其它敏感数据。基于这个原因,会话数据的暴露是被普遍关心的问题。一般来说,暴露的范围不会很大,因为会话数据是保存在服务器环境中的,而不是在数据库或文件系统中。因此,会话数据自然不会公开暴露。使用SSL是一种特别···

    详解html5 postMessage解决跨域通信的问题

    本文介绍了详解html5 postMessage解决跨域通信的问题,分享给大家,具体如下: 效果图 postmessage解析HTML5提供了新型机制PostMessage实现安全的跨源通信. 语法 otherWindow.postMessage(message, targetOrigin, [transfer]); otherWindow: 其他窗口的一个引用, 比如IFRAME的···

    一张图片能隐含千言万语之隐藏你的程序代码

    我最近开发了我的第一个网页游戏:一个HTML5的视频智力游戏。开发的过程很有趣,我喜欢编程,但当实现了游戏逻辑后,我有了一个有趣的想法:为什么不想个办法把代码隐藏起来?起初我想到的是一些很简单的做法,比如禁止上下文菜单,以防右键点击时可以查看页面源代码。但这毫无···

    解决Dede5.6联动类型更改排序数字的BUG

    DedeCMS5.6 联动类型在更改排序数字后的BUG解决办法。 版本 DEDECMS 5.6 BUG触发环境与条件: 当联动类型的最后一条记录被修改排序为非500倍数时并且不是最大排序中的最大数值时。 BUG就发生了。 例如下图环境中。 添加分类不管你怎么加。 都自动跑到分类下的子分类···

    Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法

    1. 引入jquery和vue.js <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script> 2. JS <script ···

    帝国cms用灵动标签调用单个目录下子目录的方法

    [e:loop={"select classname,classpath from neiyiqiye_enewsclass where bclassid=3 order by classid ",0,24,0}] <LI><a href="/<?=$bqr[classpath]?>"><?=$bqr[classname]?></a></LI> [/e:loop]