7

I'm banging my head on the following problem: I created a QRCode component using Vue 3 and Typescript with the following code:

<template>
  <canvas ref="qrcodeVue"> </canvas>
</template>

<script lang="ts">
import QRCode from "qrcode";
import { Vue, Options } from "vue-class-component";
import { ref } from "vue";

@Options({
  props: {
    value: {
      type: String,
      required: true
    },
    size: {
      type: [Number, String],
      validator: (s: [number | string]) => isNaN(Number(s)) !== true
    },
    level: {
      type: String,
      validator: (l: string) => ["L", "Q", "M", "H"].indexOf(l) > -1
    },
    background: String,
    foreground: String
  }
})
export default class QRCodeVue extends Vue {
  value = "";
  size: number | string = 100;
  level: "L" | "Q" | "M" | "H" = "L";
  background = "#ffffff";
  foreground = "#0000ff";

  mounted() {
    const _size = Number(this.size);
    const scale = window.devicePixelRatio || 1;
    const qrcodeVue = ref<HTMLCanvasElement | null>(null);

    QRCode.toCanvas(qrcodeVue, this.value, {
      scale: scale,
      width: _size,
      color: { dark: this.foreground, light: this.background },
      errorCorrectionLevel: this.level
    });
  }
}
</script>

But qrcodeVue is always referring to nothing, I never get access to the canvas itself. What am I missing? Where should I put this ref() code? I also tried with defineComponent with the same result. Thanks for any clue.

(BTW, I also tried to use the npm qrcode-vue package but it doesn't seem to support Vue 3)

2
  • I think you might be missing the .value part of qrcodeVue to access the canvas element QRCode.toCanvas(qrcodeVue.value, this.value, ...). Commented Dec 28, 2020 at 20:04
  • Thanks Ibrahim. See Dan's answer below for the real thing. Commented Dec 30, 2020 at 11:35

1 Answer 1

7

You have to declare the ref qrcodeVue as a class property first, and not inside mounted.

Only then will it be be available and populated with the ref element in mounted:

export default class QRCodeVue extends Vue {
  qrcodeVue = ref<HTMLCanvasElement | null>(null); // not inside mounted

  mounted() {
    console.log(this.qrcodeVue);  // now it's available
  }
}

This is the equivalent to the following Vue 3 setup syntax:

setup() {
  const qrcodeVue = ref(null);
  onMounted(() => {
    console.log(qrcodeVue.value);
  })
  return {
    qrcodeVue
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.