Vue3: La versatilidad de <​slot>

Vue3: La versatilidad de <slot>

¿Estás usando Vue slots adecuadamente? ¿Los has usado alguna vez?

Te aseguro que después de leer este artículo los usarás más seguido -o comenzarás a usarlos-.

Nota: los ejemplos de este artículo utilizan la sintaxis de Vue3 <script setup>, pero toda la funcionalidad que encontrarás aquí está disponible también en Vue2, con los necesarios cambios en el <script> (por ejemplo, tendrás que usar la función data() en tus componentes).

¿Qué es <slot>?

El tag <slot> es una manera de comunicarse y enviar información de un componente padre a un componente hijo y viceversa directamente desde el <template>, sin necesidad de props, emits, provide/inject o algún sistema de state management tipo Vuex. Nótese que he resaltado "y viceversa" porque direccionar la data desde el componente hijo al padre puede resultar muy versátil y es una de las funcionalidades que más me gusta de los slots.

Vue slots - implementación básica

¿Por qué usar slots?

De entrada, hay que aclarar que para un mismo fin pueden usarse diversas herramientas. Por ejemplo, un componente puede definir props y recibir los datos que necesarios para su correcta renderización. Además los props pueden ser tanto obligatorios como opcionales, y el componente utilizará unos y otros según lo requiera.

Vue - provide/inject

En los casos en los que datos van a ser consumidos no sólo por el componente hijo sino por algún componente de algún estrato inferior (por ejemplo un componente nieto), podemos hacer uso de las funciones provide() inject(). En este caso el ancestro común a todos los componentes que consumirán la data la declara y provee y el descendente que la requiera la inyecta incluso si su ascendente directo no la utiliza:

Y, por supuesto, siempre tendremos la opción de utilizar alguna herramienta de state managment como Vuex o Pinnia, o incluso definir nuestros propios composables para consumir y manejar estados a todo lo largo y ancho de nuestra aplicación.

Entonces, ¿por qué usar slots?

  • El <slot> nos permite embeber a un componente hijo datos arbitrarios cuando no han sido definidos por este, como sería el caso de los props.
  • Los datos enviados a través de props son inmutables, y esto marca una diferencia fundamental con provide/inject, ya que a través de estos métodos los datos mantienen su reactividad; de ahí que, si bien no es recomendable*, el componente que injecta los datos puede modificarlos.

*(sobre este punto en particular probablemente escriba un artículo o publicación en el futuro)

  • Mediante el uso de props podemos embeber en del componente hijo elementos que no han sido definidos por él (incluso otros componentes).

Y, si todo lo anterior no te resulta suficiente, la siguiente característica te convencerá de que, bien utilizados, los slots son una herramienta muy versátil:

  • Los slots funcionan de forma bidireccional: pueden enviarse datos e incluso funciones desde el componente padre al componente hijo y viceversa.

Vue slots - passing data from child to parent

Quizás estén pensando que la funcionalidad de la imagen anterior puede lograrse vía emits, y es cierto. Pero ¿qué pasaría si el componente que transfiere la función no es el hijo sino un nieto -o peor aún algún componente más abajo en la línea-? A no ser por los slots, habría que definir una cadena de emits que fácilmente pueden llevar a bugs.

La otra opción, claro está, es resolver el asunto con alguna herramienta de state management o composables, pero en el primero de los casos requerirá añadir una librería completa únicamente para manejar un estado. Y, por rápidas que sean las librerías para manejo de estados, más rápido será no tenerlas en nuestra pequeña app. En el segundo de los casos -resolver nuestra necesidad vía composables- requeriría definirlos y exportarlos para luego importarlos e implementarlos. Tanto en uno como en otro caso, nuestra app sumaría algunas líneas de código que los slots resuelven fácilmente.

Entonces ¿debes usar slots en lugar de herramientas de state managment y provide/inject?

No, por supuesto que no. Cada herramienta tiene su valor y cada desarrollador utiliza las que considera necesarias para su proyecto. Como dijimos, para cada problema hay diversas soluciones, acá simplemente quise exponer una de ellas, que quizás esté siendo subutilizada.

¡Hasta pronto!

Daniel Almenar Williams

Si consideras que este artículo te ha sido útil o puede serle de utilidad a alguien más, no dudes en compartirlo.

Inicia sesión para ver o añadir un comentario.

Otros usuarios han visto

Ver temas