index.vue 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <script lang="ts" setup>
  2. import { computed, ref, watchEffect } from "vue"
  3. import { ElMessage } from "element-plus"
  4. import screenfull from "screenfull"
  5. interface Props {
  6. /** 全屏的元素,默认是 html */
  7. element?: string
  8. /** 打开全屏提示语 */
  9. openTips?: string
  10. /** 关闭全屏提示语 */
  11. exitTips?: string
  12. /** 是否只针对内容区 */
  13. content?: boolean
  14. }
  15. const props = withDefaults(defineProps<Props>(), {
  16. element: "html",
  17. openTips: "全屏",
  18. exitTips: "退出全屏",
  19. content: false
  20. })
  21. //#region 全屏
  22. const isFullscreen = ref<boolean>(false)
  23. const fullscreenTips = computed(() => {
  24. return isFullscreen.value ? props.exitTips : props.openTips
  25. })
  26. const fullscreenSvgName = computed(() => {
  27. return isFullscreen.value ? "fullscreen-exit" : "fullscreen"
  28. })
  29. const handleFullscreenClick = () => {
  30. const dom = document.querySelector(props.element) || undefined
  31. screenfull.isEnabled ? screenfull.toggle(dom) : ElMessage.warning("您的浏览器无法工作")
  32. }
  33. const handleFullscreenChange = () => {
  34. isFullscreen.value = screenfull.isFullscreen
  35. }
  36. watchEffect((onCleanup) => {
  37. // 挂载组件时自动执行
  38. screenfull.on("change", handleFullscreenChange)
  39. // 卸载组件时自动执行
  40. onCleanup(() => {
  41. screenfull.isEnabled && screenfull.off("change", handleFullscreenChange)
  42. })
  43. })
  44. //#endregion
  45. //#region 内容区
  46. const isContentLarge = ref<boolean>(false)
  47. const contentLargeTips = computed(() => {
  48. return isContentLarge.value ? "内容区复原" : "内容区放大"
  49. })
  50. const contentLargeSvgName = computed(() => {
  51. return isContentLarge.value ? "fullscreen-exit" : "fullscreen"
  52. })
  53. const handleContentLargeClick = () => {
  54. document.body.className = !isContentLarge.value ? "content-large" : ""
  55. isContentLarge.value = !isContentLarge.value
  56. }
  57. //#endregion
  58. </script>
  59. <template>
  60. <div>
  61. <!-- 全屏 -->
  62. <el-tooltip v-if="!content" effect="dark" :content="fullscreenTips" placement="bottom">
  63. <SvgIcon :name="fullscreenSvgName" @click="handleFullscreenClick" />
  64. </el-tooltip>
  65. <!-- 内容区 -->
  66. <el-dropdown v-else>
  67. <SvgIcon :name="contentLargeSvgName" />
  68. <template #dropdown>
  69. <el-dropdown-menu>
  70. <!-- 内容区放大 -->
  71. <el-dropdown-item @click="handleContentLargeClick">{{ contentLargeTips }}</el-dropdown-item>
  72. <!-- 内容区全屏 -->
  73. <el-dropdown-item @click="handleFullscreenClick" :disabled="isFullscreen">内容区全屏</el-dropdown-item>
  74. </el-dropdown-menu>
  75. </template>
  76. </el-dropdown>
  77. </div>
  78. </template>
  79. <style lang="scss" scoped>
  80. .svg-icon {
  81. font-size: 20px;
  82. &:focus {
  83. outline: none;
  84. }
  85. }
  86. </style>