Acceder a una referencia dentro de un slot en Vue.js

Para facilitar las operaciones CRUD de elementos en mis aplicaciones, que son de lejos lo más aburrido que hay, me he creado un componente que tiene toda la funcionalidad y que se personaliza en cada caso con algunas variables de estado y dos slots, uno para la tabla de visualización de datos y otro para la ventana de creación / edición.

Al intentar que cuando se abra la ventana de creación / edición el foco se ponga en el campo del nombre me he encontrado un problema: no sabía cómo acceder a una referencia definida fuera de nuestro componente e inyectada como un slot. Para ello, si nuestro slot se llama por ejemplo editDialog y queremos localizar el elemento que tiene como referencia crudFocus deberemos hacerlo así:

this.$scopedSlots.editDialog()[0].context.$refs.crudFocus

Cómo refrescar un componente dinámico en Vue.js

Estoy haciendo un interfaz con Vue.js que utiliza pestañas para tener varias vistas abiertas a la vez. Esto se consigue metiendo un componente dinámico dentro de un keep-alive de forma que al ir cambiando el componente los datos se mantengan.

El problema es cómo mantener la coherencia entre las distintas pestañas. Si por ejemplo en una tengo abierto el editor de usuarios y en otra tengo el editor de permisos de los usuarios nos surgen los siguientes problemas:

  • En el editor de usuarios creo un nuevo usuario, y al irme a la pestaña de permisos para asignarle permisos no me aparece en el desplegable, causando confusión y quebranto en quien esté usando la aplicación.
  • Peor aún, en el editor de permisos puedo haber seleccionado un usuario y posteriormente haberme ido a la pestaña de usuarios y eliminarlo. En la pestaña de permisos puedo enviar datos de permisos para un usuario que ya no existe.

Para solucionar el primer problema lo que hago es guardar en el estado del componente principal una lista con los nombres de los componentes que deben ser recargados. Por recargado se entiende que no debemos crearlo de nuevo, debemos mantener su estado, y simplemente hay que llamar a su método de carga de datos, que incluirá el nuevo usuario.

Todos mis componentes implementan el método activated (que específicamente se llama cuando un componente inactivo en un keep-alive se activa) y en él se comprueba si el componente está en la lista de recarga, si es así recarga los datos.

Pero en el segundo problema no nos basta con recargar los datos, querremos reiniciar completamente el componente para evitar que se mantenga un estado con un usuario que ya no existe. Esto es lo que más quebraderos de cabeza me ha dado, y me he tirado toda la tarde probando cosas sin éxito hasta que he visto en el manual de Vue lo siguiente:

exclude - string or RegExp or Array. Any component with a matching name will not be cached.

En el momento en el que metemos en ese atributo el nombre de un componente Vue deja de cachearlo, eliminándolo en ese mismo momento y haciendo por tanto que la próxima vez que lo carguemos en nuestro componente contenedor se cree desde cero, que es lo que queríamos.

Hay que acordarse de quitar el nombre del componente de exclude después de volverlo a cargar para que se mantenga en el caché hasta que queramos de nuevo invalidarlo.