笔记
<!-- keep-alive学习
感觉keep-alive类似于v-show啊,我用v-show的时候,组件的数据啥的也都不会变
路由数组对象的meta中可以放自定义属性
1.用keep-alive的目的只是为了让两个经常切换的组件之间切换的时候保持状态,
从别的页面重新进入keep-alive页面的时候,我们还是想让keep-alve能够重新渲染一下的
但是并不会,他一旦看是keep-alive就一直只有那两个生命周期触发了
为了解决这个问题
可以动态的设置它的keep-alive的开启和关闭
从别的地方进入时,退出keep-alive的时候关闭keep-alive缓存
进入应该keep-alive的页面时,开启keep-alive
在keep-alive的页面的beforeRouteEnter钩子里看,如果当前页面离开的时候,去的是非keep-alive页面,那么把当前页面的keepalive关闭,否则继续保持开启
-->
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Test1 from '@/components/Test1'
import Test2 from '@/components/Test2'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/helloworld',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/test1',
name: 'Test1',
meta: {
keepAlive: true
},
component: Test1
},
{
path: '/test2',
name: 'Test2',
meta: {
keepAlive: true
},
component: Test2
}
]
})
app.vue
<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>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
helloworld.vue
<template>
<div class="hello">
<div>HelloWorld</div>
<div @click="$router.push('/test1')">去test1</div>
<div @click="$router.push('/test2')">去test2</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
created () {
console.log('helloworld created')
},
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
test1.vue
<template>
<div>
<div>test1</div>
<div @click="$router.push('/test2')">去test2</div>
<div @click="$router.push('/helloworld')">去helloworld</div>
</div>
</template>
<script>
export default {
name: 'Test1',
data: () => ({}),
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
if (from.path == '/helloworld') {
from.meta.keepAlive = false
}
next()// 要写next才会走下一步,不然会卡住的
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
next()// 要写next才会走下一步,不然会卡住的
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
if (to.path == '/helloworld') {
from.meta.keepAlive = false
}
if (to.path == '/test2') {
to.meta.keepAlive = true
}
next()// 要写next才会走下一步,不然会卡住的
},
created () {
console.log('test1 created')
// this.$route,
// {fullPath: "/test1"
// hash: ""
// matched: [{…}]
// meta: {}
// name: "Test1"
// params: {}
// path: "/test1"
// query: {}}
},
activated () {
console.log('test1 activated')
},
deactivated () {
console.log('test1 deactivated')
},
methods: {}
}
</script>
<style scoped>
</style>
test2.vue
<template>
<div>
<div>test2</div>
<div @click="$router.push('/test1')">去test1</div>
<div @click="$router.push('/helloworld')">去helloworld</div>
</div>
</template>
<script>
export default {
name: 'Test2',
data: () => ({}),
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
// console.log('beforeRouteEnter to,form', to, from)// to当前路由,from从哪个路由跳转过来的
if (from.path == '/helloworld') {
from.meta.keepAlive = false
}
next()// 要写next才会走下一步,不然会卡住的
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
next()// 要写next才会走下一步,不然会卡住的
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
if (to.path == '/helloworld') {
from.meta.keepAlive = false
}
if (to.path == '/test1') {
to.meta.keepAlive = true
}
// console.log('beforeRouteLeave to,form', to, from)// to要跳转到的路由 from当前路由
next()// 要写next才会走下一步,不然会卡住的
},
created () {
console.log('test2 created')
},
activated () {
console.log('test2 activated')
},
deactivated () {
console.log('test2 deactivated')
},
methods: {}
}
</script>
<style scoped>
</style>
这些文章有借鉴到
https://zhuanlan.zhihu.com/p/96740001? 不过这篇里的解决从别的页面里进来,keep-alive不再重新刷新一二次的问题的方法没作用,我写了一种方法解决了 具体可以试验我上面代码
https://www.jianshu.com/p/730e3c7712de?这篇文章的解决方法是把created的里的逻辑在activated里写,或者在beforeRouteEnter里写
就这么着把
includ和exclued没研究,不过下次用的时候再看一样,知道大体就行了
|