如何从 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 实例发送消息?的主要内容,如果未能解决你的问题,请参考以下文章