我使用Vue Cli开发了一个网络广播播放器。现在,我必须使用外部库添加一个新功能(它旨在处理音频广告(,并且必须从远程主机提供此库。我不能只下载库并在本地导入它。
设置
在我的Vue应用程序中,我有几个组件,其中一个组件中有一个处理无线电播放的音频标签。我需要检测到点击播放按钮,加载广告,播放它,然后转到收音机定期播放。
我尝试过的方法
- 在index.html文件中加载外部库。这是有效的,但我无法与Vue中加载的玩家互动。例如,如果我试图收听index.html文件(
audio.addEventListener("play", onPlay);
(中的播放事件,我只会在web控制台中收到"未定义的音频"> - 在组件的已安装((部分加载外部库:
const triton = document.createElement('script')
triton.setAttribute('src', '//sdk.listenlive.co/web/2.9/td-sdk.min.js')
document.head.appendChild(triton)
this.initPlayerSDK()
triton.onload = () => {
let player = new TDSdk(this.tdPlayerConfig)
console.log(player)
}
这种方法的问题是在npm run serve
之后,我接收到完全有意义的消息'TDSdk' is not defined
。我正在加载外部JS文件,但webpack没有解释其内容,因为它是在运行时完成的。我必须在我的vue.config.js中添加外部,但这也不起作用:
vue.config.js
const path = require('path')
module.exports = {
publicPath: './',
/*configureWebpack: {
externals: {
tdSdk: 'tdSdk'
}
},*/
chainWebpack: config => {
config.module
.rule('images')
.test(/.(png|jpe?g|gif|webp)(?.*)?$/)
.use('url-loader')
.loader('file-loader') // not url-loader but file-loader !
.tap((options) => { // not .option() but .tap(options...)
// modify the options...
options.name = 'img/[name].[ext]'
return options
}),
config.externals([
{
'tdSdk': 'TDSdk'
},
])
},
css: {
loaderOptions: {
sass: {
sassOptions: {
includePaths: [path.resolve(__dirname, './node_modules/compass-mixins/lib')]
}
}
}
},
externals: {
tdSdk: 'TDSdk'
}
}
myComponent.vue
import tdSdk from 'tdSdk'
我的解决方案是在public/index.html文件中加载库,然后等待DOM加载,这样我就可以将事件侦听器添加到已经加载的音频元素中:
document.addEventListener('DOMContentLoaded', function() {
var playControl = document.getElementById('playIcon');
playControl.addEventListener("click", onPlay);
}
然后,在Vuex存储中,我需要访问位于index.html中的javascript中定义的变量。为此,我在存储文件中将window.adState
(我正在使用的var(设置为全局var
Vuex.Store.prototype.$adState = window.adState
最后,在我的行动/突变中,我使用了这个$adState检查其内容:
playPause ({ commit, dispatch }) {
console.log('AdState', this.$adState)
(...)
}
代表OP添加的答案。
在评估脚本时无法解析导入,因为TDSdk
全局不可用。动态添加到head
的脚本是异步加载的,因此无论如何都会存在竞争条件。
如果涉及动态行为或类似条件,或者开发人员无法控制页面布局,则需要动态添加<script>
。对于静态脚本,Vue CLI项目的public index.html可以修改:
<body>
<div id="app"></div>
<script src="//sdk.listenlive.co/web/2.9/td-sdk.min.js"></script>
<!-- built files will be auto injected -->
</body>
应用程序捆绑包在脚本之后进行评估,并且全局应用程序有望在那里可用。
External通常用于交换到外部加载的包,通常是从CDN加载的包。由于tdSdk
不是一个真正的包,也没有可以交换的前景,因此将其映射到全局并导入并没有很好的作用。它在应用程序中只能用作TDSdk
全局。