目次
コンポーネント名を取得したい場合は、カスタム キャッシュ コンポーネントとカスタム クリア キャッシュ コンポーネントを実行するか、コンポーネントを動的に切り替える必要があります。
しかし、ほとんどの場合、それらはコンポーネントをキャッシュしています
1. コンポーネント名を取得するツール関数を定義する
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.ユースケース
ここに index1/2/3 ファイルを用意しましたが、
スクリプト タグにコンテンツが含まれている必要があります。静的ページに相当するコンテンツはありません。未定義が返され、キャッシュする必要はありません。
以下はindex1です。混乱を避けるために、index2/3に入れて手動で変更できます
<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
冗長なコードを書かないようにするために、エッジの問題には対処しませんでしたが、コアのキャッシュ コンポーネントは既に完了しています。
<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>