操作方法:使用 TailwindCSS + Vue3 + Vite 切换深色模式
P粉933003350
P粉933003350 2023-11-01 12:05:00
0
1
746

我是 Vite/Vue3 的初学者,目前我面临一个问题,我需要社区的综合知识。

我创建了一个 Vite/Vue3 应用程序并安装了 TailwindCSS:

npm create vite@latest my-vite-vue-app -- --template vue
cd my-vite-vue-app
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

然后我按照 Tailwind 主页上的说明进行操作:

在 tailwind.config.js 文件中添加所有模板文件的路径。

将新创建的 ./src/index.css 文件导入到 ./src/main.js 文件中。

创建一个 ./src/index.css 文件并为每个文件添加 @tailwind 指令Tailwind 的图层。

现在我有一个正在运行的 Vite/Vue3/TailwindCSS 应用程序,并且想要添加切换暗模式的功能。

Tailwind 文档表示,可以通过将 darkMode: 'class' 添加到 tailwind.config.js 来存档,然后将类 dark 切换为 <html> 标记。

我使用以下代码完成了这项工作:

  1. 内部index.html



<html lang="en" id="html-root">
  (...)
  <body class="antialiased text-slate-500 dark:text-slate-400 bg-white dark:bg-slate-900">
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
  1. About.vue 内部



<template>
  <div>
    <h1>This is an about page</h1>
    <button @click="toggleDarkMode">Toggle</botton>
  </div>
</template>

<script>
  export default {
    methods: {
      toggleDarkMode() {
        const element = document.getElementById('html-root')
        if (element.classList.contains('dark')) {
          element.classList.remove('dark')
        } else {
          element.classList.add('dark')
        }
      },
    },
  };
</script>

是的,我知道这不是 Vue3 风格的代码。而且,是的,我知道可以使用 element.classList.toggle() 而不是 .remove().add() 。但也许像我这样的其他初学者将来会看到这一点,并且会感激一些简单的代码开始。所以请大家怜悯……

现在我终于要问社区的问题了:

我知道像这样操作 DOM 不是 Vue 的做事方式。当然,我想以正确的方式实现我的目标。 但是我该怎么做呢?

相信我,我在 google 上搜索了好几个小时,但没有找到一个无需安装这个和这个以及这个额外 npm 模块即可工作的解决方案。

但我想要一种极简主义的方法。尽可能少的依赖,以免让我和其他想要开始学习的人不知所措。

以此为背景 - 你们有适合我和其他新手的解决方案吗? :-)

P粉933003350
P粉933003350

全部回复(1)
P粉340264283

您的事件的目标元素位于您的应用程序之外。这意味着除了通过 DOM 可用方法查询它之外,没有其他方法可以与其交互。

换句话说,你做得对。 如果该元素位于应用程序内,那么您只需将类链接到您的属性并让 Vue 处理 DOM 操作的细节:

:class="{ dark: darkMode }"

但事实并非如此。


作为旁注,非常重要您的切换方法不依赖于 <body> 元素是否具有该类,以便决定是否应该应用它/删除。您应该将保存在应用程序状态中的值保留下来,这应该是您唯一的事实来源。
这就是您不希望破坏的 Vue 原则:让数据驱动 DOM 状态,而不是相反。

可以从 <body> 的当前状态获取值(安装时),但从那时起,对应用程序状态的更改将决定该类是否存在于元素上。

vue2 示例:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    darkMode: document.body.classList.contains('dark')
  }),
  methods: {
    applyDarkMode() {
      document.body.classList[
        this.darkMode ? 'add' : 'remove'
      ]('dark')
    }
  },
  watch: {
    darkMode: 'applyDarkMode'
  }
})
body.dark {
  background-color: #191919;
  color: white;
}
sssccc

视图3示例:

const {
  createApp,
  ref,
  watchEffect
} = Vue;

createApp({
  setup() {
    const darkMode = ref(document.body.classList.contains('dark'));
    const applyDarkMode = () => document.body.classList[
      darkMode.value ? 'add' : 'remove'
    ]('dark');
    watchEffect(applyDarkMode);
    return { darkMode };
  }
}).mount('#app')
body.dark {
  background-color: #191919;
  color: white;
}
sssccc

显然,如果您在多个组件中使用 darkMode 的状态,您可能希望将 darkMode 的状态保留在 data 中的某个外部存储中,而不是本地(并通过 compulated 在您的组件中提供它)。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板