项目使用KeepAlive缓存页面,页面内容根据参数来显示区分,所以出现多个路由指向同一个组件,缓存就不生效了。
解决思路
- 1、动态路由渲染时,给组件套一个空壳,设置不一样的name。
- 2、动态路由渲染时,复制一个仅name不同的组件,或者修改组件的name。(未使用,仅验证过可行性)
思路一实现:
// dynamicRouteComponet.tsx
import { defineComponent, defineAsyncComponent } from 'vue'
export const dynamicRouteComponet = (componentOption, routeName) => {
return defineComponent({
name: routeName,
components: {
comp: defineAsyncComponent(componentOption)
},
setup() {
return () => {
return <comp></comp>
}
}
})
}
data.component = dynamicRouteComponet(comModule, route.name)
思路二实现
//组件地址必须是字符串,如果是动态的可以使用if判断,要给组件仅呈现一个根元素,不然会有警告异常,直接修改组件的name不会有警告
data.component = () => createCustomComponent(import('../views/...'), route.name)
//警告信息
//Component "default" in record with path "/dashboard/workplace" is a function that does not return a Promise. If you were passing a functional component, make sure to add a "displayName" to the component. This will break in production if not fixed.
//复制组件
import { h, onMounted, shallowRef } from 'vue'
export const createCustomComponent = (component, name) => {
return {
name,
setup() {
const comp: any = shallowRef(null)
onMounted(async () => {
if (component instanceof Promise) {
try {
const module = component
console.log(module)
comp.value = (await module)?.default
} catch (error) {
console.error(`can not resolve component ${name}, error:`, error)
}
return
}
comp.value = component
})
return () => {
console.log(comp.value)
return comp.value ? h(comp.value) : null
}
}
}
}
data.component = () => dynamicComponent(import('../views/Dashboard/Workplace.vue'), route.name)
//修改组件名称
export const dynamicComponent = (component, routeName) => {
return component.then((comp) => {
if (comp && comp.default) {
return { ...comp.default, name: routeName }
}
return comp
})
}