搜尋

首頁  >  問答  >  主體

操作方法:使用 TailwindCSS + Vue3 + Vite 切換深色模式

我是 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



  2. #
<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 內部



  2. #
<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粉933003350P粉933003350414 天前752

全部回覆(1)我來回復

  • P粉340264283

    P粉3402642832023-11-02 09:11:13

    您的事件的目標元素位於您的應用程式之外。這意味著除了透過 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 在您的元件中提供它)。

    回覆
    0
  • 取消回覆