在动态字段上触发观察者

Firing watcher on dynamic fields

我有一个使用 Quasar 的 vue 应用程序,它会在选择图像后加载模态以执行功能。这适用于固定值,但我无法让它适用于动态创建的字段(这意味着用户可以通过单击“添加字段”按钮来添加它们)。

问题 我想创建一个在三个字段(imgOne、imgTwo 和 imgThree)中的每一个上触发的观察器。我可以使用 deep 修饰符让它在数组发生变化时触发,但这对我的目的不起作用。

额外问题:如何允许在不触发监视的情况下清除文件输入字段。

  <q-file
    v-model="map"
    label="map"
  ></q-file>
  
 <div
    v-for="(field, i) in fields"
    :key="i"
  >
   <q-file
     v-model="fields[i].imgOne"
    ></q-file>
    <q-file
      v-model="fields[i].imgTwo"
    ></q-file>
    <q-file
      v-model="fields[i].imgThree"
    ></q-file>
  </div>

watch(map, (currentValue, oldValue) => {
  //this works to launch the modal
});

 watch(
  fields.imgOne,
  (currentValue, oldValue) => {
    //this does not work. I cannot use fields[i].imgOne or 
    //fields.value.imgOne
    //I want this to fire each time imgOne, imgTwo, or 
    //imgThree change
  },
  { deep: true }
);

fields 数组中的每个条目维护单独的观察者(如果你想要 imgOneimgTwo 等的单独观察者,则为 3 个观察者 - 从问题中不清楚)绝对是可能,但你需要解决一些问题:

  1. 每次添加新字段时都必须添加观察者
  2. 您可能应该存储 return value of watch 以在删除字段时停止观察者
  3. 由于fields数组的元素是反应对象而不是refs,必须使用watch接收函数的重载
// after new field with index addedFieldIndex is added into array
// local variable
const addedFieldIndex = XX
const field = fields[addedFieldIndex]
field.watcher = watch(
  // watching multiple sources at once
  [
   () => field.imgOne,
   () => field.imgTwo,
   () => field.imgThree
  ], handler)

无论如何这绝对是不必要的和复杂的。在这种情况下,watch 不是最好的工具。更好的工具是 update:model-value 事件(v-model 使用的相同事件),它在选择或清除文件时触发

<q-file
  v-model="fields[i].imgThree"
  @update:model-value="onFileSelected(field, $event)"
></q-file>
    const onFileSelected = (field, fileSelected) => {
      // null is used when field is cleared
      if(fileSelected !== null) {
        console.log("File ", fileSelected, " for field ", field.id)
      }
    }