El poder de las directivas personalizadas en Vue | Programar Plus

Cuando inicialmente está aprendiendo un marco de JavaScript, se siente un poco como si fuera un niño en una tienda de golosinas. Usted toma todo lo que está disponible para usted y, de inmediato, hay cosas que le facilitarán la vida como desarrollador. Sin embargo, inevitablemente todos llegamos a un punto en el que trabajamos con un marco en el que tenemos un caso de uso que el marco no cubre muy bien.

Lo hermoso de Vue es que es increíblemente rico en funciones. Pero incluso si tiene un caso de borde que no está cubierto por el marco, también lo respalda, porque puede crear fácilmente una directiva personalizada.

¿Qué son las directivas?

Escribí una publicación aquí sobre directivas en mi guía sobre Vue.js, pero hagamos un repaso.

Las directivas son pequeños comandos que puede adjuntar a elementos DOM. Tienen el prefijo v- para que la biblioteca sepa que está utilizando un marcado especial y para mantener la sintaxis coherente. Por lo general, son útiles si necesita acceso de bajo nivel a un elemento HTML para controlar un poco el comportamiento.

Algunas directivas con las que quizás ya esté familiarizado si ha trabajado con Vue (o Angular, para el caso) son v-if, v-else, v-showetc. Entraremos en algunos de los fundamentos, pero si prefiere leer los ejemplos, puede desplazarse un poco hacia abajo en la página y probablemente aún comprender los conceptos.

A continuación, se muestran algunas formas de utilizar una directiva, junto con una contraparte de ejemplo. Estos ejemplos no son prescriptivos, son solo casos de uso. La palabra ejemplo aquí reemplaza la directiva real.

v-example – esto creará una instancia de una directiva, pero no acepta ningún argumento. Sin pasar un valor, esto no sería muy flexible, pero aún podría colgar alguna parte de la funcionalidad del elemento DOM.

v-example="value" – esto pasará un valor a la directiva, y la directiva determina qué hacer basándose en ese valor.

<div v-if="stateExample">I will show up if stateExample is true</div>

v-example="'string'" – esto le permitirá usar una cadena como expresión.

<p v-html="'<strong>this is an example of a string in some text</strong>'"></p>

v-example:arg="value" – esto nos permite pasar un argumento a la directiva. En el siguiente ejemplo, estamos vinculando a una clase y le damos estilo con un objeto, almacenado por separado.

<div v-bind:class="someClassObject"></div>

v-example:arg.modifier="value" – esto nos permite usar un modificador. El siguiente ejemplo nos permite llamar preventDefault() en el evento de clic.

<button v-on:submit.prevent="onSubmit"></button>

Comprensión de las directivas personalizadas

Ahora que vemos todas las formas en que podemos usar las directivas, analicemos cómo las implementaríamos con una directiva personalizada que nosotros mismos creamos. Un buen ejemplo de algo para lo que podría usar una directiva personalizada es un scroll evento, así que veamos cómo lo escribimos.

En su base, así es como crearíamos una directiva global. (pero no hace nada, ¡todavía!), solo crea la directiva.

Vue.directive('tack');

En el elemento en sí, se vería así:

<p v-tack>This element has a directive on it</p>

Hay algunos ganchos disponibles para nosotros, y cada uno tiene la opción de algunos argumentos. Los ganchos son los siguientes:

  • bind – Esto ocurre una vez que la directiva se adjunta al elemento.
  • inserted – Este gancho ocurre una vez que el elemento se inserta en el DOM principal.
  • update – Este gancho se llama cuando el elemento se actualiza, pero los elementos secundarios aún no se han actualizado.
  • componentUpdated – Este gancho se llama una vez que se han actualizado el componente y los elementos secundarios.
  • unbind – Este gancho se llama una vez que se elimina la directiva.

diagrama de ganchos de directivas

Personalmente, encuentro bind y update el más útil de los cinco.

Cada uno de estos tiene el, binding, y vnode argumentos a su disposición, con la excepción de update y componentUpdated, que también exponen oldVnode, para diferenciar entre el valor anterior pasado y el valor más nuevo.

el, como era de esperar, es el elemento en el que se asienta el enlace. binding es un objeto que contiene argumentos que se pasan a los ganchos. Hay muchos argumentos disponibles, incluidos name, value, oldValue, expression, arg, y modifiers. vnode tiene un caso de uso más inusual, está disponible en caso de que necesite hacer referencia directamente al nodo en el DOM virtual. Ambos binding y vnode debe tratarse como de solo lectura.

Creación de una directiva personalizada

Ahora que lo hemos desglosado, podemos comenzar a ver cómo usaríamos una directiva personalizada en acción. Construyamos a partir de ese primer ejemplo con lo que acabamos de cubrir para que sea más útil:

Vue.directive('tack', {
 bind(el, binding, vnode) {
    el.style.position = 'fixed'
  }
});

Y en el propio HTML:

<p v-tack>I will now be tacked onto the page</p>

Esto está bien, pero no es muy flexible hasta que le pasamos un valor y lo actualizamos o reutilizamos sobre la marcha. Decidamos qué tan lejos de la parte superior nos gustaría fijar el elemento a:

Vue.directive('tack', {
  bind(el, binding, vnode) {
    el.style.position = 'fixed'
    el.style.top = binding.value + 'px'
  }
});
<div id="app">
  <p>Scroll down the page</p>
  <p v-tack="70">Stick me 70px from the top of the page</p>
</div>

Ver la pluma.

Digamos que ahora quería diferenciar entre si desviamos o no los 70 px de la parte superior o la izquierda. Podríamos hacer eso pasando un argumento:

<p v-tack:left="70">I'll now be offset from the left instead of the top</p>
Vue.directive('tack', {
  bind(el, binding, vnode) {
    el.style.position = 'fixed';
    const s = (binding.arg == 'left' ? 'left' : 'top');
    el.style[s] = binding.value + 'px';
  }
});

Ver la pluma.

También puede utilizar más de un valor. Puede hacerlo de la misma manera que lo haría con las directivas regulares:

<p v-tack="{ top: '40', left: '100' }">Stick me 40px from the top of the page and 100px from the left of the page</p>

Y luego la directiva se reescribirá para trabajar con ambos:

Vue.directive('tack', {
  bind(el, binding, vnode) {
    el.style.position = 'fixed';
    el.style.top = binding.value.top + 'px';
    el.style.left = binding.value.left + 'px';
  }
}); 

Ver la pluma.

También podemos escribir algo más complejo donde podemos crear y modificar métodos basados ​​en nuestras directivas personalizadas. Aquí, haremos un ejemplo similar a los puntos de ruta, donde podemos crear una animación que dispara un evento de desplazamiento en particular con una pequeña cantidad de código:

Vue.directive('scroll', {
  inserted: function(el, binding) {
    let f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f);
      }
    };
    window.addEventListener('scroll', f);
  },
});

// main app
new Vue({
  el: '#app',
  methods: {
   handleScroll: function(evt, el) {
    if (window.scrollY > 50) {
      TweenMax.to(el, 1.5, {
        y: -10,
        opacity: 1,
        ease: Sine.easeOut
      })
    }
    return window.scrollY > 100;
    }
  }
});
<div class="box" v-scroll="handleScroll">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque amet harum aut ab veritatis earum porro praesentium ut corporis. Quasi provident dolorem officia iure fugiat, eius mollitia sequi quisquam.</p>
</div>

Ver la pluma.

En estos bolígrafos, mantenemos todo simple para que pueda verlo fácilmente. En una aplicación real, puede crear directivas personalizadas realmente agradables y flexibles disponibles para todo su equipo.

En un proceso de compilación real, colocaría el código de la directiva en el archivo `main.js` que se encuentra en la raíz del directorio` src` (si está usando algo como la compilación Vue-cli) para que `App. vue` y todos los siguientes .vue los archivos del directorio de componentes tendrán acceso a él. También hay otras formas de trabajar con él, pero he descubierto que esta es la implementación más flexible para toda la aplicación.

Si desea obtener más información sobre el marco de Vue, consulte nuestra guía.