Si eres fan de Vue.js como yo, seguramente has creado componentes reutilizables una y otra vez. Pero… ¿alguna vez te preguntaste cómo compartir tus componentes Vue fuera de una app Vue? ¿Qué pasaría si pudieras usarlos en React, Angular o incluso en HTML puro? La respuesta está en los Web Components y Vue tiene una herramienta poderosa para eso: defineCustomElement. Hoy te voy a contar cómo Vue y los Web Components pueden ser mejores amigos. Te prometo que al final vas a querer probarlo en tu próximo proyecto (o experimento).
)
Un Web Component es básicamente un componente hecho con estándares del navegador. Vive felizmente en cualquier parte: no necesita que uses un framework específico. Son componentes nativos, encapsulados y portables.
YouTube usa Web Components para renderizar botones, menús y otros elementos interactivos de su UI.
Google utiliza Web Components internamente en muchos de sus productos, incluyendo partes de Gmail y Google Maps, gracias a su librería Lit.
Salesforce, IKEA, y Adobe también han adoptado este enfoque para crear design systems compartidos entre múltiples equipos y stacks tecnológicos distintos.
defineCustomElement al rescateVue ofrece una función muy poderosa llamada defineCustomElement, que te permite registrar tu componente como un elemento personalizado del navegador. Así, puedes usarlo como <mi-componente></mi-componente> en cualquier HTML.
Veamos un ejemplo básico:
// MyComponent.ce.ts
import { defineCustomElement } from 'vue'
import MyComponent from './MyComponent.vue'
const MyCustomElement = defineCustomElement(MyComponent)
customElements.define('mi-componente', MyCustomElement)Ahora puedes usar <mi-componente></mi-componente> en cualquier parte, sin importar si estás en una app Vue o no.
En empresas grandes o proyectos legacy, es común ver entornos con:
Páginas construidas en PHP o Django
Apps hechas con React, Angular y Vue
Widgets aislados en jQuery
Y muchas veces... todo junto al mismo tiempo 
Aquí es donde los Web Components brillan: puedes crear un componente de Vue 3, empacarlo con defineCustomElement, y luego usarlo como si fuera HTML en cualquier página, sin importar la tecnología que tenga debajo.
¿Quieres un dropdown con lógica avanzada en una app legacy que no puedes migrar aún? Créalo con Vue, expórtalo como Web Component, y reutilízalo en toda tu plataforma.
Reactividad de Vue
Ciclo de vida completo (onMounted, onUpdated, etc.)
Composición con setup
Slots, props, y eventos personalizados
defineCustomElement:Vue ahora permite configurar detalles específicos al momento de crear tu Web Component:
defineCustomElement(MyComponent, {
shadowRoot: false, // ❌ No encapsula con Shadow DOM
styles: [/* CSS inyectado */],
configureApp(app) {
// configuración personalizada del app Vue
},
})Por defecto, Vue encapsula tu componente usando Shadow DOM, lo que protege tus estilos de interferencias externas. Pero si necesitas mayor integración con estilos globales (por ejemplo, para heredar estilos de un CMS o diseño corporativo), puedes desactivarlo:
const MyCustomElement = defineCustomElement(MyComponent, {
shadowRoot: false
})Ten en cuenta que al desactivarlo, los estilos en tu SFC (<style>) ya no estarán aislados.
Crear un design system agnóstico de framework, que puedas usar en cualquier producto de tu empresa.
Inyectar componentes Vue en un CMS que solo permite HTML o JS (como WordPress).
Agregar funcionalidades modernas en apps legacy sin necesidad de migrar todo.
Empaquetar tus widgets como componentes distribuidos para terceros, sin obligarles a usar Vue.
Con defineCustomElement, Vue se vuelve aún más versátil. Ya no es solo para tus SPA, también puede ser parte de páginas estáticas, CMS, otras apps... y sin pedir permiso.
Vue ahora habla Web Components, y eso lo convierte en una herramienta ideal para equipos modernos, proyectos híbridos y soluciones verdaderamente escalables.