1. 动态导入基本写法
确保你按照正确的语法使用动态导入。在 Vue 3 + Vite 中,动态导入组件可以通过以下方式实现
const component = '/your/path/ComponentName'; // 确保路径是正确的
const componentPath = `@/views${component}.vue`;
const temp = {
component: () => import(componentPath)
};
2. 使用 import.meta.glob
Vite 提供了 import.meta.glob
来处理动态导入,这对于动态加载组件非常有用。这样可以避免路径错误和静态资源问题:
const components = import.meta.glob('@/views/**/*.vue');
const componentName = 'SomeComponent.vue'; // 目标组件名
const temp = {
component: components[`@/views/${componentName}`]
};
3. 使用异步组件
如果你要在模板中使用动态组件,可以使用 Vue 的异步组件特性:
<template>
<component :is="currentComponent" />
</template>
<script setup>
import { ref, defineAsyncComponent } from 'vue';
const componentName = 'SomeComponent.vue'; // 目标组件名
const currentComponent = ref(defineAsyncComponent(() => import(`@/views/${componentName}`)));
</script>
4. 动态加载路由和组件示例
后端数据示例
import {defineAsyncComponent, ref} from "vue";
import {defineStore} from "pinia";
import {getMenuListApi} from "@/api/user.js";
import Layout from "@/views/layout/index.vue";
import {constantRoutes} from "@/router/index.js";
export const usePermissionStore = defineStore('permission', () => {
const routes = ref([])
const generateRoutes = (roles => {
return new Promise((resolve, reject) => {
getMenuListApi().then(res => {
let accessedRoutes;
if (res.code === '500') {
accessedRoutes = filterAsyncRoutes(res.data, roles)
}
routes.value = constantRoutes.concat(accessedRoutes) //将路由添加到constantRoutes里
resolve(accessedRoutes)
}).catch(err => {
reject(err)
})
})
})
const filterAsyncRoutes = (routes, roles) => {
const res = []
routes.forEach(route => {
const temp = {...route}
if (hasPermission(roles, temp)) {
let component = temp.component;
if (component === 'Layout') {
temp.component = Layout
} else {
debugger
/**
* 1.import.meta.glob
*/
// const components = import.meta.glob('@/views/system/*.vue')
// temp.component = components[`@/views${component}.vue`]
/**
* 2.异步组件
*/
temp.component = ref(defineAsyncComponent(() => import(`@/views${component}.vue`)))
}
if (temp.children) {
temp.children = filterAsyncRoutes(temp.children, roles)
}
res.push(temp)
}
})
return res
}
const hasPermission = ((roles, route) => {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
}
return true
})
return {
generateRoutes,
routes
}
},
{
persist: {
key: 'router-store',
storage: sessionStorage
}
})