如何解决Vue.js/TypeScript:未选择组件中的事件
我在侦听条形码阅读器发出的事件时遇到问题,我在很大程度上copied from GitHub。
问题是由 BarcodeScanner
组件发出的事件未被封装组件(它是一个修改后的 HellowWorld.vue
文件)接收。带有 Vue DevTools 的浏览器控制台显示事件已正确发出。但发生这种情况时,HelloWorld
组件不会执行任何操作。
HelloWorld.vue
:
<template>
<div class="hello">
<barcode-scanner @loaded="onLoaded" @decoded="onDecoded"/>
</div>
</template>
<script lang="ts">
import {Component,Vue} from 'vue-property-decorator';
import BarcodeScanner from "@/components/BarcodeScanner.vue";
@Component({
components: {BarcodeScanner}
})
export default class HelloWorld extends Vue {
onLoaded() {
console.log("Barcode scanner component has emitLoaded");
}
onDecoded(code: string) {
console.log("Scanned code",code);
}
}
</script>
<style scoped>
</style>
BarcodeScanner.vue
:
<template>
<div class="scanner-container">
<div v-show="isLoaded">
<video ref="scanner"></video>
<div class="overlay-element"></div>
</div>
</div>
</template>
<script lang="ts">
import {Component,Emit,Ref,Vue} from "vue-property-decorator";
import {browserMultiFormatReader,Exception,Result} from "@zxing/library";
@Component
export default class BarcodeScanner extends Vue {
@Ref("scanner") private scanner!: HTMLVideoElement;
private isLoaded = false;
private codeReader = new browserMultiFormatReader();
readonly streamAPISupported = ("enumerateDevices" in navigator?.mediaDevices);
@Emit("loaded") emitLoaded(): void {
this.isLoaded = true;
}
@Emit("decoded") emitDecoded(code: string) {
console.log("Decoded",code);
}
mounted() {
if (!this.streamAPISupported) {
throw new Exception("Media stream API not supported");
}
this.start();
this.scanner.oncanplay = () => {
this.emitLoaded();
console.log("Scanner has loaded (BarcodeScanner component)");
}
}
start(): void {
this.codeReader.decodeFromVideoDevice(
null,this.scanner,// eslint-disable-next-line @typescript-eslint/no-unused-vars
(result: Result,err: Exception | undefined) => {
if (result) {
console.log(result);
this.emitDecoded(result.getText());
}
}
)
}
}
</script>
<style scoped>
video {
max-width: 100%;
max-height: 100%;
}
.scanner-container {
position: relative;
}
.overlay-element {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(30,30,0.5);
-webkit-clip-path: polygon(
0% 0%,0% 100%,20% 100%,20% 20%,80% 20%,80% 80%,20% 80%,100% 100%,100% 0%
);
clip-path: polygon(
0% 0%,100% 0%
);
}
</style>
我是否遗漏了一些明显的东西?
解决方法
回答我自己的问题:重新创建 Vue.js 项目并将上述文件复制到其中解决了问题,原因不明。
来自 Java 背景(以及超过 25 年的专业经验),我仍然发现这些新奇的前端框架的许多方面令人困惑。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。