我想导入一个JS文件并与浏览器中的模板一起运行。我尝试了this,但没有成功,因为我需要先加载所有内容,然后才能运行脚本。
让我告诉您有问题的vue文件:
<template>
<div id="canvaspage">
<canvas id="canvas"></canvas>
<div id="buttonlist">
<h5>Select your action:</h5>
<div class="col">
<button id="btn1">JS file custom action 1</button>
<button id="btn2">JS file custom action 2</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CanvasPage'
}
</script>
...
看到画布和模板上的按钮了吗?我想使用纯JS与之交互。
以下是JS文件正在尝试执行的操作的示例:
let canvas = document.getElementById('canvas')
let button1 = document.getElementById('btn1')
let button2 = document.getElementById('btn2')
canvas.addEventListener('click', () => {
console.log('Canvas clicked')
})
button1.addEventListener('click', () => {
console.log('Button 1 clicked')
})
button2.addEventListener('click', () => {
console.log('Button 2 clicked')
})
如果我尝试上面链接的解决方案,将会发生的情况是'canvas','button1'和'button2'均为null,因为JS无法找到它们。如何在Vue上使用它?
答案 0 :(得分:1)
在这个示例中,我没有看到原因-为什么要在外部js文件中执行任何操作,为什么不只是以dom the vue
的方式进行交互-我的意思是,正确的方法? Vue可以使用任何v-if或rerender动作销毁或替换您的元素。如果您想直接与DOM交互,则总是可以使用this.$refs
链接到元素,这比querySelector
更好。但是无论如何,这是一个虚拟的例子:
// external js file - ./extfile.js
export function canvasClick(...args) {
console.log('canvas clicked with: ', args);
}
export function button1Click(...args) {
console.log('button1 clicked with: ', args);
}
export function button2Click(...args) {
console.log('button2 clicked with: ', args);
}
// vue component
<template>
<div id="canvaspage">
<canvas id="canvas" @click="canvasAction"></canvas>
<div id="buttonlist">
<h5>Select your action:</h5>
<div class="col">
<button id="btn1" @click.prevent="button1Action">JS file custom action 1</button>
<button id="btn2" @click.prevent="button2Action">JS file custom action 2</button>
</div>
</div>
</div>
</template>
<script>
import { canvasClick, button1Click, button2Click } from './extfile';
export default {
name: 'CanvasPage',
methods: {
canvasAction(event) { canvasClick(event, this) },
button1Action(event) { button1Click(event, this) },
button2Action(event) { button2Click(event, this) },
}
}
</script>
答案 1 :(得分:0)
由Vue管理的对象是根据Vue的生命周期创建/销毁的。这意味着您用于查询vue管理的元素的任何外部代码都应在某种程度上与Vue的生命周期相联系。
这意味着,理想情况下,您应该使用Vue本身来添加所需的行为。例如,您应该将所需的新功能添加到Vue组件中。这样可以保证设计更简单。
替代:如果Vue组件来自第三方,也许是您无法依靠的另一个团队,则可以将这些事件侦听器挂接到document
上并检查目标的id
属性,而不是将事件侦听器直接挂钩到canvas
元素(该元素可能会被Vue破坏并丢失挂钩)。
document.body.addEventListener('click', (event) => {
switch (event.target.id) {
case 'canvas':
console.log('Canvas clicked');
break;
case 'btn1':
console.log('Button 1 clicked');
break;
case 'btn2':
console.log('Button 2 clicked');
break;
}
}, true);
此代码非常明显,如果DOM中具有这些ID的元素中不止一个,则所有这些元素都会触发代码。
演示:
const CanvasComponent = Vue.component('canvas-component', {
template: `#canvas-component`,
});
const BlankComponent = Vue.component('blank-component', {
template: `<div><h3>Now click back to canvas and see that the listeners still work.</h3></div>`,
});
var router = new VueRouter({
routes: [{
path: '/',
component: {template: '<div>Click one link above</div>'}
},{
path: '/blank',
component: BlankComponent,
name: 'blank'
},
{
path: '/canvas',
component: CanvasComponent,
name: 'canvas'
}
]
});
var app = new Vue({
el: '#app',
router: router,
template: `
<div>
<router-link :to="{name: 'canvas'}">canvas</router-link> |
<router-link :to="{name: 'blank'}">blank</router-link>
<router-view></router-view>
</div>
`
});
document.body.addEventListener('click', (event) => {
switch (event.target.id) {
case 'canvas':
console.log('Canvas clicked');
break;
case 'btn1':
console.log('Button 1 clicked');
break;
case 'btn2':
console.log('Button 2 clicked');
break;
}
}, true);
<script src="//unpkg.com/vue@2.6.9/dist/vue.min.js"></script>
<script src="//unpkg.com/vue-router@3.1.3/dist/vue-router.min.js"></script>
<div id="app">
<canvas-component></canvas-component>
</div>
<template id="canvas-component">
<div id="canvaspage">
<canvas id="canvas"></canvas>
<div id="buttonlist">
<h5>Select your action:</h5>
<div class="col">
<button id="btn1">JS file custom action 1</button>
<button id="btn2">JS file custom action 2</button>
</div>
</div>
</div>
</template>