组件修改
This commit is contained in:
@@ -1,9 +1,23 @@
|
||||
<template>
|
||||
<div class="iframe-view">
|
||||
<!-- 可选的头部区域 -->
|
||||
<div v-if="showHeader && finalUrl" class="iframe-header">
|
||||
<span class="iframe-title">{{ title }}</span>
|
||||
<el-button
|
||||
text
|
||||
@click="refresh"
|
||||
:icon="RefreshCw"
|
||||
>
|
||||
刷新
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<iframe
|
||||
v-if="iframeUrl"
|
||||
:src="iframeUrl"
|
||||
v-if="finalUrl"
|
||||
ref="iframeRef"
|
||||
:src="finalUrl"
|
||||
class="iframe-content"
|
||||
:class="{ 'with-header': showHeader }"
|
||||
frameborder="0"
|
||||
@load="handleLoad"
|
||||
/>
|
||||
@@ -19,24 +33,62 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { Loader, AlertTriangle } from 'lucide-vue-next'
|
||||
import { Loader, AlertTriangle, RefreshCw } from 'lucide-vue-next'
|
||||
|
||||
interface Props {
|
||||
url?: string // 直接传入的 URL(优先级高于 route.meta)
|
||||
title?: string // 标题
|
||||
showHeader?: boolean // 是否显示头部(带刷新按钮)
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
url: '',
|
||||
title: '',
|
||||
showHeader: false
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
load: []
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
const loading = ref(true)
|
||||
const iframeRef = ref<HTMLIFrameElement>()
|
||||
|
||||
// 从路由 meta 中获取 iframe URL
|
||||
const iframeUrl = computed(() => {
|
||||
return route.meta.iframeUrl as string || ''
|
||||
// 最终的 iframe URL(props.url 优先,否则从 route.meta 获取)
|
||||
const finalUrl = computed(() => {
|
||||
return props.url || (route.meta.iframeUrl as string) || ''
|
||||
})
|
||||
|
||||
function handleLoad() {
|
||||
loading.value = false
|
||||
emit('load')
|
||||
}
|
||||
|
||||
// 刷新 iframe
|
||||
function refresh() {
|
||||
if (iframeRef.value) {
|
||||
loading.value = true
|
||||
iframeRef.value.src = iframeRef.value.src
|
||||
}
|
||||
}
|
||||
|
||||
// 监听 URL 变化,重新加载
|
||||
watch(finalUrl, () => {
|
||||
if (finalUrl.value) {
|
||||
loading.value = true
|
||||
}
|
||||
})
|
||||
|
||||
// 暴露方法供外部调用
|
||||
defineExpose({
|
||||
refresh
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log('[IframeView] 加载 iframe:', iframeUrl.value)
|
||||
console.log('[IframeView] 加载 iframe:', finalUrl.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -46,12 +98,35 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.iframe-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background: var(--el-bg-color);
|
||||
border-bottom: 1px solid var(--el-border-color-light);
|
||||
flex-shrink: 0;
|
||||
|
||||
.iframe-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.iframe-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
flex: 1;
|
||||
|
||||
&.with-header {
|
||||
height: calc(100% - 49px);
|
||||
}
|
||||
}
|
||||
|
||||
.iframe-error {
|
||||
@@ -82,9 +157,18 @@ onMounted(() => {
|
||||
background: var(--el-bg-color);
|
||||
gap: 12px;
|
||||
|
||||
.el-icon {
|
||||
font-size: 32px;
|
||||
.is-loading {
|
||||
animation: rotating 1.5s linear infinite;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -65,29 +65,12 @@
|
||||
<!-- 主内容区 -->
|
||||
<main class="main-content">
|
||||
<!-- iframe 模式 -->
|
||||
<div v-if="currentIframeUrl" class="iframe-container">
|
||||
<div class="iframe-header">
|
||||
<span class="iframe-title">{{ currentMenuItem?.label }}</span>
|
||||
<el-button
|
||||
text
|
||||
@click="handleRefreshIframe"
|
||||
:icon="Refresh"
|
||||
>
|
||||
刷新
|
||||
</el-button>
|
||||
</div>
|
||||
<iframe
|
||||
ref="iframeRef"
|
||||
:src="currentIframeUrl"
|
||||
class="content-iframe"
|
||||
frameborder="0"
|
||||
@load="handleIframeLoad"
|
||||
/>
|
||||
<div v-if="iframeLoading" class="iframe-loading">
|
||||
<Loader :size="20" class="is-loading" />
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
</div>
|
||||
<IframeView
|
||||
v-if="currentIframeUrl"
|
||||
:url="currentIframeUrl"
|
||||
:title="currentMenuItem?.label"
|
||||
:show-header="true"
|
||||
/>
|
||||
|
||||
<!-- 路由模式 -->
|
||||
<router-view v-else />
|
||||
@@ -112,13 +95,9 @@ import {
|
||||
ChevronDown,
|
||||
User,
|
||||
Settings,
|
||||
LogOut,
|
||||
RefreshCw,
|
||||
Loader
|
||||
LogOut
|
||||
} from 'lucide-vue-next'
|
||||
|
||||
// el-button 图标需要传入组件
|
||||
const Refresh = RefreshCw
|
||||
import { IframeView } from '@/components'
|
||||
|
||||
import type { MenuItem } from '@/types/menu'
|
||||
|
||||
@@ -217,8 +196,6 @@ const serviceTitle = computed(() => {
|
||||
// 状态管理
|
||||
const collapsed = ref(false)
|
||||
const activeMenu = ref('home')
|
||||
const iframeLoading = ref(false)
|
||||
const iframeRef = ref<HTMLIFrameElement>()
|
||||
|
||||
// 从 LocalStorage 获取用户名
|
||||
function getUserName(): string {
|
||||
@@ -344,22 +321,6 @@ const handleMenuClick = (item: MenuItem) => {
|
||||
// 所有菜单都通过路由跳转
|
||||
if (item.url) {
|
||||
router.push(item.url)
|
||||
if (item.viewType === 'iframe') {
|
||||
iframeLoading.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iframe 加载完成
|
||||
const handleIframeLoad = () => {
|
||||
iframeLoading.value = false
|
||||
}
|
||||
|
||||
// 刷新 iframe
|
||||
const handleRefreshIframe = () => {
|
||||
if (iframeRef.value) {
|
||||
iframeLoading.value = true
|
||||
iframeRef.value.src = iframeRef.value.src
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,29 +137,12 @@
|
||||
<!-- 主内容区 -->
|
||||
<main class="main-content">
|
||||
<!-- iframe 模式 -->
|
||||
<div v-if="currentIframeUrl" class="iframe-container">
|
||||
<div class="iframe-header">
|
||||
<span class="iframe-title">{{ currentMenuItem?.label }}</span>
|
||||
<el-button
|
||||
text
|
||||
@click="handleRefreshIframe"
|
||||
:icon="Refresh"
|
||||
>
|
||||
刷新
|
||||
</el-button>
|
||||
</div>
|
||||
<iframe
|
||||
ref="iframeRef"
|
||||
:src="currentIframeUrl"
|
||||
class="content-iframe"
|
||||
frameborder="0"
|
||||
@load="handleIframeLoad"
|
||||
/>
|
||||
<div v-if="iframeLoading" class="iframe-loading">
|
||||
<Loader :size="20" class="is-loading" />
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
</div>
|
||||
<IframeView
|
||||
v-if="currentIframeUrl"
|
||||
:url="currentIframeUrl"
|
||||
:title="currentMenuItem?.label"
|
||||
:show-header="true"
|
||||
/>
|
||||
|
||||
<!-- 路由模式 -->
|
||||
<router-view v-else />
|
||||
@@ -177,13 +160,9 @@ import {
|
||||
Server,
|
||||
Monitor,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
RefreshCw,
|
||||
Loader
|
||||
ChevronRight
|
||||
} from 'lucide-vue-next'
|
||||
|
||||
// el-button 刷新图标需要传入组件
|
||||
const Refresh = RefreshCw
|
||||
import { IframeView } from '@/components'
|
||||
|
||||
// ... (rest of the code remains the same)
|
||||
import type { MenuItem } from '@/types/menu'
|
||||
@@ -287,8 +266,6 @@ const serviceTitle = computed(() => {
|
||||
// 状态管理
|
||||
const collapsed = ref(false)
|
||||
const activeMenu = ref('home')
|
||||
const iframeLoading = ref(false)
|
||||
const iframeRef = ref<HTMLIFrameElement>()
|
||||
|
||||
// 从 LocalStorage 获取用户名
|
||||
function getUserName(): string {
|
||||
@@ -488,22 +465,6 @@ const handleMenuClick = (item: MenuItem) => {
|
||||
// 所有菜单都通过路由跳转
|
||||
if (item.url) {
|
||||
router.push(item.url)
|
||||
if (item.viewType === 'iframe') {
|
||||
iframeLoading.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iframe 加载完成
|
||||
const handleIframeLoad = () => {
|
||||
iframeLoading.value = false
|
||||
}
|
||||
|
||||
// 刷新 iframe
|
||||
const handleRefreshIframe = () => {
|
||||
if (iframeRef.value) {
|
||||
iframeLoading.value = true
|
||||
iframeRef.value.src = iframeRef.value.src
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user