I'm encountering an issue with receiving events from a barcode reader, which I heavily referenced from a GitHub repository.
The problem lies in the fact that the events emitted by the BarcodeScanner component are not being captured by the enclosing component, a modified version of HelloWorld.vue. The Vue DevTools in the browser console indicate that the events are being properly emitted. However, the HelloWorld component does not respond to these events.
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, 30, 0.5);
-webkit-clip-path: polygon(
0% 0%,
0% 100%,
20% 100%,
20% 20%,
80% 20%,
80% 80%,
20% 80%,
20% 100%,
100% 100%,
100% 0%
);
clip-path: polygon(
0% 0%,
0% 100%,
20% 100%,
20% 20%,
80% 20%,
80% 80%,
20% 80%,
20% 100%,
100% 100%,
100% 0%
);
}
</style>
Is there something obvious that I may be overlooking?