Estado compartido (Pinia)¶
Cada isla Vue es su propia app, pero pueden compartir estado reactivo a través de una única instancia de Pinia a nivel de página. Esto es opt-in por diseño: Pinia se carga solo cuando un componente importa un store. El bootstrap de islas instala entonces esa instancia compartida en las islas —pero una página donde ningún componente usa un store no envÃa Pinia en absoluto.
Un módulo de store activa la instancia compartida al importarse (vÃa ensureSharedPinia()), y como todos los stores resuelven contra la misma Pinia activa, cualquier isla que lo importe comparte el estado. ESM nativo, pago por uso.
Requisito: los stores importan
pinia, asà que el tema debe exponerla enexposeNpmPackages(ver Configuración de JS). Si se importa un store sin Pinia expuesta, el build falla de forma ruidosa.
Crear un store compartido¶
Llama a ensureSharedPinia() al inicio de tu módulo de store y define stores como siempre:
Dos islas distintas —por ejemplo un botón de carrito en el header y un cajón de carrito— que ambas hagan import { useUiStore } leen y escriben ahora el mismo estado.
El puente customer-data¶
useCustomerData es un store listo que espeja el contenido privado de Magento (las secciones customer-data: cart, customer, wishlist, compare-products, …) en estado reactivo:
Es read-mostly: el customer-data.js nativo de Magento sigue siendo el dueño del store canónico (localStorage['mage-cache-storage']) y del endpoint /customer/section/load/. El puente lee esa caché, se re-sincroniza cuando Magento emite una actualización, y expone reload() para un refresco explÃcito —asà nunca rompe el Full Page Cache.
| Miembro | Propósito |
|---|---|
sections |
Mapa reactivo de todas las secciones. |
section(name) |
Una sección, o null. |
sync() |
Re-lee el store canónico (se llama solo ante actualizaciones de Magento). |
reload(names = [], { force }) |
Trae secciones de /customer/section/load/ y las fusiona. |
patch(name, partial) |
Fusiona una sección parcial en el mapa reactivo, sólo en memoria. |
snapshot() |
El mapa actual, para poder volver. |
restore(snapshot) |
Lo devuelve. |
Proyectar un cambio antes de que el servidor lo confirme¶
patch existe para que una interacción muestre su resultado de inmediato en vez de esperar el viaje de ida y vuelta — subir summary_count en el momento en que se envÃa un add-to-cart, quitar una fila en el momento en que se toca su papelera.
Es deliberadamente sólo en memoria: nunca escribe en mage-cache-storage. El customer-data.js de Magento sigue siendo el dueño de la caché canónica, asà que una proyección que resulte equivocada muere con la página en vez de sobrevivirle en local storage. snapshot() y restore() son el par que deshace una cuando el servidor rechaza:
Un flujo que recarga la sección después no necesita rollback en absoluto — la recarga sobrescribe la proyección con la verdad. En UI Optimista y Movimiento está el patrón completo y el flag de admin que lo gobierna.
Por qué respeta el FPC¶
Magento sirve páginas cacheadas y carga el contenido privado en el cliente tras el render (vÃa /customer/section/load/, un endpoint no cacheado), asà que los datos por usuario nunca quedan horneados en el HTML cacheado. El puente observa ese flujo en lugar de pelearse con él: lee mage-cache-storage, se suscribe a las emisiones de Magento, y solo el reload() explÃcito toca la red.
Próximos pasos¶
- Configuración de JS — exponer paquetes npm como
piniaal bundle. - Islas Vue — el modelo de app por isla que abarca esta capa de estado.
- UI Optimista y Movimiento — para qué se construyeron
patch,snapshotyrestore.