vue3中ref的使用

usage of ref in vue3

我写了一个 vue3 组件,它使用 PrimeVue 的 VirtualScroller,每次添加新元素时我都想滚动到滚动条的末尾。为此,组件上定义了 scrollInView 方法并记录在案 here

我的代码看起来像这样(它是带有 vue-class-component 和单个文件语法的打字稿):

<template>
 ...
   <VirtualScroller :items="content" :itemSize="50" class="streamscroller" ref="streamscroller">
      <template v-slot:item="{ item }">
        <pre>{{ item }}</pre>
      </template>
    </VirtualScroller>
...
</template>

<script lang="ts">
...
import { ref, ComponentPublicInstance } from "vue";
import VirtualScroller from "primevue/virtualscroller";
...
@Options({
  components: {
    VirtualScroller,
...
  },
})
export default class StreamResultViewer extends Vue {
  streamscroller = ref<ComponentPublicInstance<VirtualScroller>>();
  content: string [] = [ "No output" ];
...
  mounted(): void {
...
    console.debug("scroller mounted: ", this.streamscroller.value);   // <=== here, already the value is indefined
  }
  onData(msg: string): void {
      const lines = msg.split('\n');
      const content =  [...this.content, ...lines];
      this.content = content;
      console.debug("scroller: ", this.streamscroller.value);   // <== always undefined
      this.streamscroller.value?.scrollInView(this.content.length, 'to-end', 'smooth');   // <== so never called
  }
...

虚拟滚动条运行良好(我可以在每次到达时添加行并且滚动条移动...)但我永远无法调用滚动方法,因为 ref 未定义...

如果有任何线索,我将不胜感激...

谢谢

我发现的唯一解决方法是像这样使用 $refs:

onData(msg: string): void {
  const lines = msg.split('\n');
  const content = [...this.content, ...lines];
  this.content = content;
  const scroller = this.$refs.streamscroller as VirtualScroller;
  scroller.scrollInView(this.content.length, 'to-end', 'smooth');
}

通过这种方式,我可以调用滚动方法并且它工作正常。

如果有人能解释在 vue-class-component + typescript 模式下如何使用 ref() 正常工作,我会很高兴听到。