如何从 index.html 向 Vue.js 3 实例发送消息?

Posted

技术标签:

【中文标题】如何从 index.html 向 Vue.js 3 实例发送消息?【英文标题】:How to send a message from index.html to Vue.js 3 instance? 【发布时间】:2021-02-09 03:07:37 【问题描述】:

所以,想象一下 Vue index.html 也会加载一些自定义脚本:

<!DOCTYPE html>
<html lang="en">
<head>
    ...
    ...
    <script type="text/javascript">
    languagePluginLoader.then(function () 
        pyodide.loadPackage("someName").then(() => 
            // Send message to Vue that everything is fine
        ).catch((err) => 
            // Send message to Vue that it failed
        )
    )
    </script>
    ...
    ...
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

有没有办法通过index.html 文件与正在运行的 Vue 实例或/和 Vuex 进行通信?例如,我想在脚本完全加载之前显示“正在加载...”等。

一种方法是将消息发送给 Service Worker,然后从 Service Worker 发送给 Vue,但感觉不实用。

另一种方法是在初始化之后设置windows.script_status = true,但是window对象不是reactive的,所以Vue会检查一次,得到undefined就忘了。

UPD:第三种方法是从 Vue 端注入脚本并将一些函数放入 script.onload 以获取它何时准备就绪,但不确定解决方案的稳定性。

所以,任何建议都可以:)

【问题讨论】:

我建议你使用pyodide.runPythonAsync。此功能将自动下载所有导入包。不过,您仍然必须等到 pyodide 初始化。查看my answer 【参考方案1】:

我会走外部事件中心的路线。由于 Vue 3 移除了 $on、$off 和 $once 实例方法,事件中心的官方migration strategy 是使用外部库,例如mitt。使用例如一旦加载了其他自定义脚本,您应该能够轻松地向 Vue 发出信号。

【讨论】:

谢谢,从来没有听说过mitt,看起来合法:) 最近第一次使用mitt,就像一个魅力和200字节的gzipped足迹,这对我来说很容易。【参考方案2】:

解决方案是第三个 - 通过mounted 手动注入脚本并将所有逻辑放入script.onload 部分。谷歌地图示例:

mounted: function () 
    if (window.google && window.google.maps) 
        this.create_map();
        return;
    

    var self = this;
    var script = document.createElement("script");
    script.onload = function () 
        if (!window.google && !window.google.maps)
            return void (console.error("no google maps script included"));

        self.create_map();
    ;

    script.async = true;
    script.defer = true;
    script.src = "https://maps.googleapis.com/maps/api/js?key=googleapikeyxxxx&callback=initMap";
    document.getElementsByTagName("head")[0].appendChild(script);

从另一个 SO 问题的答案中选择逻辑:https://***.com/a/45605316/1598470。

【讨论】:

重要的部分——如果你想从data 中的.then() 部分更新组件变量——在开始时重新分配let self = this(如上例所示),因为每个.then() 都有它自己的this :)

以上是关于如何从 index.html 向 Vue.js 3 实例发送消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Vue.js 向 gRpc 标头添加授权

VUE如何加载index.html和main.js

如何从 Vue.Js 中的变量向数组添加值以制作条形图

如何在 Vue.js 中导入 css?

Vue.js / Webpack 使用 CSS 和 JS 的“静态”子域构建“index.html”

从html javascript向nodejs发出请求