如何重置 ref 的值并保持关联的观察者工作?

How can I reset the value of a ref and keep an associated watcher working?

更新:

我已经通过更改 resetArray:

在我的应用程序 MCV 中实现了预期的行为
function resetArray() {
  // myArray.value = [] // old version
  myArray.value.length = 0 // new version
}

但我还是不明白为什么我的 MCV 不工作。

原版POST:

背景

在我正在构建的应用程序中,我将数据存储在一个 ref 中,创建为 const myArray = ref([]),它采用对象数组的形式。此数组仅通过以下方式更改:

  1. myArray.value[index] = {key: value}
  2. myArray.value = [].

特别是,myArray 中的对象绝不会被修改、创建或替换。

我后来添加了一个 watch,它对每个 myArray.value 都采取了行动。我发现将 myArray 重置为 [] 后,watcher 不再被调用。

我尝试过的东西:

  1. 我确认我对 ref 的使用遵循 中关于 refreactive 的指南。
  2. 重构为使用 watchEffect 而不是 watch。没有帮助。
  3. 重构为使用 reactive 而不是 ref。没有帮助。

我的问题

在下面的 MCV 中,通过调用 addToArray 修改 myArray 按预期工作:呈现 myArray.length 并触发第一个 watch

调用 resetArray 仅触发第二个 watch,但第一个 watch 不会 在之后调用 addToArray 时触发。

我的问题

如何在每次 myArray 更改时保持将 myArray 设置为 [] 并触发操作的能力?

我的MCV

View my MCV on Vue SFC Playground

下面的代码是用npm init vue@latest创建的Vue项目中App.vue的内容:

<script setup>
import {ref, watch} from "vue"

const myArray = ref([])

function addToArray() {
  myArray.value.push("1")
}

function resetArray() {
  myArray.value = []
}

watch(myArray.value, () => {
  console.log("CLICKED!")
})

watch(myArray, () => {
  console.log("RESET! clicked won't get called again!")
})

</script>

<template>
  {{myArray.length}}<br />
  <button @click="addToArray">CLICK ME</button><br />
  <button @click="resetArray">RESET</button>
</template>
  1. 观看 ref 时,使用 ref 本身 -- 而不是它的 value 属性 -- 作为观看源(第一个watch()).

    的参数
  2. 要观察新的数组分配或项目 additions/removals,传递 deep:true 选项(watch() 的第三个参数):

watch(
  myArray 1️⃣,
  () => { /* handle change */ },
  { deep: true } 2️⃣
)

demo