我如何 access/mutate 来自 vanilla JS 的 Vue 组件属性

How can I access/mutate Vue component properties from vanilla JS

我有一个使用 Vue CLI 制作的 Vue 2 项目,我计划将其作为一个库进行分发,理想情况下是通过某种包装脚本抽象出依赖项和 Vue 语法内容。我想允许这种互动:

// 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!');

我曾尝试更改“构建目标”以构建库或 Web 组件,如 Vue documentation 中所述。我可以很好地挂载库组件并处理事件,但它没有提到我如何与 Vue VM 外部的组件数据交互(参见评论 AB).

如何在普通 JS 中从 Vue VM 外部访问 Vue 组件方法和数据属性?

要在 VM 外部访问 Vue 组件属性(和方法),您可以像这样使用“template ref”挂载它:

const vm = new Vue({
    components: {
        MyComponent,
    },

    template: `
        <my-component
            ref="myComponent"
        />
    `,
}).$mount('#mount-element");

然后你可以这样调用它的方法:

vm.$refs.myComponent.someFunction();

您将获得返回值,并且它将 access/mutate VM 内的反应属性按预期进行。

要使用原始问题中描述的 class 语法,我们可以创建一个简单的 class 来包装 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()
    }

}

它似乎工作得很好。一个可能的改进是使用不同的工具构建组件库,因为 Vue CLI v3(带有 Vue v2 项目)不能输出 ESM 模块文件,所以我们能做的最好的是一个全局定义的 UMD 模块。