Como construir mejores componentes de alto nivel (Higher-order components) con el Vue 3

Como construir mejores componentes de alto nivel (Higher-order components) con el Vue 3

El Vue 3 será lanzado pronto con la introducción del API de composición (Composition API). Viene con muchos cambios y mejoras en el rendimiento.

Los componentes de orden superior (HOC o Higher-order components) son componentes que añaden ciertas funcionalidades a su aplicación de forma declarativa utilizando la plantilla. Creo que seguirán siendo muy relevantes incluso con la introducción de la API de composición.

Los HOC siempre han tenido problemas para exponer toda la potencia de su funcionalidad, y como no son tan comunes en la mayoría de las aplicaciones de Vue, a menudo están mal diseñados y pueden introducir limitaciones. Esto se debe a que la plantilla es sólo eso - una plantilla, o un lenguaje restringido en el que se expresa algo de lógica. Sin embargo, en los entornos JavaScript o JSX, es mucho más fácil expresar la lógica porque tienes todo el JavaScript disponible para que lo utilices.

Lo que Vue 3 aporta es la capacidad de mezclar y combinar sin problemas la expresividad de JavaScript utilizando el API de composición y la facilidad declarativa de las plantillas.

Estamos usando activamente HOCs en las aplicaciones que construimos para varias piezas de lógica como red, animaciones, interfaz de usuario y estilo, utilidades y bibliotecas de código abierto. Hay algunos consejos para compartir sobre cómo construir HOCs, especialmente con la próxima API de composición de Vue 3.

La plantilla (template)

Asumamos el siguiente componente de búsqueda (fetch component). Antes de entrar en cómo implementar tal componente, deberías pensar en cómo usarías tu componente. Luego, debes decidir cómo implementarlo. Esto es similar a TDD pero sin las pruebas - es más como jugar con el concepto antes de que funcione.

Lo ideal sería que ese componente utilizara un endpoint y devolviera su resultado como una propriedad de scoped slot:


  

Ahora bien, aunque esta API tiene el propósito básico de buscar algunos datos en la red y mostrarlos, hay muchas cosas que faltan y que sería útil tener.

Empecemos con el manejo de errores. Lo ideal sería poder detectar si se ha producido un error de red o de respuesta y mostrar alguna indicación de ello al usuario. Vamos a esbozar eso en nuestro recorte de uso:


  
{{ error.message }}

Hasta ahora todo bien. ¿Pero qué hay del estado de carga (loading state)? Si seguimos el mismo camino, terminamos con algo como esto:


  
{{ error.message }}
Loading....

Genial. Ahora, asumamos que necesitamos tener soporte de paginación:


  
{{ error.message }}
Loading....

Ves a dónde va esto, ¿verdad? Estamos agregando demasiadas propiedades a nuestro scoped slot predeterminado. En su lugar, vamos a dividirlo en múltiples slots: