watch() 在其组件被实例化两次时不起作用

问题描述 投票:0回答:1

我有一个组件

Gregory
,它有一个
QFile
组件和一个可编辑的 div。我在
ref()
上放置了
QFile
,并在用户发送文件时放置了
watch()
来观察,因为我需要在 Gregory 的可编辑 div 上插入用户发送的文件的链接,为此我使用
document.querySelector()
来检测可编辑 div 的位置(基于其 id)。可编辑 div 的 id 绑定到
Gregory
属性
itemId
:

// Gregory.vue
<template>
  <div>
    <div contenteditable :id=”`editor-${itemId}`”>
    </div>
    <QFile v-model=”files” /> 
  </div>
</template>

<script setup lang=”ts”>
import { watch } from ‘vue’
const props = defineProps({
  itemId: {
    type: String,
    required: true,
  }
})
const { itemId } = toRefs(props)
const files = ref()

watch(files, () => { /*…  (using itemId here)*/ })
</script>

问题是我在同一个组件中有两个

Gregory
实例,并且出于某种原因,我在那里编写的
watch()
不适用于多个 Gregory 实例,因为它仅使用第一个实例的 props即使在第二次触发时也是如此。

为什么会发生这种情况以及如何使

watch()
能够在我的组件的多个实例上工作?

vuejs3 quasar vue-reactivity
1个回答
0
投票

解决方案

为了确保

watch
函数对于
Gregory
的每个实例都能正确运行,请按照以下步骤操作:

  1. 为每个实例使用单独的

    files
    反应引用。 您应该直接在
    files
    函数中定义
    setup
    ,而不是全局定义。

  2. 确保

    watch
    正在使用本地
    files
    参考
    来独立监控每个实例的更改。

这是更新后的代码:

// Gregory.vue
<template>
  <div>
    <div contenteditable :id="`editor-${itemId}`"></div>
    <QFile v-model="files" />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, defineProps, toRefs } from 'vue';

const props = defineProps({
  itemId: {
    type: String,
    required: true,
  }
});
const { itemId } = toRefs(props);
const files = ref([]); // Initialize files as an empty array or any appropriate value.

watch(files, (newFiles) => {
  if (newFiles.length > 0) {
    const editorId = `editor-${itemId.value}`;
    const editor = document.querySelector(`#${editorId}`);
    if (editor) {
      // Insert logic to update the editable div with the file link
      // For example, you can append the file names
      newFiles.forEach(file => {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(file); // Create a link to the file
        link.innerText = file.name; // Set the text to the file name
        editor.appendChild(link); // Append the link to the editable div
        editor.appendChild(document.createElement('br')); // Add line break
      });
    }
  }
});
</script>

主要变化:

  1. files
    的初始化:确保
    files
    是每个
    Gregory
    实例的反应引用。

  2. itemId
    的正确使用:当您在
    itemId
    中访问
    watch
    时,使用
    itemId.value
    来引用当前实例的ID。

  3. 将链接附加到可编辑 div: 这部分保持不变,但至关重要的是它基于当前实例的

    itemId
    引用正确的可编辑 div。

© www.soinside.com 2019 - 2024. All rights reserved.