当前位置: > > > Vue.js - 路由 vue-router 的使用详解6(keep-alive使用2:结合router-view)

Vue.js - 路由 vue-router 的使用详解6(keep-alive使用2:结合router-view)

    <keep-alive> 除了可以包裹普通组件外,它还可以配合 <router-view> 使用,将整个路由页面一起缓存下来。下面通过样例进行演示。

二、配合 router-view 使用

1,使用样例

(1)效果图
  • 这是一个简单的 router-view 路由导航效果。当路由地址改变时,页面组件随之切换显示。
  • 由于 router-view 是包裹在 <keep-alive> 中,可以看到切换后之前页面的内容和数据仍然保留,说明页面组件消失时并没有被销毁,而是缓存起来。

(2)样例代码
  • 根实例(App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  text-align: center;
}
</style>

  • 首页面(index.vue
<template>
  <div>
    <h1>首页</h1>
    <input type="text" name="" value=""><br>
    <router-link to="/hello">前往欢迎页</router-link>
  </div>
</template>

<script>
export default {
  name: 'index',
  //keep-alive钩子函数:组件被激活时调用
  activated() {
    console.log('首页被激活');
  },
  //keep-alive钩子函数:组件消失,被缓存时调用
  deactivated() {
    console.log('首页被缓存');
  }
}
</script>

  • 欢迎页(hello.vue
<template>
  <div>
    <h1>欢迎页</h1>
    <input type="text" name="" value=""><br>
    <router-link to="/">回到首页</router-link>
  </div>
</template>

<script>
export default {
  name: 'hello',
  //keep-alive钩子函数:组件被激活时调用
  activated() {
    console.log('欢迎页被激活');
  },
  //keep-alive钩子函数:组件消失,被缓存时调用
  deactivated() {
    console.log('欢迎页被缓存');
  }
}
</script>

2,钩子函数

(1)<keep-alive> 提供了如下两个生命周期钩子函数:
  • activated():页面组件被激活时调用。即组件第一次渲染时会被调用,之后每次 keep-alive 激活时也会被调用。通常我们可以在这个方法中实现:每次进入页面的时候获取最新的数据。
  • deactivated():页面组件被停用时调用。

(2)关于这两个钩子函数的调用要注意的是:
  • 只有组件被 keep-alive 包裹时,这两个函数才会被调用。如果作为正常组件使用,是不会被调用的。
  • 即使组件被 keep-alive 包裹,如果使用 exclude 排除之后,这两个钩子依然不会被调用。

(3)上面样例中,我们在页面组件内部的钩子函数中输出了一些信息。当我们打开首页,先跳转到欢迎页然后再跳回来,控制台输出如下:

三、只缓存 router-view 里面的部分组件页面

如果只想 router-view 里面某个、或某些页面组件被缓存,通常有如下两种办法:
  • 使用 include/exclude 来实现
  • 配合 router.meta 属性来实现

1,使用 include/exclude 来实现

(1)这两个属性的作用前文也介绍过:
  • include:只有匹配的组件会被缓存(支持字符串或正则表达)
  • exclude:任何匹配的组件都不会被缓存(支持字符串或正则表达)

(2)使用样例
  • 只缓存 name index 的组件:
<keep-alive include="index">
  <router-view/>
</keep-alive>

  • 不缓存 name index 的组件:
<keep-alive exclude="index">
  <router-view/>
</keep-alive>

  • 只缓存 name index hello 的组件:
<keep-alive include="index,hello">
  <router-view/>
</keep-alive>

  • 只缓存以 in 开头的组件(使用正则表达式,需使用 v-bind):
<keep-alive :include="/^in.*/">
  <router-view/>
</keep-alive>

  • 也可以动态绑定需要缓存的组件:
<keep-alive :include="includedComponents">
  <router-view/>
</keep-alive>

2,配合 router.meta 属性来实现

(1)首先我们在路由元信息 meta 中添加个 keepAlive 属性,用来表示那些页面组件需要缓存,那些不需要。
import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index' //引入首页组件
import hello from '@/components/hello' //引入欢迎页组件

//Vue全局使用Router
Vue.use(Router)

const router =  new Router({
  routes: [ //配置路由,使用数组形式
    {
      path: '/',   //链接路径
      name: 'index',  //路由名称
      component: index, //映射的组件
      meta: {
        keepAlive: true // 需要缓存
      }
    },
    {
      path: '/hello',
      name: 'hello',
      component: hello,
      meta: {
        keepAlive: false // 不需要缓存
      }
    }
  ]
})

export default router

(2)接着我们对根实例(App.vue)代码做如下修改。通过判断元数据的 keepAlive 属性值,来决定路由视图是放在 <keep-alive> 里面(需要缓存),还是外面(不需要缓存)
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

四、页面动态决定是否需要缓存

    有时对于同一个页面组件,并不是一直都需要缓存,或者一直都不缓存。而是根据情况动态地改变。实现这种需求同样是通过配合 router.meta 属性来实现,我们根据情况动态地改变里面的 keepAlive 属性值即可。

1,效果图

(1)当我们从首页跳转到欢迎页再跳回来,发现首页内容仍然保留,说明首页是缓存的。

(2)当我们从首页跳转到关于页再跳回来,发现首页内容已经清空,说明首页这时又不缓存了。


2,样例代码 

(1)在欢迎页(hello.vue)路由离开这个钩子函数中设置首页缓存:
<template>
  <div>
    <h1>欢迎页</h1>
    <input type="text" name="" value=""><br>
    <router-link to="/">回到首页</router-link>
  </div>
</template>

<script>
export default {
  name: 'hello',
  //keep-alive钩子函数:组件被激活时调用
  activated() {
    console.log('首页被激活');
  },
  //keep-alive钩子函数:组件消失,被缓存时调用
  deactivated() {
    console.log('首页被缓存');
  },
  beforeRouteLeave(to, from, next) {
    //设置下一个路由的meta(即首页)
    to.meta.keepAlive = true;  //让首页缓存,即不刷新
    next();
  }
}
</script>

(3)在关于页(about.vue)路由离开这个钩子函数中设置首页不缓存:
<template>
  <div>
    <h1>关于页</h1>
    <input type="text" name="" value=""><br>
    <router-link to="/">回到首页</router-link>
  </div>
</template>

<script>
export default {
  name: 'hello',
  //keep-alive钩子函数:组件被激活时调用
  activated() {
    console.log('首页被激活');
  },
  //keep-alive钩子函数:组件消失,被缓存时调用
  deactivated() {
    console.log('首页被缓存');
  },
  beforeRouteLeave(to, from, next) {
    //设置下一个路由的meta(即首页)
    to.meta.keepAlive = false;  //让首页不缓存,即刷新
    next();
  }
}
</script>
评论0