uniapp实现页面缓存(仿router-view回退上页)

技术栈:uniapp的vue3+vite2+ts版本
前言:最近一个需求,页面部分区域切换到新的组件页,返回时不需要重新请求,即有缓存,但是在uniapp中没有<router-view />该功能,因为pages.json无法设置子路径,导致不能使用页面回退来访问页面缓存,所以同时使用v-if和v-show来完成缓存效果(uniapp中自带的<keep-alive>只适用H5,此种方法适用多端,如微信小程序)

一、原理分析

通过v-if控制是否渲染,通过v-show控制是否显示,我是使用pinia进行状态储存,也可以通过vuex或组件间传参实现

二、页面逻辑

通过数组控制,数组里参数对应v-if和v-show,即对应如下[v-if, v-show],组件B和组件C初始状态为[false, false],例如组件A至B时[true, true],即渲染加显示,同理,返回时改为[false, true],即不渲染(改为[false, false]也可以,渲染都未渲染肯定未显示了)
在这里插入图片描述

三、缓存效果代码实现

我把业务中的代码提取出来简化后来展示效果,是否成功可以看控制台是否重新打印该页面提示,此处只贴状态管理和三个组件部分,基本上最重要的内容都包含进去了,文章末尾有demo项目,有区别之处请自行对照
stores/base.ts

import { defineStore } from 'pinia';

export const useBase = defineStore('base', {
	state: () => {
		return {
			subunitBShow: [false, false], // 参数对应[v-if, v-show]
			subunitCShow: [false, false], // 参数对应[v-if, v-show]
		};
	},
	actions: {
		setSubunitBShow(param: Array<boolean>) {
			this.subunitBShow = param
		},
		setSubunitCShow(param: Array<boolean>) {
			this.subunitCShow = param
		}
	},
});

subunitA.vue

<template>
    <subunit-b v-if="store.subunitBShow[0]" v-show="store.subunitBShow[1]"></subunit-b>
    <view v-else>
        <text>这是组件A</text>
        <button @click="handleClickTo">去组件B</button>
    </view>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted } from 'vue'
import SubunitB from '@/components/cache/subunitB.vue';
import { useBase } from '@/stores/base';
const store = useBase()
onMounted(() => {
    console.log('这是组件A')
})
const handleClickTo = () => {
    store.setSubunitBShow([true, true])
}
</script>

<style lang='scss' scoped>
</style>

subunitB.vue

<template>
    <subunit-c v-if="store.subunitCShow[0]" v-show="store.subunitCShow[1]"></subunit-c>
    <view v-else>
        <text>这是组件B</text>
        <button @click="handleClickTo">去组件C</button>
        <button @click="handleClickBack">返回组件A</button>
    </view>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted } from 'vue'
import SubunitC from '@/components/cache/subunitC.vue';
import { useBase } from '@/stores/base';
const store = useBase()
onMounted(() => {
    console.log('这是组件B')
})
const handleClickTo = () => {
    store.setSubunitCShow([true, true])
}
const handleClickBack = () => {
    store.setSubunitBShow([false, true])
}
</script>

<style lang='scss' scoped>
</style>

subunitC.vue

<template>
    <view>
        <text>这是组件C</text>
        <button @click="handleClickBack">返回组件B</button>
    </view>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useBase } from '@/stores/base';
const store = useBase()
onMounted(() => {
    console.log('这是组件C')
})
const handleClickBack = () => {
    store.setSubunitCShow([false, true])
}
</script>

<style lang='scss' scoped>
</style>
四、参考链接地址

1、关于uniapp不支持router-view的讨论:https://ask.dcloud.net.cn/question/64581
2、示例参照一:http://www.manongjc.com/detail/29-bixynacatyhmfrr.html
3、示例参照二:https://blog.csdn.net/qq_41777791/article/details/104665170
4、v-show和v-if能否一起使用的问题:https://blog.csdn.net/yuan_xiaoxin/article/details/120988587
5、文章上述内容的demo案例,我放在了gitee上,有需要自行提取,若有用并且方便的话请收藏点赞一下,谢谢:https://gitee.com/zasulan/csdn-item/tree/master/uni-demo-item-vite

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值