vue3 keepAlive+记录滚动条

store

javascript 复制代码
import { defineStore } from 'pinia'

export const useCachedViewsStore = defineStore('cachedViews', {
    state: () => ({
        // 存储的是组件的 name,不是路由 path
        cachedViews: [] as string[]
    }),

    actions: {
        /** 添加缓存(路由守卫中调用) */
        addCachedView(name: string) {
            if (name && !this.cachedViews.includes(name)) {
                this.cachedViews.push(name)
            }
        },

        /** 移除指定缓存(关闭标签页/编辑后返回时调用) */
        removeCachedView(name: string) {
            const index = this.cachedViews.indexOf(name)
            if (index > -1) {
                this.cachedViews.splice(index, 1)
            }
        },

        /** 清空所有缓存(退出登录时调用) */
        clearAllCachedViews() {
            this.cachedViews = []
        }
    }
})

App.vue

javascript 复制代码
<template>
    <router-view v-slot="{ Component, route }">
        <keep-alive :include="cachedViews">
            <component :is="Component" :key="route.fullPath"/>
        </keep-alive>
    </router-view>
</template>

<script setup lang="ts">
    import {computed} from 'vue'
    import {useCachedViewsStore} from '@/store'

    const cachedViewsStore = useCachedViewsStore()
    const cachedViews = computed(() => cachedViewsStore.cachedViews)
</script>

router

javascript 复制代码
import {createRouter, createWebHashHistory} from 'vue-router'
import routes from './routes'
import {useCachedViewsStore} from '@/store'

const asmnPosition = {}
const router = createRouter({
    history: createWebHashHistory(`/#/${import.meta.env.VITE_PROJECT_NAME}/`),
    routes,
    scrollBehavior(to, from, savedPosition) {
        if (needKeepAlive(to)) {
            // savedPosition 是浏览器前进/后退时记录的位置
            if (savedPosition) {
                return savedPosition
            }
            // 代码 push 跳转,读取 asmnPosition 中保存的位置
            const top = asmnPosition[to.name]
            if (top)
                return {top}
        }
        // 滚动到顶部
        return {top: 0}
    }
})

router.beforeEach((to, from, next) => {
    const cachedViewsStore = useCachedViewsStore()
    if (needKeepAlive(to))
    // 注意:这里传入的是路由 name,必须和组件 name 保持一致!
        cachedViewsStore.addCachedView(to.name)

    if (needKeepAlive(from))
        asmnPosition[from.name] = window.scrollY

    next()
})


function needKeepAlive(to) {
    return to.meta.keepAlive && to.name
}

export default router

router

javascript 复制代码
const routes = [
    {
        path: '/',
        // keepAlive时name必须和组件 name 保持一致!
        name: 'home',
        component: () => import( '@/views/Home.vue'),
        meta: {
            keepAlive: true,
        }
    },
    {
        path: '/test',
        name: 'test',
        component: () => import( '@/views/Test.vue'),
    },
]

export default routes

home.vue

javascript 复制代码
<template>
    <div class="flex-center">
        <div class="a">
            <div class="b">slave-home</div>
        </div>
        <router-link to="/test">测试页</router-link>
        <div v-for="(v, i) in 100">
            {{v}}
        </div>
    </div>

    <HomeTabbar/>
</template>

<script setup lang="ts">
    import {ref} from 'vue'
    import HomeTabbar from '@/components/HomeTabbar/Index.vue'

		// 定义当前组件的name,同vue2的name
    defineOptions({
        name: 'home'
    })

    const active = ref('0')

    console.log('asmn')
</script>

<style lang="scss" scoped>
    .a {
        .b {
            color: red;
        }
    }
</style>

通过来回切换页面 Home --> Test ---> Home,看有无日志"asmn"输出,判断keepAlive是否生效,相当于有输出代表生效,即页面内的组件在test -> push -> Home回来的时候没被销毁。

keepAlive无法记录滚动条,所以也单独处理了,可观察切换回来时,滚动条是否与上次一致。

注意:使用keepAlive与记录滚动条,router里面的name需要与组件的name保持一致

相关推荐
葡萄城技术团队1 小时前
SpreadJS V19.2 新特性揭秘:甘特表的进度线
前端
计算机魔术师1 小时前
黄仁勋台上接特朗普电话开免提,全场听到一句话:AI 不会减速
前端
yivifu2 小时前
HTML元素的textContent和innerText两个属性的差别
前端·html
Bs_MoneyMagnet2 小时前
基于springboot+vue的会议室预约管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
天若有情6732 小时前
开源轻量双语工具|一键批量查询 NPM 包历史下载量,支持按作者批量统计
javascript·npm·github pages·开源工具·netlify·前端开源·npm克隆量
咸鱼老弟2 小时前
Speculative Decoding(投机采样):大模型"先猜后验",生成速度翻倍
前端·算法·ai编程
Bs_MoneyMagnet2 小时前
基于springboot+vue的茶铺管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
a1117762 小时前
网页版「MATLAB」开源
前端·开源
JianZhen✓3 小时前
解决SPA发版旧版本残留+动态路由打包失效的完整方案(附落地代码)
前端·状态模式