您的位置:首页 > 产品设计 > UI/UE

内置组件 && vue中强大的缓存机制之keep-alive

2017-05-25 17:45 1116 查看

vue中强大的缓存机制之keep-alive

  最近在用vue做项目,在切换页面时发现切换回原来的页面无法保存原来的状态。 如A页面需要ajax请求数据,然后切换到B页面做某些事情,再切换回A页面时,A页面又再请求数据,但是作为前端,性能优化时必须要考虑的,并且,vue构建的单页面应用,大多数情况下是不需要重新请求数据的,这时keep-alive就派上用场了。

  

第一部分:vue中内置的组件

  在vue中,为了方便开发者更好的使用vue,减少不必要的代码量,作者内置了一些组件,主要有:

component组件

transition组件

transition-group组件

keep-alive组件

slot组件 

(1). component组件

props

is 依照is的值,来决定使用哪个组件被渲染

inline-template 布尔值

var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})


   即在components下设置多个组件。

<component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! -->
</component>


    也可以直接绑定在对象上:

var Home = {
template: '<p>Welcome home!</p>'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})


    

(2) transition组件

props

name --- string,用于自动生成 CSS 过渡类名。例如:
name: 'fade'
将自动拓展为
.fade-enter
.fade-enter-active
等。默认类名为
"v"。


appear --- boolean, 是否在初始渲染时使用过渡。默认为false。

css --- boolean, 是否使用过渡类。默认为
true
。如果设置为
false
,将只通过组件事件触发注册的 JavaScript 钩子。

type --- boolean, 过渡事件类型,侦听过渡何时结束。有效值为
"transition"
"animation"
。默认 Vue.js 将自动检测出持续时间长的为过渡事件类型。

mode --- string,控制离开/进入的过渡时间序列。有效的模式有
"out-in"
"in-out"
;默认同时生效。

enter-class --- string

leave-class --- string

enter-active-class --- string

leave-active-class --- string

appear-class --- string

appear-active-class --- string

事件

before-enter

enter

after-enter

before-leave

leave

after-leave

before-appear

appear

after-appear

  
<transition>
元素作为单个元素/组件的过渡效果
<transition>
不会渲染额外的 DOM 元素,也不会出现在检测过的组件层级中
。它只是将内容包裹在其中,简单的运用过渡行为。

<!-- 简单元素 -->
<transition>
<div v-if="ok">toggled content</div>
</transition>
<!-- 动态组件 -->
<transition name="fade" mode="out-in" appear>
<component :is="view"></component>
</transition>
<!-- 事件钩子 -->
<div id="transition-demo">
<transition @after-enter="transitionComplete">
<div v-show="ok">toggled content</div>
</transition>
</div>


  

new Vue({
...
methods: {
transitionComplete: function (el) {
// 传入 'el' 这个 DOM 元素作为参数。
}
}
...
}).$mount('#transition-demo')


(3). transition-group

  

tag
- string, 默认为
span


move-class
- 覆盖移动过渡期间应用的 CSS 类。

除了
mode
,其他特性和
<transition>
相同。

  <transition-group>
元素作为多个元素/组件的过渡效果。
<transition-group>
渲染一个真实的 DOM 元素。默认渲染
<span>
,可以通过
tag
属性配置哪个元素应该被渲染。

  注意,每个
<transition-group>
的子节点必须有 独立的key ,动画才能正常工作

  <transition-group>
支持通过 CSS transform 过渡移动。当一个子节点被更新,从屏幕上的位置发生变化,它将会获取应用 CSS 移动类(通过
name
属性或配置
move-class
属性自动生成)。如果 CSS
transform
属性是“可过渡”属性,当应用移动类时,将会使用 FLIP 技术 使元素流畅地到达动画终点。

(4). slot

 不再赘述

第二部分: keep-alive

props包括:

include --- 字符串或正则表达式。只有匹配的组件会被缓存。

exclude --- 字符串或正则表达式。任何匹配的组件都不会被缓存。

用法:

  
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。正如之前所说的,如果不使用keep-alive,每次切换到一个路由下的组件时,如果有请求,就会发起ajax请求,即在离开这个组件时就已经销毁了这个组件。和
<transition>
相似,
<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素
,也不会出现在父组件链中。 

  当组件在
<keep-alive>
内被切换,它的
activated
deactivated
这两个生命周期钩子函数将会被对应执行。主要用于保留组件状态或避免重新渲染

<!-- 基本 -->
<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>
<!-- 和 <transition> 一起使用 -->
<transition>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</transition>


  include和exclude是vue2.1.0新增的:

<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 v-bind) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>


  注意
<keep-alive>
不会在函数式组件中正常工作,因为它们没有缓存实例。


第三部分:

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


只有keep-alive设置为true的才可以被缓存:

routes: [
{
path: "/",
redirect: "/commodity",
},
{
path: '/Mall',
component: Mall,
name: "店铺",
meta: { keepAlive: false }
},
{
path: '/personal-center',
component: personalCenter,
name: "个人中心",
},
{
path: "/address",
component: AddressManage,
name: "地址管理"
},
{
path: '/order',
component: Myorder,
name: "我的订单"
},
{
path: '/commodity',
component: Commodity,
name: "商品",

meta: { keepAlive: true }

},
{
path:"/Mall/payment",
component: Ordersettlement,
name: "支付信息"
}
]


如下所示: 只有商品这一页才可以被缓存,其他的都不能缓存。



在这里,无论怎么切换路由,都只有Commodity一直存在,并且显示 inactive, 即不活跃,缓存的意思。

这时,我们可以在商品页设置一个 activated 钩子函数:

activated: function () {
alert("activated");
},


这时,只要从别的页面切换过来,都会alert activated,表示已经缓存了。

而其他的页面钩子函数 deactive 会被调用

参考文章: issue

第三部分: 遇到的坑

  使用keep-alive固然是好,但是并不是所有情况下都适合使用keep-alive,因为keep-alive意味着页面省去了重新挂载渲染,这貌似很好,但是这更意味着我们没法使用 created updated mounted 这些生命周期钩子函数了,所以只有在固定不变的地方我们才建议使用keep-alive, 否则不适用。

  比如下面的这个页面:



  仅仅是介绍了一些店铺的基本信息,并没有介绍到更多的内容,所以这时我们就可以使用keep-alive了,但是,这时使用keep-alive并不是万能的,因为一旦用户刷新了页面,而我们的state是在首页获取的,就会出现问题。

所以,更为普遍的方法是下面这样的:  

created () {this.updateMall();
}


  即如果创建了新的页面,那么一定会触发created钩子函数,然后我们再去请求数据,这样就是一种很好的做法了。

参考文章: 官网
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: