Tengo un proyecto de Vue 2 hecho con Vue CLI, y planeo distribuirlo como una biblioteca, idealmente con las dependencias y la sintaxis de Vue abstraídas por algún tipo de script contenedor. Me gustaría permitir este tipo de interacción:
// mount the component on a plain JS webpage const myComponent = new MyComponent('#my-component'); // handle events from the component in vanilla JS myComponent.on('load', someHandler); // (A.) call a component method and get a return value const processedData = myComponent.process(123); // (B.) access/mutate reactive component data properties myComponent.setMessage('Hello world!');Intenté cambiar el "objetivo de compilación" para compilar una biblioteca o un componente web como se menciona en la documentación de Vue . Puedo montar el componente de la biblioteca sin problemas y manejar eventos, pero no menciona cómo podría interactuar con los datos del componente desde fuera de la VM de Vue (consulte los comentarios A y B ).
¿Cómo puedo acceder a los métodos de los componentes de Vue y a las propiedades de los datos desde fuera de la VM de Vue, en Vanilla JS?
Para acceder a las propiedades (y métodos) del componente Vue fuera de la máquina virtual, puede montarlo con una " referencia de plantilla " como esta:
const vm = new Vue({ components: { MyComponent, }, template: ` <my-component ref="myComponent" /> `, }).$mount('#mount-element");y luego puedes llamar a sus métodos así:
vm.$refs.myComponent.someFunction();Obtendrá los valores devueltos y accederá/mutará las propiedades reactivas dentro de la máquina virtual como se esperaba.
Para usar la sintaxis de clase descrita en la pregunta original, podemos crear una clase simple para envolver el componente vue:
// import the component built by Vue CLI with the "library" build target // (puts `MyComponent` in the global namespace) import './MyComponent.umd.min.js'; import Vue from 'https://unpkg.com/vue@2/dist/vue.esm.browser.min.js'; export default class { constructor(mountElement) { // mount vue VM with a template ref to access its properties const thisClass = this; this.vm = new Vue({ components: { MyComponent, }, template: ` <my-component ref="myComponent" /> `, }).$mount(mountElement); this.component = this.vm.$refs.myComponent; } // define methods that could call this.component's functions someFunction() { // do stuff return this.component.someFunction() } }Parece funcionar bastante bien. Una posible mejora sería construir la biblioteca de componentes con una herramienta diferente, ya que Vue CLI v3 (con proyectos Vue v2) no puede generar archivos de módulos ESM, por lo que lo mejor que podemos hacer es un modelo UMD que se define globalmente.