【问题标题】:How to get and observe ref to element from a v-for?如何从 v-for 获取和观察元素的引用?
【发布时间】:2023-11-21 08:12:02
【问题描述】:

似乎解决类似问题的所有答案都与 Vue 2 相关,或者根本没有给出预期的结果。即使the docs 中描述的内容也不起作用,因为如果我记录 ref 的值,我只会看到一个空对象。

我有一个这样的模板:

<template>
  <post-content v-for="post in posts" :post-data="post" :key="post.id" ref="lastPost" />
</template>

PostContent 组件的内容并不重要,将其想象成一个 div,显示 post.content 中的任何内容。

在脚本中,我从 API 获取 posts,并且我希望在引用 lastPost 中获得最后加载的帖子,以便我可以访问它的 HTMLElement(我需要它来获取东西,但是在这里我只是尝试记录它)。

// This uses composition API with <script setup> syntax

const posts = ref<{id: number, content: string}[]>([])

getPostsFromApi()
  .then((thePost: {id: number, content: string}) => posts.value.push(thePost))

const lastPost = ref<typeof PostContent>()

watch(lastPost, () => nextTick(() => console.log(lastPost.value)), {flush: "post"})

但是,这会导致日志成为一个简单的空对象 {}

  • 我需要能够在 HTMLElement 加载后访问它本身。
  • 我需要观察参考的变化,这样我每次发帖都能拿到元素。
  • 我只需要在任何给定时间的最后一个帖子,我不关心以前的帖子。我一次只会添加一个帖子。这就是我不使用数组作为参考的原因。

为什么要记录一个空对象,而不是根据文档,应该预期什么?我做错了什么?

【问题讨论】:

    标签: typescript vue.js vuejs3 vue-composition-api


    【解决方案1】:

    与具有常规 &lt;script&gt; 块的 SFC 不同,&lt;script setup&gt; 组件默认关闭 -- 即 &lt;script setup&gt; 范围内的变量不会向父级公开,除非通过 @987654321 明确公开@。记录的模板引用中的空对象表示您没有公开任何属性。

    要公开PostContent 的根元素,请在组件中使用模板引用,并使用defineExpose() 公开ref(例如,命名为“$el”):

    // PostContent.vue
    <script setup lang="ts">
    const $el = ref()
    defineExpose({ $el })
    </script>
    
    <template>
      <div ref="$el">...</div>
    </template>
    

    顺便说一句,watch(){ flush: 'post' } 可以简化为 watchPostEffect()

    watch(lastPost, () => nextTick(() => console.log(lastPost.value.$el)), {flush: "post"})
    
    // OR more simply:
    watchPostEffect(() => console.log(lastPost.value.$el))
    

    demo

    【讨论】:

      最近更新 更多