- 作者:老汪软件技巧
- 发表时间:2024-12-14 17:04
- 浏览量:
前言
我们在看一些官网的时候总能看到一些关于暗亮主题切换的功能,比如vue3的官方文档。
Link标签动态引入
Link标签动态引入的优点是- 实现了按需加载,提高了首屏加载时的[性能]缺点是:最开始我们可以准备好几套css主题文件。
我想通过点击灯泡来切换背景颜色
代码实现
"themeIcon" class="iconfont icon-dengpao1"
style="color: red; font-size: 20px">
import { ref, onMounted } from 'vue';
// 定义一个 ref 来引用主题图标
const themeIcon = ref(null);
// 定义当前主题
let currentTheme = ref('blue');
// 定义切换主题的函数
function switchTheme() {
let themeLink = document.getElementById('theme-link');
if (!themeLink) {
// 创建新的 元素
themeLink = document.createElement('link');
themeLink.id = 'theme-link';
themeLink.rel = 'stylesheet';
themeLink.type = 'text/css';
document.head.appendChild(themeLink);
}
// 切换主题样式
if (currentTheme.value === 'blue') {
themeLink.href = new URL('@/css/green-theme.css', import.meta.url).href;
currentTheme.value = 'green';
} else {
themeLink.href = new URL('@/css/blue-theme.css', import.meta.url).href;
currentTheme.value = 'blue';
}
}
// 在组件挂载后添加点击事件监听器
onMounted(() => {
themeIcon.value.addEventListener('click', switchTheme);
});
//首先通过const themeIcon=ref('null')这样我们就引入了一个主题图标。
let currentTheme=ref('blue')
currentTheme:我们再次使用 ref 创建了一个名为 currentTheme 的响应式引用,初始值为 'blue'。这个变量用于跟踪当前的主题(蓝色或绿色),并在切换主题时更新其值。好啦这是基本变量的定义。
接下来就是定义一个 switchTheme函数
function switchTheme() {
let themeLink = document.getElementById('theme-link');
if (!themeLink) {
// 创建新的 元素
themeLink = document.createElement('link');
themeLink.id = 'theme-link';
themeLink.rel = 'stylesheet';
themeLink.type = 'text/css';
document.head.appendChild(themeLink);
}
// 切换主题样式
if (currentTheme.value === 'blue') {
themeLink.href = new URL('@/css/green-theme.css', import.meta.url).href;
currentTheme.value = 'green';
} else {
themeLink.href = new URL('@/css/blue-theme.css', import.meta.url).href; currentTheme.value = 'blue';
}
}
let themeLink = document.getElementById('theme-link');这段代码是用来获取具有id为theme-link的元素。如果该元素不存在的话,那么就创建该元素。并且给它的属性加上id,rel,type。document.head.appendChild(themeLink);用于将新创建的 DOM 元素(如 标签)添加到文档的 部分的方法。
if (currentTheme.value === 'blue'):这行代码检查当前的主题是否为蓝色。如果 currentTheme.value 的值是 'blue',则执行 if 块中的代码,切换到绿色主题;否则,执行 else 块中的代码,切换回蓝色主题。new URL('@/css/green-theme.css', import.meta.url).href
new URL():这是一个构造函数,用于创建一个新的 URL 对象。它接受两个参数:
第一个参数是你要解析的路径(在这个例子中是 @/css/green-theme.css)。
第二个参数是基础 URL(在这个例子中是 import.meta.url),它提供了当前模块的 URL,确保路径解析的正确性。
import.meta.url:这是 Vite 和 Webpack 等现代构建工具提供的一个属性,表示当前模块的 URL。它确保了即使在不同的开发环境中,路径解析也能正确进行。
.href:这是 URL 对象的一个属性,返回完整的 URL 字符串。我们将这个字符串赋值给 themeLink.href,以便浏览器加载相应的 CSS 文件。
最后执行onMounted(() => {
themeIcon.value.addEventListener('click', switchTheme);
});由于组件挂载之前,Vue 可能还没有将模板中的元素渲染到页面中。如果你直接在组件初始化时尝试操作 DOM 元素(例如通过 ref 获取元素),可能会导致 themeIcon.value 为 null 或 undefined,因为此时元素还没有被渲染到页面上。这可以避免这个问题。
提前引入所有主题样式,做类名切换
先提一嘴, 标签中没有使用 scoped 属性的样式会被视为全局样式,这意味着这些样式会应用于整个项目中的所有组件和页面,而不仅仅局限于当前组件。
为了方便使用我将它封装到了
并且:在main.js里边
好啦话不多说我们来看看下边的代码是如何实现的吧
<div class="parent">
<div class="son1">
<div>
<h1 style="display: inline-block; font-size: 20px">Introducing Claude, AI Assistanth1>
<i class="iconfont icon-xiajiantou" style="font-size: 18px">i>
div>
div>
<div class="son2">
<i class="iconfont icon-star" style="font-size: 25px">i>
<i class="iconfont icon-luntaituoyin" style="font-size: 25px">i>
<i class="iconfont icon-xiaoxi" style="font-size: 25px">i>
<i class="iconfont icon-dengpao1" @click="switchTheme" style="color: red; font-size: 20px">i>
div>
div>
<script setup>
import { ref, onMounted } from 'vue';
// 定义当前主题
const currentTheme = ref('light'); // 默认为亮色主题
// 定义切换主题的函数
function switchTheme() {
// 切换主题
const newTheme = currentTheme.value === 'light' ? 'dark' : 'light';
// 使用 classList API 安全地切换类名
document.body.classList.toggle('light', newTheme === 'light');
document.body.classList.toggle('dark', newTheme === 'dark');
// 更新当前主题状态
currentTheme.value = newTheme;
// 打印日志以确认切换
console.log(`Switched to ${newTheme} theme`);
}
// 在组件挂载时设置初始主题
onMounted(() => {
// 确保初始主题正确应用
document.body.classList.add(currentTheme.value);
});
script>
<style lang="scss">
/* 全局样式 */
body {
transition: background-color 0.3s, color 0.3s; /* 添加过渡效果 */
}
/* 亮色主题 */
body.light {
background-color: #fff !important; /* 白色背景 */
color: #333 !important; /* 深灰色文本 */
}
/* 暗色主题 */
body.dark {
background-color: #333 !important; /* 深灰色背景 */
color: #eee !important; /* 浅灰色文本 */
}
/* 特定元素在亮色主题下的样式 */
body.light .box {
color: #f90 !important; /* 橙色文本 */
background: #fff !important; /* 白色背景 */
}
style>
<style lang="scss" scoped>
.parent {
display: flex;
justify-content: flex-end;
align-items: center; /* 垂直居中 */
}
.son1 {
width: 90%;
display: flex;
justify-content: center;
}
.son2 {
display: flex;
width: 10%;
justify-content: space-between;
}
.iconfont {
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
style>
点击后的颜色切换。核心代码是如下:
function switchTheme() {
// 切换主题
const newTheme = currentTheme.value === 'light' ? 'dark' : 'light';
// 使用 classList API 安全地切换类名
document.body.classList.toggle('light', newTheme === 'light');
document.body.classList.toggle('dark', newTheme === 'dark');
// 更新当前主题状态
currentTheme.value = newTheme;
// 打印日志以确认切换
console.log(`Switched to ${newTheme} theme`);
}//递归思想
由于先是const currentTheme = ref('light'); // 默认为亮色主题设置为了亮色主题。当点击后const newTheme = currentTheme.value === 'light' ? 'dark' : 'light';就会设置一个newTheme。document.body.classList.toggle('light', newTheme === 'light');
document.body.classList.toggle('dark', newTheme === 'dark');通过这两段代码来进行类名切换。
currentTheme.value = newTheme;又进行一次重置。