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

我是 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粉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 在您的元件中提供它)。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板