Commit 50789fd1 by 高源

添加.vue文件页面加载及数据请求

parent 849d0456
No preview for this file type
<!doctype html>
<html lang="zh-cmn-Hans">
<head>
<meta name="buildTime" content="2025-02-06 10:11:28">
<meta name="buildTime" content="2025-02-07 10:12:47">
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>VueDashboard</title>
<script type="module" crossorigin src="/Content/VueDashboardUi/VueDashboard1/assets/index-DpYjMZ_w.js"></script>
<script type="module" crossorigin src="/Content/VueDashboardUi/VueDashboard1/assets/index-CPk3udR2.js"></script>
<link rel="stylesheet" crossorigin href="/Content/VueDashboardUi/VueDashboard1/assets/index-9k_B1ZU8.css">
</head>
<body>
......
......@@ -7,19 +7,55 @@ import { getSelectMenu } from '@/service/api';
import NotFound from '@/views/_builtin/404/index.vue'; // 引入 404 组件
import ExtJsComponent from './extJs.vue';
import WebviewComponent from './webview.vue';
import VueComponent from './vueComponent.vue'; // 添加新组件导入
interface Props {
url: string;
// eslint-disable-next-line vue/prop-name-casing, vue/no-unused-properties
kvid: string;
type: string;
}
// 定义一个响应式变量来存储异步加载的组件
// 定义响应式变量
const asyncComponent = shallowRef<any>(null);
const { url, kvid, type } = defineProps<Props>();
const selectTag = ref(''); // 定义响应式变量
const extTag = ref(''); // 定义响应式变量
const hasError = ref(false); // 标志位,用于指示是否发生错误
const selectTag = ref('');
const extTag = ref('');
const hasError = ref(false);
// 定义加载外部组件的函数
const loadExternalComponent = async (url: string) => {
const options = {
moduleCache: {
vue: await import('vue')
},
// eslint-disable-next-line @typescript-eslint/no-shadow
async getFile(url: string) {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}`);
}
return await res.text();
},
addStyle(textContent: string) {
const style = document.createElement('style');
style.textContent = textContent;
document.head.appendChild(style);
},
log(type: string, ...args: any[]) {
console[type](...args);
}
};
// 使用 loadModule 加载外部组件
loadModule(url, options)
.then(component => {
asyncComponent.value = component;
console.log('Component loaded:', asyncComponent.value);
})
.catch(error => {
console.error('Error loading component:', error);
});
};
onMounted(() => {
// console.log('mounted');
......@@ -39,8 +75,12 @@ onActivated(async () => {
if (type === 'System') {
console.log(url);
if (url.startsWith('App')) {
// selectTag.value = `${origin}/extjs6/classic/${url}`;
extTag.value = url;
} else if (url.endsWith('.vue')) {
// 添加.vue文件判断
// selectTag.value = `${origin}/${url}`;
// asyncComponent.value = `${origin}/${url}`; // 存储vue文件的URL
loadExternalComponent(`${origin}/${url}`);
} else {
selectTag.value = `${origin}/${url}`;
}
......@@ -50,61 +90,40 @@ onActivated(async () => {
`/Restful/Kivii.Basic.Entities.Function/Access.json?MenuKvids=${kvid}`
);
if (selectMenu?.Results !== undefined && selectMenu?.Results.length > 0) {
// eslint-disable-next-line max-depth
if (selectMenu.Results[0].Handler !== undefined && selectMenu.Results[0].Handler.slice(0, 1) === '/') {
selectTag.value = `${origin}${selectMenu.Results[0].Handler}`;
const handler = selectMenu.Results[0].Handler;
if (handler.slice(0, 1) === '/') {
// 先判断是否以/开头
if (handler.endsWith('.vue')) {
// 如果以.vue结尾
// asyncComponent.value = `${origin}${handler}`;
loadExternalComponent(`${origin}${handler}`);
} else {
// 如果不以.vue结尾
selectTag.value = `${origin}${handler}`;
}
} else {
// selectTag.value = `${origin}/extjs6/classic/${selectMenu.Results[0].Handler}`;
extTag.value = selectMenu.Results[0].Handler;
extTag.value = handler;
}
} else {
hasError.value = true; // 设置错误标志位
hasError.value = true;
}
} catch (error) {
hasError.value = true; // 如果请求失败,也设置错误标志位
hasError.value = true;
}
}
});
// 定义加载外部组件的函数
const loadExternalComponent = async (url: string) => {
const options = {
moduleCache: {
vue: await import('vue')
},
// eslint-disable-next-line @typescript-eslint/no-shadow
async getFile(url: string) {
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Failed to fetch ${url}`);
}
return await res.text();
},
addStyle(textContent: string) {
const style = document.createElement('style');
style.textContent = textContent;
document.head.appendChild(style);
},
log(type: string, ...args: any[]) {
console[type](...args);
}
};
// 使用 loadModule 加载外部组件
loadModule(url, options)
.then(component => {
asyncComponent.value = component;
console.log('Component loaded:', asyncComponent.value);
})
.catch(error => {
console.error('Error loading component:', error);
});
};
</script>
<template>
<div class="h-full">
<WebviewComponent v-if="selectTag && !hasError" id="iframePage" class="size-full" :url="selectTag"></WebviewComponent>
<WebviewComponent
v-if="selectTag && !hasError && !asyncComponent"
id="iframePage"
class="size-full"
:url="selectTag"
></WebviewComponent>
<ExtJsComponent v-else-if="extTag && !hasError" :key="extTag" :url="extTag"></ExtJsComponent>
<VueComponent v-else-if="asyncComponent && !hasError" :url="asyncComponent"></VueComponent>
<NotFound v-else />
</div>
</template>
......
<script setup lang="ts">
import { computed, getCurrentInstance, onActivated, onDeactivated, onMounted, ref, shallowRef } from 'vue';
import { NConfigProvider, darkTheme } from 'naive-ui';
import * as naive from 'naive-ui';
import axios from 'axios';
import { useThemeStore } from '@/store/modules/theme';
const props = defineProps<{
url: string;
}>();
const asyncComponent = shallowRef<any>(null);
const loading = ref(true);
const error = ref(false);
const isActive = ref(true);
const containerId = `vueCom-${Math.random().toString(36).substr(2, 9)}`;
const themeStore = useThemeStore();
const naiveDarkTheme = computed(() => (themeStore.darkMode ? darkTheme : undefined));
// 全局注册Naive UI组件
const app = getCurrentInstance()?.appContext.app;
Object.keys(naive).forEach(key => {
if (key.startsWith('N')) {
app?.component(key, (naive as any)[key]);
}
});
// 添加类型声明
declare global {
interface Window {
$axios: typeof axios;
}
}
// 全局注入axios
(window as any).$axios = axios;
onMounted(async () => {
try {
asyncComponent.value = props.url;
isActive.value = true;
} catch (err) {
console.error('组件加载错误:', err);
error.value = true;
} finally {
loading.value = false;
}
});
onActivated(() => {
isActive.value = true;
});
onDeactivated(() => {
isActive.value = false;
});
</script>
<template>
<Teleport to="#extjs-root">
<div v-show="isActive" :id="containerId" class="containers">
<NConfigProvider :theme="naiveDarkTheme" :theme-overrides="themeStore.naiveTheme">
<div v-if="loading" class="loading">加载中...</div>
<div v-else-if="error" class="error">组件加载失败</div>
<component :is="asyncComponent" v-else class="containers" />
</NConfigProvider>
</div>
</Teleport>
</template>
<style scoped>
.containers {
width: 100%;
height: 100%;
}
.loading,
.error {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: 16px;
}
.error {
color: #ff4d4f;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment