Comprendiendo el selector CSS profundo de Vue

Aprenda a usar el selector profundo en Vue, una poderosa herramienta para resolver ciertos problemas de CSS.


CSS puede ser una delicia absoluta o su peor pesadilla, especialmente cuando se trata de componentes que envuelven una serie de componentes secundarios que deben ser diseñados por el padre.

En este artículo exploraremos el deepselector de Vue y por qué puede ser una herramienta poderosa para tener en tu haber.

Por supuesto, el deepselector no es una forma muy común de resolver problemas de inyección de CSS. Hay pocos escenarios reales en los que pueda pensar que se beneficiarán de este enfoque: uno de ellos es modificar el estilo de un componente de biblioteca de terceros. O tal vez incluso establecer reglas CSS específicas para descendientes por componente, que es la que usaremos hoy como ejemplo.

Tenga en cuenta que este enfoque se propagará a TODOS los componentes secundarios, por lo que es algo que debe tener en cuenta. Un buen nombre de clase y una cuidadosa consideración de su estructura CSS son imprescindibles.

Habiendo dicho eso, preparémonos.

Configurar un ejemplo

Para comprender mejor cómo usar el deepselector en Vue, vamos a construir una aplicación de ejemplo muy simple que tendrá algunos <BaseButton>componentes. Estos botones no se diseñarán de ninguna manera en particular, pero cambiarán dependiendo del padre que los contenga.


El primer componente <BaseButton>será un contenedor simple para un HTML <button>. Hay una razón para eso <div>allí, y entraremos en detalles más adelante en el artículo.
    <template>
      <div>
        <button v-on="$listeners">
          <slot/>
        </button>
      </div>
    </template>

Como acordamos, no se establecerá ningún estilo para este botón. Tenga en cuenta que todavía está sujeto a selectores CSS globales que lo modifican, por ejemplo, configurando button { background-color: 'blue'; }sus estilos globales.

El siguiente paso es crear dos padres que usarán este componente de botón en particular. Vamos a hacer que se repitan con a v-fory renderizar tres de ellos por padre, solo por ejemplo.

El primer componente se BlueParentve así.
    <template>
      <div>
        <h1>I is blue</h1>
        <BaseButton v-for="i in 3" :key="`blue${i}`">{{ i }}</BaseButton>
      </div>
    </template>

    <script>
    import BaseButton from "./BaseButton";
    export default {
      components: { BaseButton }
    };
    </script>
Como puede ver, lo estamos importando BaseButtony renderizando en la pantalla tres veces. Eso es.
El siguiente componente será RedParenty se ve así.
<template>
      <div>
        <h1>I is red</h1>
        <BaseButton v-for="i in 3" :key="`red${i}`">{{ i }}</BaseButton>
      </div>
    </template>

    <script>
    import BaseButton from "./BaseButton";
    export default {
      components: { BaseButton }
    };
    </script>

Diseñando a los niños a través de los padres
Vayamos directamente a los negocios. Abra BlueParenty agregue el siguiente código al final del archivo.
  <style scoped>
    div >>> button {
      background-color: lightblue;
    }
    </style>
Hay algunas cosas notables que suceden aquí. Vamos a recorrerlos paso a paso.

En primer lugar, estamos configurando un <style>bloque que se va a abarcar a este componente. Scopedlos estilos se aplican solo a este componente en particular, lo que significa que si tuviéramos que configurar:
    div {
      background-color: black;
    }
Esta div particular, en el interior del BlueParenttendría un color de fondo negro. ¿Por qué no se aplica a todos los divs en la aplicación como de costumbre?

ScopedLos estilos se aplican a los elementos a través de una propiedad de datos. Eso significa que cuando Vue compila su aplicación, inyectará una cadena aleatoria como una datapropiedad a su elemento.

En este caso, nuestro contenedor <div>puede recibir un atributo de datos, como <div data-v-123>.

Una vez que esto se aplica aleatoriamente a cada INSTANCIA de su componente (cada uno será único), Vue crea estilos en su aplicación que apuntan a esto en datalugar de divcomo lo escribió:

   div[data-v-123] {
      background-color: black;
    }
Teniendo esto en cuenta. Pasemos a la siguiente cosa importante en BlueParentel bloque de estilo.
  div >>> button
El triple >>>es lo que se llama un deepselector CSS para Vue. Lo que significa, literalmente, es: "Busque cualquier botón dentro de este div y aplíqueles el siguiente estilo, INCLUSO los que representan los componentes secundarios".

Si agrega esto <BlueParent>a su aplicación ahora y lo mira en el navegador, verá que los tres botones ahora están coloreados de azul en el fondo.

Vamos a experimentar un poco sin embargo. Agregue un simple <button>dentro de la plantilla de BlueParent.

    <template>
      <div>
        <h1>I is blue</h1>
        <BaseButton v-for="i in 3" :key="`blue${i}`">{{ i }}</BaseButton>
        <button>Blue</button>
      </div>
    </template>
Si miras una vez más en el navegador, ¡incluso este nuevo <button>Blue</button>recibirá los estilos!

Una última prueba. Continúe y cambie el código de estilo para reflejar lo siguiente:

  <style scoped>
    .blue > button {
      background-color: lightblue;
    }
    </style>
Ahora que el deepselector se ha ido, y es solo un >selector simple , los estilos ya no se aplicarán a los elementos en su interior <BaseButton>.

Ahora echemos un vistazo <RedParent>.

    <style scoped>
    div /deep/ button {
      background-color: red;
    }
    </style>
En este ejemplo, estamos usando la otra forma de escribir un deepselector. Entonces >>>es lo mismo que /deep/! La razón para tener estas dos formas de declararlo es que, a veces, cuando usa precompiladores, como SASS, pueden tener problemas de comprensión >>>y no podrán compilar su CSS. Si esto sucede, recurra a /deep/.

Una vez más, agregue este componente a su aplicación, ejecútelo en su navegador y verá los tres botones adicionales con el color de fondo rojo.

Sin embargo, una última cosa antes de terminar. ¿Recuerdas que <div>agregamos a <BaseButton>?

Cuando diseñe los componentes seleccionando su elemento ROOT / FIRST, no necesita usar el combinador profundo. ¡Pruébalo! Añadir el class="buttonWrapper"que la envoltura <div>en <BaseButton>.

    <template>
      <div class="buttonWrapper">
        <button v-on="$listeners">
          <slot/>
        </button>
      </div>
    </template>

Ahora regrese a cualquiera de los componentes principales y agregue el siguiente CSS.

   div > .buttonWrapper {
      background-color: yellow;
    }
Verá que div se está apuntando correctamente y su fondo ahora se volverá amarillo.

Terminando
El deepselector no es algo que generalmente se encuentra en la naturaleza en muchos componentes Vue de ejemplo porque es una solución muy específica para un problema muy específico, pero esto abre posibilidades para incluso reducir la cantidad de accesorios que puede necesitar en sus componentes para inyectar diferentes estilos

Si desea ver esto en acción, aquí hay un sandbox de código con el código del artículo: https://codesandbox.io/s/deep-css-example-l1p5e .

Como siempre, gracias por leer, y avíseme en Twitter @marinamosti si alguna vez encontró un ejemplo elegante de usar el deepselector.

Link del texto original Ingles(https://www.telerik.com/blogs/understanding-vue-deep-css-selector)


Comentarios

Entradas populares