This commit is contained in:
xingyy 2025-02-26 11:33:50 +08:00
parent 4e6829af0b
commit 743206c277
3 changed files with 95 additions and 63 deletions

View File

@ -1,6 +1,7 @@
<script setup>
import {useI18n} from 'vue-i18n'
import {message} from '@/components/x-message/useMessage.js'
import {hideMinWindow1} from "@/components/floatingBubble/floating.js";
// message.success('success')
useHead({
title: useI18n().t('appSetting.appName'),
@ -23,7 +24,9 @@ const routeHistory = ref([])
router.beforeEach((to, from) => {
//
routeHistory.value.push(from.path)
if (to.path==='/'){
hideMinWindow1()
}
//
if (routeHistory.value.includes(to.path)) {
slideDirection.value = 'slide-right'

View File

@ -1,64 +1,87 @@
/**
* 浮动气泡窗口管理模块
* 提供创建和销毁浮动气泡窗口的功能
*/
import { createApp } from 'vue'
import MinWindow from '@/components/floatingBubble/index.vue'
let minWindowInstance = null
let minWindowApp = null
let container = null
// 全局单例状态管理
let minWindowInstance = null // 组件实例引用
let minWindowApp = null // Vue应用实例
let container = null // DOM容器元素
// 创建悬浮窗
/**
* 创建并显示浮动气泡窗口
* @param {Object} props - 传递给浮动气泡组件的属性
* @returns {Object|null} 返回组件实例或null服务端渲染时
*/
export const showMinWindow1 = (props = {}) => {
if (!process.client) return
// 服务端渲染时直接返回
console.log('!process.client',!process.client)
if (!process.client) return null
// 如果在首页,不创建实例并销毁现有实例
if (window?.$nuxt?.$route?.path === '/') {
hideMinWindow1()
return null
}
// 如果已经存在实例,直接返回该实例
// 如果实例已存在,避免重复创建
if (minWindowInstance) {
return minWindowInstance
}
// 确保清理旧的容器
const existingContainer = document.querySelector('.floating-bubble-container')
if (existingContainer) {
document.body.removeChild(existingContainer)
}
container = document.createElement('div')
container.className = 'floating-bubble-container'
document.body.appendChild(container)
const app = createApp(MinWindow, {
...props
})
minWindowApp = app
minWindowInstance = app.mount(container)
return minWindowInstance
}
export const hideMinWindow1 = () => {
if (!minWindowApp) return
try {
minWindowApp.unmount()
if (container && document.body.contains(container)) {
document.body.removeChild(container)
}
} catch (e) {
console.error('清理浮动气泡时出错:', e)
} finally {
// 确保状态被重置
minWindowApp = null
minWindowInstance = null
container = null
// 额外清理可能残留的容器
// 清理可能存在的残留容器
const existingContainer = document.querySelector('.floating-bubble-container')
if (existingContainer) {
document.body.removeChild(existingContainer)
}
// 创建新的容器元素
container = document.createElement('div')
container.className = 'floating-bubble-container'
document.body.appendChild(container)
// 创建Vue应用实例
const app = createApp(MinWindow, props)
minWindowApp = app
minWindowInstance = app.mount(container)
return minWindowInstance
} catch (error) {
console.error('创建浮动气泡时发生错误:', error)
// 发生错误时确保清理资源
hideMinWindow1()
return null
}
}
/**
* 销毁浮动气泡窗口
* 清理所有相关资源和DOM元素
*/
export const hideMinWindow1 = () => {
console.log('!minWindowApp && !container', !minWindowApp && !container);
if (!minWindowApp && !container) return
try {
// 卸载Vue应用
if (minWindowApp) {
minWindowApp.unmount()
}
// 移除DOM容器
if (container && document.body.contains(container)) {
document.body.removeChild(container)
}
// 清理可能残留的其他容器
const existingContainer = document.querySelector('.floating-bubble-container')
if (existingContainer) {
document.body.removeChild(existingContainer)
}
} catch (error) {
console.error('清理浮动气泡时发生错误:', error)
} finally {
// 重置所有状态
minWindowApp = null
minWindowInstance = null
container = null
}
}

View File

@ -1,23 +1,30 @@
<!--
浮动气泡组件
提供一个可拖拽的浮动按钮支持自定义点击事件和自动销毁功能
-->
<script setup>
import { watch, onUnmounted } from 'vue'
import { hideMinWindow1 } from './floating'
//
const props = defineProps({
/** 点击气泡时的回调函数 */
onClick: {
type: Function,
default: () => {}
},
/** 气泡文本内容 */
text: {
type: String,
default: '回到直播'
}
})
const route = useRoute()
//
watch(() => route.path, (newPath) => {
if (newPath === '/') {
hideMinWindow1()
}
}, { immediate: true })
//
//
//
onUnmounted(() => {
hideMinWindow1()
})
@ -25,20 +32,19 @@ onUnmounted(() => {
<template>
<van-floating-bubble
v-if="route.path !== '/'"
axis="xy"
magnetic="x"
:offset="{ x: 300, y: 50 }"
@click="onClick"
axis="xy"
magnetic="x"
:offset="{ x: 300, y: 50 }"
@click="onClick"
>
回到直播
{{ text }}
</van-floating-bubble>
</template>
<style>
.van-floating-bubble{
.van-floating-bubble {
width: 70px;
height: 70px;
border-radius: 5px!important;
border-radius: 5px!important;
}
</style>