Maison  >  Questions et réponses  >  le corps du texte

Comment : Changer le mode sombre à l'aide de TailwindCSS + Vue3 + Vite

Je suis débutant dans Vite/Vue3 et actuellement je suis confronté à un problème où j'ai besoin des connaissances combinées de la communauté.

J'ai créé une application Vite/Vue3 et installé 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

Ensuite, j'ai suivi les instructions sur la page d'accueil de Tailwind :

Ajoutez les chemins de tous les fichiers modèles dans le fichier tailwind.config.js.

Importez le fichier ./src/index.css nouvellement créé dans le fichier ./src/main.js.

Créez un fichier ./src/index.css et ajoutez la couche Tailwind de la directive @tailwind à chaque fichier.

Maintenant, j'ai une application Vite/Vue3/TailwindCSS en cours d'exécution et je souhaite ajouter la possibilité de basculer en mode sombre.

La documentation

Tailwind indique que cela peut être fait en le marquant avec darkMode: 'class' 添加到 tailwind.config.js 来存档,然后将类 dark 切换为 <html>.

J'ai fait le travail en utilisant le code suivant :

  1. Interneindex.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 interne



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

Oui, je sais que ce n'est pas du code de style Vue3. Et oui, je sais que c'est possible d'utiliser element.classList.toggle() 而不是 .remove().add() . Mais peut-être que d'autres débutants comme moi verront cela à l'avenir et apprécieront un code simple pour commencer. Alors s'il vous plaît, ayez pitié...

Maintenant, j'ai enfin une question à poser à la communauté :

Je sais que manipuler le DOM comme ça n'est pas la façon de faire de Vue. Bien sûr, je veux atteindre mes objectifs de la bonne manière. Mais que dois-je faire ?

Croyez-moi, j'ai cherché sur Google pendant des heures et je n'ai pas trouvé de solution qui fonctionne sans installer this et this et this modules npm supplémentaires.

Mais je voulais une approche minimaliste. Compter sur le moins possible pour ne pas me submerger ni submerger les autres qui souhaitent commencer à apprendre.

Avec ceci en toile de fond, avez-vous une solution qui fonctionnerait pour moi et pour d'autres débutants ? :-)

P粉933003350P粉933003350352 Il y a quelques jours687

répondre à tous(1)je répondrai

  • P粉340264283

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

    L'élément cible de votre événement est extérieur à votre candidature. Cela signifie qu'il n'y a aucun moyen d'interagir avec lui autre que de l'interroger via les méthodes disponibles dans le DOM.

    En d'autres termes, vous avez fait la bonne chose . Si l'élément se trouve dans votre application, il vous suffit de lier la classe à votre attribut et de laisser Vue gérer les détails de la manipulation du DOM :

    :class="{ dark: darkMode }"

    Mais ce n’est pas le cas.


    En remarque, il est très important que votre méthode toggle ne dépende pas du fait que l'élément <body> a la classe afin de décider s'il doit être appliqué/supprimé. Vous devez conserver les valeurs enregistrées dans l'état de l'application, qui devraient être votre seule source de vérité.
    C'est le principe de Vue que vous ne voulez pas enfreindre : laissez les données piloter l'état du DOM, et non l'inverse.

    La valeur peut être obtenue à partir de l'état actuel de <body> (une fois installé), mais à partir de ce moment, les modifications apportées à l'état de l'application détermineront si la classe est présente sur l'élément.

    exemple 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
    

    Voir 3 exemple :

    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
    
    

    Évidemment, si vous l'utilisez dans plusieurs composants darkMode 的状态,您可能希望将 darkMode 的状态保留在 data 中的某个外部存储中,而不是本地(并通过 compulated fournissez-le dans votre composant).

    répondre
    0
  • Annulerrépondre