通用管理后台组件库-2-暗黑模式和全屏组件

22 阅读1分钟

1. 暗黑模式组件

说明:使用elementplus暗黑模式集成,给html添加dark样式,同时也可使用vueuse中的usePreferredDark方法,根据系统设备模式设置自动切换暗黑模式。
main.ts

import 'element-plus/theme-chalk/dark/css-vars.css'

main.css

html,
body {
  background-color: var(--el-bg-color);
}

.dark {
  background-color: var(--el-bg-color);
}

切换暗黑模式组件DarkModeTaggle.vue

<template>
  <el-switch
    style="--el-switch-on-color: #333"
    v-model="isDark"
    :active-action-icon="Moon"
    :inactive-action-icon="Sun"
  />
</template>

<script setup lang="tsx">
/**
 *  element-plus设置暗黑模式,在html中添加class=> dark
 * 由于没有使用接口,为了保留用户选择的模式,将状态保存在本地localStorage中,刷新页面后依然有效
 */
// 接受用户传入
const props = defineProps({
  isDark: Boolean
})
// 使用unocss中关联的iconfy图标
const Moon = () => <i class="i-prime:moon" />
const Sun = () => <i class="i-octicon:sun-24" />

// 使用vueuse中的useStorage方法,将状态保存在本地localStorage中
const isDark = useStorage('dark-mode-flag', props.isDark)
// 也可使用vueuse中的usePreferredDark方法,根据系统设备模式设置自动切换暗黑模式
const preferDark = usePreferredDark()

// 切换模式,给html添加class=> dark
function toggleMode(flag: boolean) {
  if (flag) {
    document.documentElement.classList.add('dark')
  } else {
    document.documentElement.classList.remove('dark')
  }
}

// 监听isDark和preferDark的变化,切换模式
watch(
  isDark,
  (val) => {
    nextTick(() => {
      toggleMode(val)
    })
  },
  {
    immediate: true
  }
)
watch(preferDark, (val) => {
  nextTick(() => {
    toggleMode(val)
    isDark.value = val
  })
})
onMounted(() => {
  // 如果用户没有选择模式,则根据系统设置自动切换暗黑模式
  if (typeof isDark.value === 'undefined' && !props.isDark) {
    toggleMode(preferDark.value)
    isDark.value = preferDark.value
  }
})
</script>

<style scoped></style>

实现效果:

image.png

2.全屏组件

说明:使用vueuse中useFullscreen函数实现全屏。
FullScreen.vue组件

<template>
  <component
    :is="tag"
    @click="toggle"
    :class="[!isFullscreen ? 'i-ep:full-screen' : 'i-ri:fullscreen-exit-fill', 'cursor-pointer']"
  ></component>
</template>

<script setup lang="ts">
// 使用vueuse的useFullscreen 实现全屏功能
const { isFullscreen, toggle } = useFullscreen()

// 接受用户传入的标签
const props = defineProps({
  tag: {
    type: String,
    default: 'i'
  }
})
</script>

<style scoped></style>

实现效果:

image.png