全屏功能组合式函数(useFullscreen)文档

80 阅读4分钟

全屏功能组合式函数(useFullscreen)文档

概述

该函数是 Vue 3 组合式 API 规范的可复用工具,封装了浏览器全屏功能的核心逻辑,提供「进入/退出/切换全屏」的操作方法及响应式状态跟踪,兼容主流浏览器的全屏 API 差异,适用于数据可视化大屏、视频播放、页面预览等需要全屏展示的场景。


import { ref } from 'vue'

export function useFullscreen() {
  // 响应式状态:跟踪当前是否处于全屏模式(默认非全屏)
  const isFullscreen = ref(false)

  /**
   * 进入全屏模式
   * @param element 要全屏的DOM元素,默认值为document.body(整个页面)
   */
  const requestFullscreen = (element = document.body) => {
    if ((element as any)?.requestFullscreen) {
      ;(element as any)?.requestFullscreen() // 标准API
    } else if ((element as any)?.webkitRequestFullScreen) {
      ;(element as any)?.webkitRequestFullScreen() // Chrome/Safari私有API
    } else if ((element as any)?.msRequestFullscreen) {
      ;(element as any)?.msRequestFullscreen() // Edge/IE私有API
    }
  }

  /** 退出全屏模式 */
  const exitFullscreen = () => {
    if (document.exitFullscreen) {
      document.exitFullscreen() // 标准API
    } else if ((document as any)?.webkitExitFullscreen) {
      ;(document as any)?.webkitExitFullscreen() // Chrome/Safari私有API
    } else if ((document as any)?.msExitFullscreen) {
      ;(document as any)?.msExitFullscreen() // Edge/IE私有API
    }
  }

  /**
   * 切换全屏模式
   * @param element 要全屏的DOM元素,默认值为document.body(整个页面)
   */
  const toggleFullscreen = (element = document.body) => {
    if (isFullscreen.value) {
      exitFullscreen()
      isFullscreen.value = false
    } else {
      requestFullscreen(element)
      isFullscreen.value = true
    }
  }

  /** 全屏状态变化时的处理函数(同步响应式状态) */
  const handleFullscreenChange = () => {
    isFullscreen.value = !!(
      document.fullscreenElement || // 标准属性:当前全屏元素(无则为null)
      (document as any)?.webkitFullscreenElement || // Chrome/Safari私有属性
      (document as any)?.msFullscreenElement // Edge/IE私有属性
    )
  }

  // 监听全屏状态变化事件(兼容各浏览器)
  document.addEventListener('fullscreenchange', handleFullscreenChange)
  document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
  document.addEventListener('msfullscreenchange', handleFullscreenChange)

  // 暴露给组件的状态和方法
  return {
    isFullscreen,
    requestFullscreen,
    exitFullscreen,
    toggleFullscreen,
  }
}

核心功能说明

1. 响应式状态

名称类型说明初始值
isFullscreenRef跟踪当前是否处于全屏模式的响应式状态false

2. 核心方法

方法名参数功能描述注意事项
requestFullscreenelement(默认document.body)使指定DOM元素进入全屏模式支持传入具体元素(如图表容器、视频标签)
exitFullscreen退出当前全屏模式无论之前是哪个元素全屏,均通过document退出
toggleFullscreenelement(默认document.body)切换全屏/非全屏状态自动根据当前状态执行进入/退出操作

3. 浏览器兼容性处理

浏览器进入全屏API退出全屏API全屏元素属性状态变化事件
标准浏览器(Firefox等)requestFullscreenexitFullscreenfullscreenElementfullscreenchange
Chrome/SafariwebkitRequestFullScreenwebkitExitFullscreenwebkitFullscreenElementwebkitfullscreenchange
Edge/IE11msRequestFullscreenmsExitFullscreenmsFullscreenElementmsfullscreenchange

4. 状态同步机制

通过监听浏览器原生的全屏状态变化事件(fullscreenchange 及各浏览器私有事件),在事件触发时更新 isFullscreen 状态,确保:

  • 代码操作(调用方法)导致的全屏变化能同步状态
  • 非代码操作(如按 F11、浏览器菜单)导致的全屏变化也能同步状态

组件中使用示例

<template>
  <div class="screen-container">
    <!-- 大屏内容区域 -->
    <div class="dashboard">能源电力数据可视化大屏</div>
    
    <!-- 全屏控制按钮 -->
    <div class="fullscreen-controls">
      <button @click="toggleFullscreen" class="control-btn">
        {{ isFullscreen ? '退出全屏' : '进入全屏' }}
      </button>
      <button @click="requestFullscreen" class="control-btn">单独全屏大屏</button>
      <button @click="exitFullscreen" class="control-btn">强制退出全屏</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useFullscreen } from '@/hooks/useFullscreen'

// 解构获取状态和方法
const { isFullscreen, requestFullscreen, exitFullscreen, toggleFullscreen } = useFullscreen()

// 若需指定仅大屏容器全屏,可传入具体DOM元素
const dashboardRef = ref<HTMLDivElement>(null)
const fullscreenDashboard = () => {
  if (dashboardRef.value) {
    requestFullscreen(dashboardRef.value)
  }
}
</script>

<style scoped lang="less">
.screen-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.dashboard {
  width: 100%;
  height: 100%;
  background: #0f172a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
}

.fullscreen-controls {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  gap: 10px;

  .control-btn {
    padding: 8px 16px;
    background: #165dff;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    &:hover {
      background: #0f48d9;
    }
  }
}
</style>

注意事项

  1. 默认全屏元素:默认使用 document.body 作为全屏元素,避免单个元素全屏时遮挡弹窗、浮层等组件(全屏元素的子元素才会显示在全屏层)。
  2. TypeScript 类型断言:代码中 (element as any)(document as any) 是为了规避私有 API 未被 TS 内置类型定义的报错,不影响功能使用。
  3. 事件监听清理:若在单页应用中使用,建议在组件卸载时移除事件监听(避免内存泄漏),可扩展如下:
    // 新增:返回清理监听的方法
    const cleanup = () => {
      document.removeEventListener('fullscreenchange', handleFullscreenChange)
      document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
      document.removeEventListener('msfullscreenchange', handleFullscreenChange)
    }
    
    return {
      isFullscreen,
      requestFullscreen,
      exitFullscreen,
      toggleFullscreen,
      cleanup // 暴露清理方法
    }
    
    组件中使用:
    import { onUnmounted } from 'vue'
    
    const { cleanup } = useFullscreen()
    onUnmounted(cleanup) // 组件卸载时清理监听
    
  4. 权限限制:部分浏览器在非安全上下文(http 协议,除 localhost 外)下会禁用全屏 API,建议使用 https 协议部署。

适用场景

  • 数据可视化大屏(如能源电力行业监控大屏)全屏展示
  • 视频播放、图片预览等需要沉浸式展示的场景
  • 任何需要一键切换全屏/非全屏的 Vue 3 项目组件