使用vue3實(shí)現(xiàn)element-plus的主題切換效果
先看實(shí)現(xiàn)效果
實(shí)現(xiàn)過(guò)程
前提需要引入好 element-plus,并導(dǎo)入element的黑色主題CSS
示例,再 main.js 中引入
import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import 'element-plus/theme-chalk/dark/css-vars.css' // 黑色主題 app.use(ElementPlus, { locale: locale, size: Cookies.get('size') || 'default' })
接著編寫下面的基礎(chǔ)代碼
<template> <div> <el-switch v-model='value1' class='switch' @change='changeSwitch'> <template #active-action> <el-icon> <Moon /> </el-icon> </template> <template #inactive-action> <el-icon> <Sunny /> </el-icon> </template> </el-switch> </div> </template> <script setup> let value1 = ref(false) function changeSwitch() { document.documentElement.classList.toggle('dark') } </script> <style scoped lang='scss'> .switch { position: absolute; left: 200px; top: 200px; } </style>
現(xiàn)在當(dāng)切換 switch 時(shí),背景顏色會(huì)直接進(jìn)行黑白切換
從動(dòng)畫可以看到,現(xiàn)在是沒(méi)有任何過(guò)渡效果的
我們可以使用 document.startViewTransition
很簡(jiǎn)單的就可以加上過(guò)渡效果,document.startViewTransition
接收一個(gè)函數(shù)參數(shù),再函數(shù)內(nèi)部寫上操作DOM的邏輯代碼即可實(shí)現(xiàn)一個(gè)默認(rèn)的過(guò)度效果
function changeSwitch() { document.startViewTransition(() => { document.documentElement.classList.toggle('dark') }) }
現(xiàn)在就有了一個(gè)默認(rèn)的過(guò)渡效果
為什么使用了 document.startViewTransition
就會(huì)有一個(gè)動(dòng)畫效果呢
MDN文檔:Document:startViewTransition() 方法 - Web API | MDN
通過(guò)調(diào)用 API,讓瀏覽器為新舊兩種不同視圖分別捕獲并建立了快照 (即 ::view-transition-old(root)舊快照 和 ::view-transition-new(root) 新快照),而后新舊兩快照在 ::view-transition-image-pair(root) 容器中完成轉(zhuǎn)場(chǎng)動(dòng)畫的過(guò)渡。動(dòng)畫結(jié)束后則刪除其相關(guān)偽元素 (快照和容器)。
我們也可以控制默認(rèn)的動(dòng)畫時(shí)長(zhǎng)
::view-transition-old(root), /* 舊視圖*/ ::view-transition-new(root) { /* 新視圖*/ animation-duration: 2s; }
了解了這些,現(xiàn)在想點(diǎn)擊按鈕,實(shí)現(xiàn)一個(gè)擴(kuò)散圓來(lái)實(shí)現(xiàn)主題切換效果,只需要根據(jù)按鈕位置,計(jì)算圓的半徑,然后設(shè)置 ::view-transition-new(root)
這個(gè)偽元素的動(dòng)畫效果,讓圓從 0% 到 100%即可
完整代碼
<template> <div> <el-switch v-model='isDark' class='switch' ref='switchRef' @change='changeSwitch'> <template #active-action> <el-icon> <Moon /> </el-icon> </template> <template #inactive-action> <el-icon> <Sunny /> </el-icon> </template> </el-switch> </div> </template> <script setup> import { ref } from 'vue' let isDark = ref(false) let switchRef = ref(null) function changeSwitch() { // 創(chuàng)建一個(gè)視圖過(guò)渡動(dòng)畫,用于在切換深色模式時(shí)優(yōu)化用戶體驗(yàn) const transition = document.startViewTransition(() => { // 切換HTML文檔的dark類,以激活或停用深色模式 document.documentElement.classList.toggle('dark') }) // 當(dāng)視圖過(guò)渡動(dòng)畫準(zhǔn)備就緒時(shí)執(zhí)行以下代碼 transition.ready.then(() => { // 獲取switch組件的DOM元素,用于計(jì)算過(guò)渡動(dòng)畫的起點(diǎn) const switchElement = switchRef.value?.$el // 計(jì)算switch組件中心點(diǎn)的坐標(biāo) const rect = switchElement.getBoundingClientRect() const x = rect.left + rect.width / 2 const y = rect.top + rect.height / 2 // 計(jì)算過(guò)渡動(dòng)畫結(jié)束時(shí)的圓半徑,確保覆蓋整個(gè)視口 const endRadius = Math.hypot( Math.max(x, innerWidth - x), Math.max(y, innerHeight - y), ) // 創(chuàng)建clipPath數(shù)組,定義了過(guò)渡動(dòng)畫的起始和結(jié)束形狀 const clipPath = [ `circle(0 at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`, ] // 在HTML文檔的根元素上啟動(dòng)一個(gè)動(dòng)畫,根據(jù)當(dāng)前是否為深色模式來(lái)決定動(dòng)畫的方向 document.documentElement.animate( { clipPath: isDark.value ? clipPath.reverse() : clipPath, }, { duration: 400, // 動(dòng)畫持續(xù)時(shí)間 pseudoElement: isDark.value ? '::view-transition-old(root)' : '::view-transition-new(root)', // 根據(jù)深色模式狀態(tài)選擇偽元素 }, ) }) } </script> <style> ::view-transition-new(root), ::view-transition-old(root) { /* 關(guān)閉默認(rèn)動(dòng)畫,否則影響自定義動(dòng)畫的執(zhí)行 */ animation: none !important; } /*黑暗模式下,讓舊節(jié)點(diǎn)的層級(jí)變高,否則會(huì)導(dǎo)致動(dòng)畫出不來(lái)*/ .dark::view-transition-old(root) { z-index: 100; } </style> <style scoped> .switch { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } </style>
circle 表示畫一個(gè)圓形,更多圖像可參考:clip-path - CSS:層疊樣式表 | MDN
以上就是使用vue3實(shí)現(xiàn)element-plus的主題切換效果的詳細(xì)內(nèi)容,更多關(guān)于vue3 element-plus主題切換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在vue項(xiàng)目中(本地)使用iconfont字體圖標(biāo)的三種方式總結(jié)
這篇文章主要介紹了在vue項(xiàng)目中(本地)使用iconfont字體圖標(biāo)的三種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue虛擬滾動(dòng)/虛擬列表簡(jiǎn)單實(shí)現(xiàn)示例
本文主要介紹了vue虛擬滾動(dòng)/虛擬列表簡(jiǎn)單實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01Element?el-date-picker?日期選擇器的使用
本文主要介紹了Element?el-date-picker?日期選擇器的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04Vue+ElementUI?封裝簡(jiǎn)易PaginationSelect組件的詳細(xì)步驟
這篇文章主要介紹了Vue+ElementUI?封裝簡(jiǎn)易PaginationSelect組件,這里簡(jiǎn)單介紹封裝的一個(gè)Pagination-Select組件幾個(gè)步驟,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08在Vue中使用Avue、配置過(guò)程及實(shí)際應(yīng)用小結(jié)
在項(xiàng)目中遇到通過(guò)點(diǎn)擊加號(hào)實(shí)現(xiàn)輸入框的增加、以及對(duì)該輸入框的輸入內(nèi)容進(jìn)行驗(yàn)證,通過(guò)這些誘導(dǎo)因素創(chuàng)作的這篇文章,本文重點(diǎn)給大家介紹在Vue中使用Avue、配置過(guò)程以及實(shí)際應(yīng)用,需要的朋友可以參考下2022-10-10