web会议聊天

This commit is contained in:
2025-12-27 11:29:52 +08:00
parent 545153fd01
commit 0f985ae8e8
5 changed files with 64 additions and 10 deletions

View File

@@ -16,10 +16,14 @@
v-if="finalUrl"
ref="iframeRef"
:src="finalUrl"
:key="iframeKey"
class="iframe-content"
:class="{ 'with-header': showHeader }"
frameborder="0"
allow="camera; microphone; fullscreen; display-capture; autoplay"
allowfullscreen
@load="handleLoad"
@error="handleError"
/>
<div v-else class="iframe-error">
<AlertTriangle :size="48" class="error-icon" />
@@ -33,7 +37,7 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { ref, computed, onMounted, watch, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { Loader, AlertTriangle, RefreshCw } from 'lucide-vue-next'
@@ -41,21 +45,26 @@ interface Props {
url?: string // 直接传入的 URL优先级高于 route.meta
title?: string // 标题
showHeader?: boolean // 是否显示头部(带刷新按钮)
timeout?: number // 加载超时时间(毫秒),默认 10000
}
const props = withDefaults(defineProps<Props>(), {
url: '',
title: '',
showHeader: false
showHeader: false,
timeout: 10000
})
const emit = defineEmits<{
load: []
error: [error: string]
}>()
const route = useRoute()
const loading = ref(true)
const iframeRef = ref<HTMLIFrameElement>()
const iframeKey = ref(0)
let loadTimeout: number | null = null
// 最终的 iframe URLprops.url 优先,否则从 route.meta 获取)
const finalUrl = computed(() => {
@@ -63,22 +72,54 @@ const finalUrl = computed(() => {
})
function handleLoad() {
clearLoadTimeout()
loading.value = false
console.log('[IframeView] iframe 加载完成')
emit('load')
}
function handleError(e: Event) {
clearLoadTimeout()
loading.value = false
console.error('[IframeView] iframe 加载错误:', e)
emit('error', 'iframe 加载失败')
}
function clearLoadTimeout() {
if (loadTimeout) {
clearTimeout(loadTimeout)
loadTimeout = null
}
}
function startLoadTimeout() {
clearLoadTimeout()
// 设置超时,如果超时后仍在加载,则隐藏加载状态
// 因为某些情况下 iframe 的 load 事件可能不会触发
loadTimeout = window.setTimeout(() => {
if (loading.value) {
console.warn('[IframeView] iframe 加载超时,隐藏加载状态')
loading.value = false
}
}, props.timeout)
}
// 刷新 iframe
function refresh() {
if (iframeRef.value) {
loading.value = true
iframeRef.value.src = iframeRef.value.src
iframeKey.value++ // 通过改变 key 强制重新渲染 iframe
startLoadTimeout()
}
}
// 监听 URL 变化,重新加载
watch(finalUrl, () => {
if (finalUrl.value) {
watch(finalUrl, (newUrl) => {
if (newUrl) {
loading.value = true
iframeKey.value++ // 强制重新渲染
startLoadTimeout()
console.log('[IframeView] URL 变化,重新加载:', newUrl)
}
})
@@ -89,6 +130,13 @@ defineExpose({
onMounted(() => {
console.log('[IframeView] 加载 iframe:', finalUrl.value)
if (finalUrl.value) {
startLoadTimeout()
}
})
onUnmounted(() => {
clearLoadTimeout()
})
</script>