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

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

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

  

 

第一部分: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下设置多个组件。vue

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

    也能够直接绑定在对象上:git

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 元素,也不会出如今检测过的组件层级中。它只是将内容包裹在其中,简单的运用过渡行为。github

<!-- 简单元素 -->
<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 属性配置哪一个元素应该被渲染。ajax

  注意,每一个 <transition-group> 的子节点必须有 独立的key ,动画才能正常工做正则表达式

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

 

 

(4). slotapi

 再也不赘述缓存

 

 

 

 

第二部分: 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钩子函数,而后咱们再去请求数据,这样就是一种很好的作法了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

参考文章: 官网

相关文章
相关标签/搜索