|
@@ -1,18 +1,97 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <el-switch v-model="isDark" :active-action-icon="Moon" :inactive-action-icon="Sunny" inline-prompt
|
|
|
|
|
- @change="onToggle" />
|
|
|
|
|
|
|
+ <div class="theme-toggle" @click="onToggle">
|
|
|
|
|
+ <div class="toggle-bg" :class="{ 'right': isDark }">
|
|
|
|
|
+ <el-icon :size="18" class="bg-icon">
|
|
|
|
|
+ <component :is="isDark ? Moon : Sunny" />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="toggle-option" :class="{ 'active': !isDark }">
|
|
|
|
|
+ <el-icon :size="18">
|
|
|
|
|
+ <Sunny />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="toggle-option" :class="{ 'active': isDark }">
|
|
|
|
|
+ <el-icon :size="18">
|
|
|
|
|
+ <Moon />
|
|
|
|
|
+ </el-icon>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { Sunny, Moon } from '@element-plus/icons-vue'
|
|
import { Sunny, Moon } from '@element-plus/icons-vue'
|
|
|
-import { isDark, toggleTheme } from '@/composables/useTheme'
|
|
|
|
|
|
|
+import { isDark } from '@/composables/useTheme'
|
|
|
|
|
|
|
|
function onToggle() {
|
|
function onToggle() {
|
|
|
- // 可选:添加过渡动画
|
|
|
|
|
|
|
+ isDark.value = !isDark.value
|
|
|
document.documentElement.classList.add('theme-transition')
|
|
document.documentElement.classList.add('theme-transition')
|
|
|
- toggleTheme()
|
|
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
document.documentElement.classList.remove('theme-transition')
|
|
document.documentElement.classList.remove('theme-transition')
|
|
|
}, 400)
|
|
}, 400)
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.theme-toggle {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ width: 80px;
|
|
|
|
|
+ height: 36px;
|
|
|
|
|
+ border-radius: 18px;
|
|
|
|
|
+ background: rgba(128, 128, 128, 0.2);
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ user-select: none;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-bg {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 2px;
|
|
|
|
|
+ left: 2px;
|
|
|
|
|
+ width: 30px;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ transition: transform 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ border: 1px solid #F5E4FF;
|
|
|
|
|
+ background: linear-gradient(180deg, rgba(239, 64, 255, 0.50) 0%, rgba(133, 47, 255, 0.50) 100%);
|
|
|
|
|
+ box-shadow: 0 11.392px 22.336px 0 rgba(130, 53, 185, 0.09), 0 -2px 1px 0 rgba(200, 151, 255, 0.40) inset;
|
|
|
|
|
+ backdrop-filter: blur(2px);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-bg.right {
|
|
|
|
|
+ transform: translateX(44px);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-bg .bg-icon {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-option {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ z-index: 2;
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.5);
|
|
|
|
|
+ transition: color 0.3s;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-option.active {
|
|
|
|
|
+ color: transparent;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.toggle-option .el-icon {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|