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.
¿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.
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?
Recomendado por LinkedIn
*(sobre este punto en particular probablemente escriba un artículo o publicación en el futuro)
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:
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!
Si consideras que este artículo te ha sido útil o puede serle de utilidad a alguien más, no dudes en compartirlo.