vue使用keep-alive缓存组件

vue使用keep-alive缓存组件

为了避免反复重渲染导致的性能问题,可以使用keep-alive组件来实现缓存【不会销毁哦】。

这里再次记录下keep-alive组件基本使用,具体使用请查看文档。


keep-alive文档

在动态组件上使用keep-alive文档

效果图

在这里插入图片描述

生命周期

  • 初次进入时:created > mounted > activated;离开页面会触发 deactivated函数。
  • 再次进入:会触发 activated函数,需要每次进入页面都要执行的方法放在 activated中。
  • 当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行。

开启keep-alive

此展示在APP.vue中配置,可根据需求自行调整。

  • APP.vue页面中开启keep-alive组件
<template>
    <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>
</template>

路由配置

  • router中配置meta对象,添加keepAlive属性
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const routes = [ 	
    {
        path: '/index',
        name: 'index',
        component: () => import("@/components/index"),
        meta: {
            title: 'keep-alive',
            keepAlive: true //如需缓存组件设置true
        }
    },
]

const router = new Router({
    routes
})

使用

此时,页面内容已实现缓存

<template>
    <div class='keepAlive'>
        <div class="wrap">
            <h1>测试Keep-alive</h1>
            <input type="text" v-model="val" placeholder="请输入">
            <router-link to="step">下一步</router-link>
        </div>
    </div>
</template>


<script>
    export default {
        name: 'index',
        data () {
            return {
                val: '',
            }
        },
        activated() {
            // 可根据需求处理相关逻辑
            console.log('activated');
        },
        deactivated() {
            console.log('deactivated ');
        }
    }
</script>

如何记录上次滚动的位置?

返回上一页,没有保持滚动位置

  • router中添加scrollBehavior来管理组件滚动行为
  • 注意: 这个功能只在支持 history.pushState 的浏览器中可用。

滚动行为.文档

/**
 * 处理滚动行为
 */
scrollBehavior (to, from, savedPosition) {
    if (savedPosition) {
        return savedPosition
    } else {
        if (from.meta.keepAlive) {
            from.meta.savedPosition = document.body.scrollTop
        }
        return { x: 0, y: to.meta.savedPosition || 0 }
    }
}

遇到问题

个人遇到问题,欢迎指导…

无法记录上次滚动位置

即使设置scrollBehavior滚动行为,发现返回上一页还是无法记录滚动位置。

1. 设置overflow属性引起无法记录滚动行为
  • 场景: 页面最外层高度设置100%,搭配overflow属性使用,超过高度内容自动滚动,发现无法记录上次滚动位置问题。
<template>
    <div class='keepAlive'>
        <div class="wrap">
            <div id="header">header</div>
           	<div class="main">
                <!-- 内容 -->
    		</div>
            <div id="footer">footer</div>
        </div>
    </div>
</template>
.keepAlive {
    height: 100%;
    .wrap {
        width: 100%;
        height: 100%;
        overflow: hidden;
    }
    .main {
        height: 100%;
        overflow-y: scroll;
        -webkit-overflow-scrolling:touch;
    }
}
解决方式

从布局上解决

  • 方式一: 使用flex布局
.keepAlive {
    height: 100%;
    .wrap {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction:column;
    }

    .main {
        flex:1;
        width:100%;
    }
}
  • 方式二: 使用position定位
.keepAlive {
     height: 100%;
    .wrap{
        width: 100%;
        position: relative;
    }
    .main{
        position: absolute;
        z-index: 1;
        top: 0;
        left: 0;
        width: 100%;
    }
}
2. 如果布局中设置overflow属性,无法记录位置如何解决?
  • 场景: 通过@scroll事件结合overflow属性使用时,返回上一页无法记录滚动的位置
<div class="keepAlive" @scroll="scrollTap($event)" ref="wrap">
    <div class="list">
        <div class="item" v-for="item in 30">
            列表
        </div>
    </div>
</div>

.keepAlive {
    @include wh(100%, 100%);
    @include bg(hotpink);

    overflow: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}
<script>
export default {
    name: 'index',
    data() {
        return {
            
        };
    },
    activated() {
        // 根据需求处理业务逻辑
        console.log('------activated--------》');
    },
    deactivated() {
        console.log('------deactivated--------》');
    },
    methods: {
		/**
         *  监听滑动事件
         */
        scrollTap(e) {
            // 根据需求处理业务逻辑
            console.log(e);
        }
    }
}
</script>
解决方式
  • 可以通过beforeRouteEnterbeforeRouteLeave相关方法来记录滚动高度。
  • data中定义scroll
data() {
    return {
		scroll: 0, // 记录滚动值
    };
},
/**
  * 进入路由之前执行的函数
  */
beforeRouteEnter(to,from,next) {
    next(vm => {
        const div1 = vm.$refs.wrap
        // 记录滚动高度
        div1.scrollTop = vm.scroll;
        console.log('---beforeRouteEnter-----》', div1.scrollTop);
    })
},
/**
  * 离开路由之前执行的函数
  */
beforeRouteLeave(to,from,next){//记录离开时的位置
	const div1 = this.$refs.wrap;
    this.scroll = div1.scrollTop; //data中记得定义变量scroll
    console.log('-----beforeRouteLeave------》', this.scroll);
    // 注意: 调用next()
    next()
},
效果图

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值