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


    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钩子函数,然后我们再去请求数据,这样就是一种很好的做法了。

    参考文章: 官网

  • 相关阅读:
    Java高级工程师面试题总结及参考答案
    Java面试通关要点汇总整理【终极版】
    40道Java基础常见面试题及详细答案
    Java方向如何准备BAT技术面试答案(汇总版)
    10-01 Java 类,抽象类,接口的综合小练习--运动员和教练
    div在页面垂直居中方法---增强改进版
    TortoiseSVN切换更改登录账号密码
    09-04 java 接口
    09-03 Java 抽象类
    09-02 java 多态
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6905140.html
Copyright © 2020-2023  润新知