vue 实现Element Plus的炫酷主题切换

效果图

.vue

bash 复制代码
<template>
  <view class="flex-end">
    <div class="wxy-switch" :class="{'wxy-switch-checked':showView}"
    @click="themeSwitch" >
      <div class="wxy-switch-round"></div>
    </div>
  </view>
</template>

<script setup>
import {ref } from 'vue'

const showView = ref(false)

const themeSwitch = (e) => {
  showView.value = !showView.value;
  // 如果不支持 startViewTransition 直接切换
  if (!document.startViewTransition) {
  	document.documentElement.classList.toggle("dark");
  	return
  }

  const transition =  document.startViewTransition(() => {
    document.documentElement.classList.toggle("dark");
  });

  transition.ready.then(() => {
    const { clientX, clientY } = e
    const radius = Math.hypot(
      Math.max(clientX, window.innerWidth - clientX),
      Math.max(clientY, window.innerHeight - clientY)
    )
    
    const isDark = document.documentElement.classList.contains("dark");
    const clipPath = [
      `circle(0px at ${clientX}px ${clientY}px)`,
      `circle(${radius}px at ${clientX}px ${clientY}px)`,
    ]
    document.documentElement.animate(
      { clipPath: isDark ? clipPath.reverse() : clipPath },
      { 
        duration: 500,
        fill: "both",
        pseudoElement: isDark ? "::view-transition-old(root)" : "::view-transition-new(root)"
      }
    )
  });
}
</script>

<style scoped>
.flex-end{
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.wxy-switch{
  --w:40px;
  --h:20px;

  position: relative;
  width: var(--w);
  height: var(--h);
  background-color: #D6D6D6;
  border-radius: 25px;
  transition: background-color 0.3s;
}

.wxy-switch-checked{
  background-color: #39b54a;
}

.wxy-switch-round{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 1.5px;
  width: calc(var(--h) - 3px);
  height: calc(var(--h) - 3px);
  margin: auto 0;
  background: #fff;
  border-radius: 50%;
  transition: left 0.3s;
}

.wxy-switch-checked .wxy-switch-round{
  left: calc(100% - var(--h) + 1.5px);
}
</style>

.css

bash 复制代码
body{
  margin: 0;
}

:root {
  --theme-bg-color: #fff;
  --theme-text-color: #333;
}

:root.dark {
  --theme-bg-color: #333;
  --theme-text-color: #fff;
}

::view-transition-new(root),
::view-transition-old(root) {
  animation: none;
}

.dark::view-transition-old(root) {
  z-index: 9999;
}

#app {
  min-height: 100vh;
  background-color: var(--theme-bg-color);
  color: var(--theme-text-color);
  text-align: center;
  padding: 2rem;
}

div,a{
  box-sizing: border-box;
}

遇到问题可以看我主页加我,很少看博客,对你有帮助别忘记点赞收藏。

相关推荐
一 乐11 分钟前
二手交易平台|基于springboot + vue二手交易平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序
天若有情67324 分钟前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具
vx-程序开发1 小时前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
林语琛1 小时前
我写的 switch…break 被 Babel 偷偷吞了
前端·javascript·babel
liuchangng1 小时前
Jev 模型研究:从生成式大模型到决策式模型——System One、RLCD 校准与采用边界
java·javascript·人工智能·python·深度学习
一 乐2 小时前
养老院管理系统|基于springboot + vue养老院管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
我命由我123453 小时前
CSS - CSS 媒体查询 orientation
前端·javascript·css·html·css3·html5·js
雪芽蓝域zzs4 小时前
第 12 章:一页多图表看板(多 BaseEchart 组件共存,后台首页大屏效果)
vue.js·echars
边境悍匪4 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
志尊宝6 小时前
Vue3 零基础每日笔记(048):嵌套路由与命名视图——后台管理系统布局雏形
前端·javascript·vue.js·笔记·html5