Aplicación Nuxt.js desde el kit de interfaz de usuario hasta la implementación. Parte 2: tema oscuro

¡Hola, Habr!



Estamos publicando la segunda parte de una serie de artículos sobre la creación de un blog moderno con Nuxt.js. Hoy implementaremos el tema oscuro en la aplicación que escribimos junto con ustedes en la primera parte .



Tenga en cuenta que el código para cada parte se puede encontrar en su propio hilo en Github , y la master



versión de la aplicación del último artículo publicado está disponible.







¿Qué es el tema oscuro?



Un tema oscuro es un esquema de color para cualquier interfaz que muestra texto claro y elementos de la interfaz sobre un fondo oscuro, lo que facilita la visualización de la pantalla en teléfonos móviles, tabletas y computadoras en condiciones de poca luz. El tema oscuro reduce la luz emitida por la pantalla mientras mantiene la relación de contraste de color mínima necesaria para la legibilidad.



El tema oscuro mejora la ergonomía visual al reducir la fatiga visual al ajustar la pantalla para adaptarse a las condiciones de iluminación actuales y facilitar su uso por la noche o en la oscuridad.



Además, tenga en cuenta que el uso del tema oscuro en aplicaciones web y móviles puede extender la duración de la batería de su dispositivo. Google ha confirmado que el tema oscuro en las pantallas OLED es muy útil para extender la duración de la batería.



@ nuxtjs / modo de color



Para implementar el tema oscuro, usaremos el módulo @ nuxtjs / color-mode , que proporciona las siguientes capacidades:



  • Agrega una clase .${color}-mode



    a la etiqueta <html>



    para facilitar la administración de temas CSS
  • funciona en cualquier modo Nuxt



    ( static



    , ssr



    o spa



    );
  • detecta automáticamente el modo de color del sistema en el dispositivo del usuario y puede establecer el tema apropiado en función de estos datos;
  • le permite sincronizar el tema seleccionado entre pestañas y ventanas;
  • le permite utilizar los temas implementados para páginas individuales en lugar de para toda la aplicación (ideal para desarrollo incremental);
  • el módulo también es compatible con IE9 + (no estoy seguro de si esto sigue siendo relevante en el desarrollo moderno, pero podría ser útil para alguien).


Primero, instalemos el módulo:



npm i --save-dev @nuxtjs/color-mode
      
      





Y luego agregue información sobre este módulo a la sección buildModules



en el archivo nuxt.config.js



:



{
  buildModules: [
    '@nuxtjs/color-mode'
  ]
}
      
      





¡Multa! Ahora bien, si ejecutamos nuestra aplicación y abrimos una pestaña Elements



en la consola del desarrollador, veremos que html



se ha agregado una clase a la etiqueta que corresponde al tema del sistema operativo, por ejemplo, en nuestro caso class="light-mode"



.



Selector de temas



En el siguiente paso, implementemos un interruptor que cambiará el tema oscuro al tema claro y viceversa.



Si miramos el diseño de nuestra aplicación en Figma, podemos ver que junto al selector de temas también hay un selector de idiomas, que implementaremos en uno de los próximos artículos de esta serie.



Escribamos inmediatamente un componente contenedor que encapsulará estos conmutadores y será responsable de los márgenes antes que otros componentes.



Para hacer esto, cree un componente AppOptions



con el siguiente contenido:



<template lang="pug">
section.section
  .content
    .app-options
      switcher-color-mode
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'AppOptions',
})
</script>

<style lang="scss" scoped>
.app-options {
  display: flex;
  margin-top: 24px;
}
</style>
      
      





Componente en Github .



Como podemos ver, no hay lógica en este componente, solo establece márgenes para componentes anidados. Ahora que solo tenemos un componente anidado switcher-color-mode



, implementémoslo.



Echemos un vistazo a la sección de script



este componente:



<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'SwitcherColorMode',

  computed: {
    icon() {
      return (this as any).$colorMode.value === 'light'
        ? 'assets/icons/sun.svg'
        : 'assets/icons/moon.svg'
    },
  },

  methods: {
    changeColorMode() {
      ;(this as any).$colorMode.preference =
        (this as any).$colorMode.value === 'light' ? 'dark' : 'light'
    },
  },
})
</script>
      
      





Aquí estamos implementando un método changeColorMode



que cambia de tema en el objeto proporcionado por el módulo @nuxtjs/color-mode



.



Cuando se cambia el valor $colorMode.preference



, también se establecerá la clase correspondiente de la etiqueta html



: class="light-mode"



o class="dark-mode"



.



Además, hay una propiedad calculada icon



que devuelve el icono que necesitamos, según el tema seleccionado. Tenga en cuenta que para que funcione correctamente es necesario agregar iconos sun.svg



y moon.svg



directorio assets/icons



.



La plantilla de componentes se verá así:



<template lang="pug">
button(@click="changeColorMode")
  img(
    alt="theme-icon"
    :src="getDynamicFile(icon)"
  )
</template>
      
      





¡Aquí todo es bastante sencillo! Tenemos un botón, cuando hacemos clic en el que llamamos a un método changeColorMode



y cambiamos nuestro tema. Dentro del botón, mostramos una imagen del tema seleccionado.



Componente en Github .



Solo queda agregar este componente a la página principal de nuestra aplicación. Después de eso, la plantilla de la página debería verse así:



<template lang="pug">
.page
  section-header(
    title="Nuxt blog"
    subtitle="The best blog you can find on the global internet"
  )

  app-options

  post-list
</template>
      
      





Gestión de variables



Como recordarás de la primera parte, usamos scss



variables para definir todos los colores en la aplicación , y ahora todo lo que tenemos que hacer es cambiar los valores de estas variables en función del tema elegido.



Pero el problema es que las scss



variables se establecen una vez al construir la aplicación, y en el futuro no podemos redefinirlas al cambiar el tema.



Esta limitación se puede eludir con la ayuda js



, pero hay una solución mucho más simple: podemos usar css



variables nativas .



Ahora en nuestro archivo con variables, la assets/styles/variables.scss



sección con colores se ve así:



// colors  
$text-primary:                      rgb(22, 22, 23);  
$text-secondary:                    rgb(110, 109, 122);  
$line-color:                        rgb(231, 231, 233);  
$background-color:                  rgb(243, 243, 244);  
$html-background-color:             rgb(255, 255, 255);
      
      





Primero definamos dos esquemas de color en el mismo archivo, claro y oscuro, usando css



variables:



:root {
  // light theme
  --text-primary:                   rgb(22, 22, 23);  
  --text-secondary:                 rgb(110, 109, 122);  
  --line-color:                     rgb(231, 231, 233);  
  --background-color:               rgb(243, 243, 244);  
  --html-background-color:          rgb(255, 255, 255);  
  
  // dark theme  
  &.dark-mode {
    --text-primary:                 rgb(250, 250, 250);  
    --text-secondary:               rgb(188, 187, 201);  
    --line-color:                   rgb(45, 55, 72);  
    --background-color:             rgb(45, 55, 72);  
    --html-background-color:        rgb(26, 32, 44);  
  }  
}
      
      





Hemos definido las css



variables en el selector :root



. De forma estándar, una css



variable se especifica y se usa con un prefijo --



. Leer



acerca css



pseudo clase:root



de MDN y W3Schools . Cita de MDN



: la



css



pseudoclase :root



encuentra el elemento raíz del árbol del documento. Se aplica a HTML, :root



encuentra una etiqueta html



y es idéntico al selector de etiquetas html, pero su especificidad es mayor.



Como podemos ver, aquellos colores que antes estaban escritos directamente en scss



las variables ahora se especifican en css



variables como valores predeterminados, y si una clase está presente, .dark-mode



estos valores se anulan.



Ahora nuestras scss



variables de color se verán así:



$text-primary:                      var(--text-primary);  
$text-secondary:                    var(--text-secondary);  
$line-color:                        var(--line-color);  
$background-color:                  var(--background-color);  
$html-background-color:             var(--html-background-color);
      
      





Al cambiar de tema, el esquema de color cambiará de acuerdo con los valores dados y no necesitamos cambiar nada en los componentes ya implementados.



Conclusión



Gracias a este artículo, aprendimos cómo implementar un tema oscuro para una aplicación Nuxt.js.



¿Conseguiste completar todos los pasos? ¿Crees que el tema oscuro es solo una exageración o es una necesidad? Comparte tu opinión en los comentarios.



Enlaces a materiales requeridos:






All Articles