如何使用 Vue Class 组件访问 VueJS 3 和 Typescript 中的 HTML 引用?

How to access an HTML ref in VueJS 3 and Typescript with Vue Class Component?

我正在努力解决以下问题:我使用 Vue 3 和 Typescript 创建了一个 QRCode 组件,代码如下:

<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>

但是 qrcodeVue 总是没有任何意义,我从来没有访问过 canvas 本身。我错过了什么?我应该把这个 ref() 代码放在哪里?我也尝试使用 defineComponent 得到相同的结果。感谢您提供任何线索。

(顺便说一句,我也尝试使用 npm qrcode-vue 包,但它似乎不支持 Vue 3)

您必须首先将 ref qrcodeVue 声明为 class 属性,而不是在 mounted.

只有这样它才可用并填充 mounted:

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

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

这等同于以下 Vue 3 setup 语法:

setup() {
  const qrcodeVue = ref(null);
  onMounted(() => {
    console.log(qrcodeVue.value);
  })
  return {
    qrcodeVue
  }
}