在 Vue3 中封装全屏功能 Hook 可以方便地在多个组件中复用全屏逻辑,以下是一个完整的实现方案:
import { ref, onMounted, onUnmounted, onBeforeUnmount } from 'vue';
/**
* 全屏 Hook - 实现指定元素的全屏切换功能
* @param {HTMLElement} targetRef - 要全屏的元素 ref
* @returns {Object} - 包含全屏状态和操作方法的对象
*/
export function useFullscreen(targetRef) {
// 全屏状态
const isFullscreen = ref(false);
// 错误信息
const error = ref('');
// 进入全屏
const enterFullscreen = () => {
const target = targetRef.value;
if (!target) {
error.value = '未找到要全屏的元素';
return;
}
// 兼容不同浏览器的全屏 API
if (target.requestFullscreen) {
target.requestFullscreen()
.catch(err => {
error.value = `进入全屏失败: ${err.message}`;
});
} else if (target.webkitRequestFullscreen) { /* Safari */
target.webkitRequestFullscreen()
.catch(err => {
error.value = `进入全屏失败: ${err.message}`;
});
} else if (target.msRequestFullscreen) { /* IE11 */
target.msRequestFullscreen()
.catch(err => {
error.value = `进入全屏失败: ${err.message}`;
});
} else {
error.value = '浏览器不支持全屏功能';
}
};
// 退出全屏
const exitFullscreen = () => {
if (document.exitFullscreen) {
document.exitFullscreen()
.catch(err => {
error.value = `退出全屏失败: ${err.message}`;
});
} else if (document.webkitExitFullscreen) { /* Safari */
document.webkitExitFullscreen()
.catch(err => {
error.value = `退出全屏失败: ${err.message}`;
});
} else if (document.msExitFullscreen) { /* IE11 */
document.msExitFullscreen()
.catch(err => {
error.value = `退出全屏失败: ${err.message}`;
});
} else {
error.value = '浏览器不支持退出全屏';
}
};
// 切换全屏状态
const toggleFullscreen = () => {
isFullscreen.value ? exitFullscreen() : enterFullscreen();
};
// 监听全屏状态变化
const handleFullscreenChange = () => {
isFullscreen.value = !!(document.fullscreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement);
};
// 组件挂载时添加事件监听
onMounted(() => {
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
document.addEventListener('msfullscreenchange', handleFullscreenChange);
});
// 组件卸载前移除事件监听
onBeforeUnmount(() => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
document.removeEventListener('msfullscreenchange', handleFullscreenChange);
});
return {
isFullscreen,
error,
enterFullscreen,
exitFullscreen,
toggleFullscreen
};
}
使用示例
下面是如何在 Vue 组件中使用这个 Hook 的示例:
<template>
<div class="app-container">
<button @click="toggleFullscreen">
{{ isFullscreen ? '退出全屏' : '进入全屏' }}
</button>
<div ref="targetRef" class="fullscreen-target">
<h3>这是要全屏显示的区域</h3>
<p>全屏后内容会充满整个屏幕</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useFullscreen } from './useFullscreen';
const targetRef = ref(null);
const { isFullscreen, toggleFullscreen } = useFullscreen(targetRef);
</script>
<style>
.fullscreen-target {
width: 100%;
height: 300px;
background-color: #f5f5f5;
padding: 20px;
border: 1px solid #ddd;
}
</style>
功能说明
这个 Hook 实现了以下核心功能:
o 全屏控制:支持进入全屏、退出全屏和切换全屏状态
o 浏览器兼容:处理了不同浏览器(Chrome、Safari、IE11 等)的全屏 API 差异
o 状态监听:自动监听全屏状态变化并更新 isFullscreen 状态
o 错误处理:捕获全屏操作中的错误并提供错误信息
o 生命周期管理:自动添加和移除事件监听,避免内存泄漏