Vue3 gets component name, custom cache component, custom clear cache component

Table of contents

1. Define the tool function to get the component name

2. use

3. Complete case


 If you want to get the component name, you need to do custom cache components and custom clear cache components, or dynamically switch components

But most likely they are caching components

1. Define the tool function to get the component name

import router from "@/routes"
export default function getComponentName() {
    let currentMatched = router.currentRoute.value.matched
    let currentComponent = currentMatched[currentMatched.length - 1].components!.default
    let componentName = currentComponent.name || (currentComponent as { __name: string }).__name
    // 如果组件内的 script 没有内容,并且没有自定义组件name,就会返回 undefined
    console.log('componentName',componentName);
    
    return componentName
}

2. Use cases

I have prepared index1/2/3 files here,

There must be content in the script tag, no content is equivalent to a static page, it will return undefined, and there is no need to cache,

The following is index1, you can put it in index2/3 and modify it manually to avoid confusion

<template>
    index1
    <button @click="num++">页面1的num++</button>
    <div >{
   
   { num }}</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let num = ref(0);
</script>

app.vue

In order not to write redundant code, I did not deal with edge issues, but the core caching components are already done

<script setup lang="ts">
import router from "./routes";
import getComponentName from "./utils/getComponentName";
import { ref } from "vue";
// 不要缓存的页面
let includeName = ref<string[]>([]);
// 需要缓存的页面
let excludeName = ref<string[]>([]);
// tabs栏
let tabs = ref<{ path: string; name: string; componentName: string }[]>([]);

const goto = async (path: string, name: string) => {
	// 跳转,路由是Promise,是异步的
	await router.push(path);
	// 获取组件名
	let comName = getComponentName();
	// 现在你有 路由路径 和 这个路由路径的组件名
	let tab = {
		path,
		name,
		componentName: comName,
	};

	// 判断是否有这个tab页面,是否都通过测试,如果是空数组则返回true
	let flag = tabs.value.every((item: any) => {
		return item.path !== path;
	});
	// 如果没有就添加新的tab标签
	if (flag) tabs.value.push(tab);

	// 是否有组件名(看1的注释) &&
	// ! 需要缓存的里面是否有这个组件名 &&
	// ! 不要缓存的是否有这个组件名
	if (comName && !includeName.value.includes(comName) && !excludeName.value.includes(comName)) {
		includeName.value.push(comName);
	}
};

//关闭对应的tab标签
const tabRemove = (item: any) => {
	// 获取该路由对应的组件名
	let index = tabs.value.findIndex((v: any) => v.path === item.path);
	// 清除缓存组件名
	let componentName = tabs.value[index].componentName;
	if (componentName) {
		includeName.value.splice(includeName.value.indexOf(componentName), 1);
	}
	// 也把tabs里面的清除
	tabs.value.splice(index, 1);
};
</script>
<template>
	<div>
		菜单栏
		<ul>
			<li @click="goto('/index1', '页面1')">
				<span>去页面1</span>
			</li>
			<li @click="goto('/index2', '页面2')">
				<span>去页面2</span>
			</li>
			<li @click="goto('/index3', '页面3')">
				<span>去页面3</span>
			</li>
		</ul>
	</div>
	<div>
		tab栏
		<ul>
			<li v-for="item in tabs">
				<span @click="router.push(item.path)">{
   
   { item.name }}</span>
				<span @click="tabRemove(item)">X</span>
			</li>
		</ul>
	</div>
	<div>
		页面:
		<router-view v-slot="{ Component }">
			<keep-alive :include="includeName">
				<component :is="Component" />
			</keep-alive>
		</router-view>
	</div>
</template>

<style lang="css" scoped>
li {
	cursor: pointer;
}
</style>

Guess you like

Origin blog.csdn.net/weixin_59916662/article/details/129611803