组件的切换与缓存

SPA页面是多组件拼起来的,这时候就存在组件之间的切换问题,Vue中也提出了动态组件的概念,使得我们可以更好的实现组件之间的切换效果 , 但是vue中组件的切换实际是组件本身重新创建和销毁的过程,在某些场景下我们并不希望组件被重新创建重新渲染

这里我就主要介绍Vue中组件的切换以及缓存解决方法

一、组件的切换方式

(1) 使用 v-if和v-else或者(v-show)
<Com1 v-if="istrue" />
<Com2 v-else />

当里面的istrue为true时,Com1显示,否则就是Com2进行显示

(2) 使用is特性来进行动态组件的切换
// 点击切换登录,注册,退出组件

   <template>
     <div>
        <a href="#" @click.prevent="comName = 'login'">登录</a>
        <a href="#" @click.prevent="comName = 'register'">注册</a>
        <a href="#" @click.prevent="comName = 'logOut'">退出</a>
        
        //  <component></component> 来展示对应名称的组件,相当于一个占位符
        //    :is 属性指定 组件名称

      <component :is="comName"></component>
      </div>
    </template>
(3) 使用路由(router)进行动态组件的切换
// 路由规则:
  {
    path: '/login',
    name: 'login',
    component: () => import('../views/login.vue')
  },
  {
    path: '/register',
    name: 'register',
    component: () => import('../views/register.vue')
  },
  
  // 需要展示组件的位置:
  <router-view />

二、组件缓存

组件的缓存可以在进行动态组件切换的时候对组件内部数据进行缓存,而不是走销毁流程

使用场景: 多表单切换,对表单内数据进行保存

1.keep-alive定义:

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

是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。 当组件在<keep-alive>内被切换,它的activateddeactivated这两个生命周期钩子函数将会被对应执行 。

2.keep-alive的两个钩子函数

activateddeactivated
keep-alive 组件激活时调用keep-alive 组件停用时调用
该钩子函数在服务器端渲染期间不被调用该钩子在服务器端渲染期间不被调用

使用keep-alive会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在 activated阶段获取数据,承担原来created钩子函数中获取数据的任务。

注意: 只有组件被keep-alive包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的

在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子函数依然不会被调用!在服务端渲染时,此钩子函数也不会被调用。

设置了缓存的组件钩子调用情况:

第一次进入:beforeRouterEnter ->created->…->activated->…->deactivated> beforeRouteLeave

后续进入时:beforeRouterEnter ->activated->deactivated> beforeRouteLeave

3.keep-alive使用方法
(1)Props
include - 字符串 || 数组 || 正则       名称匹配的组件会被缓存-->include的值为组件的name。

exclude - 字符串 || 正则               任何名称匹配的组件都不会被缓存。

max - 数量                            决定最多可以缓存多少组件。 
(2)搭配<component></component>使用
  <template>
     <div>
        <a href="#" @click.prevent="comName = 'login'">登录</a>
        <a href="#" @click.prevent="comName = 'register'">注册</a>
        <a href="#" @click.prevent="comName = 'logOut'">退出</a>
     
     // login组件会被缓存 不设置include会默认缓存所有挂载到<component></component>的组件
     // 缓存多个指定组件include = ['login','register']
      <keep-alive include="login">
          <component :is="comName"></component>
      </keep-alive>    
      </div>
    </template>
(3)搭配路由使用

需配置路由meta信息的keepAlive属性
keep-alive代码可以结合v-if进行包裹,如果meta中的keepAlive为true进行缓存,否则不进行缓存,这样可以更灵活


 {
    path: '/login',
    name: 'login',
    component: () => import('../page/login.vue')
    meta:{
        keepAlive : true   // login组件会被缓存
    }
  },
  {
    path: '/index',
    name: 'index',
    component: () => import('../page/index.vue'),
      meta:{
        keepAlive : false   //  index组件不会被缓存
    }
  }
<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>
(4)清除缓存组件
 // beforeRouteLeave()钩子
 
// 判断是否要到详情页

  beforeRouteLeave(to, from, next) {
      if (to.path === "/goods_detail") {
        from.meta.keepAlive = true;
      } else {
        from.meta.keepAlive = false;
      }
      next();
    }

拓展:

beforeRouteLeave钩子

beforeRouteLeave(to, from, next): 离开路由之前执行的函数,可用于页面的反向传值,页面跳转。

 // 点击后拿到数据返回给下单地址
  beforeRouteLeave (to, from, next) {
    if (to.name === 'home') {
      to.query.temp = '选中后的地址'
    }
    console.log(to)
    console.log(from)
    next()//一定不要忘记写
  },
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用一个缓存对象来存储已经渲染过的组件内容并在需要时进行调用。具体实现可以参考以下步骤: 1. 创建一个缓存对象,可以使用一个简单的 JavaScript 对象,将组件名作为键值对应存储组件内容。 2. 在组件渲染前,先从缓存对象中查找是否已有该组件缓存内容,如果有,则直接返回该内容。 3. 如果没有缓存内容,则使用该组件进行渲染,渲染完成后,将渲染后的组件内容存储到缓存对象中。 4. 在组件切换时,依然可以使用缓存对象中存储的内容进行渲染。 具体实现可以参考下面的代码: ```jsx const cache = {}; // 缓存对象 class CacheableComponent extends React.Component { constructor(props) { super(props); this.state = { isCached: false }; } componentWillMount() { const { name } = this.props; if (name in cache) { this.setState({ isCached: true, cachedContent: cache[name] }); } } componentDidUpdate() { const { name } = this.props; if (!this.state.isCached) { cache[name] = ReactDOMServer.renderToString(this.props.children); this.setState({ isCached: true, cachedContent: cache[name] }); } } render() { if (this.state.isCached) { return <div dangerouslySetInnerHTML={{ __html: this.state.cachedContent }} />; } return <div>{this.props.children}</div>; } } ``` 在上面的代码中,我们创建了一个名为 `CacheableComponent` 的组件类,这个组件会在第一次渲染时,根据 `name` 属性去缓存对象中查找该组件缓存内容。如果有缓存内容,直接通过 `dangerouslySetInnerHTML` 将缓存内容插入到 DOM 中,否则使用 `ReactDOMServer.renderToString` 方法将组件内容转换为字符串,并存储到缓存对象中。在组件切换后,依然可以通过缓存对象中的内容进行渲染,实现了组件缓存的效果。 使用方法: ```jsx <CacheableComponent name="myComponent"> <MyComponent /> </CacheableComponent> ``` 在上面的代码中,我们在 `CacheableComponent` 组件的子组件中插入了要渲染的实际组件,同时指定了组件的名称为 `"myComponent"`,即在缓存对象中以 `"myComponent"` 为键值存储组件内容,下次渲染时将直接使用缓存对象中的内容进行渲染。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值