Как структурно сравнить предыдущее и новое значение вложенных объектов, которые используются в «watch», в API опций?

#vuejs3 #watch #vue-composition-api

Вопрос:

У меня есть вопрос, который представляет собой сочетание API композиции и API опций

Что я хочу сделать: я хочу наблюдать за объектом. Этот объект глубоко вложен во все типы данных.

  • Всякий раз, когда какое-либо из вложенных свойств внутри изменяется, я хочу, чтобы часы запускались.
    • (Это можно сделать, используя опцию deep: true).
  • И я хочу иметь возможность видеть предыдущее значение и текущее значение объекта.
    • (это кажется невозможным, потому что Vue хранит ссылки на объекты, так что теперь значение и предыдущее значение указывают на одно и то же.)

В документах Vue3 для API watch говорится следующее

 However, watching a reactive object or array will always return a reference to the 
current value of that object for both the current and previous value of the state. 
To fully watch deeply nested objects and arrays, a deep copy of values may be required.
 This can be achieved with a utility such as lodash.cloneDeep
 

И этот следующий пример приведен

 import _ from 'lodash'

const state = reactive({
  id: 1,
  attributes: {
    name: ''
  }
})

watch(
  () => _.cloneDeep(state),
  (state, prevState) => {
    console.log(state.attributes.name, prevState.attributes.name)
  }
)

state.attributes.name = 'Alex' // Logs: "Alex" ""
 

Ссылка на документы здесь — https://v3.vuejs.org/guide/reactivity-computed-watchers.html#watching-reactive-objects

Однако это API композиции (если я не ошибаюсь). Как я могу использовать этот способ использования cloneDeep в часах, определенных в API опций?

В качестве примера, это мой код

 watch: {
    items: {
      handler(value, prevValue) {
        // check if value and prevValue are STRUCTURALLY EQUAL
        let isEqual = this.checkIfStructurallyEqual(value, prevValue)
        if (isEqual) return
        else this.doSomething()
      },
      deep: true,
    },
}
 

Я использую Vue 3 с API опций.

Как бы я поступил, если бы сделал это в API опций? Любая помощь будет оценена по достоинству! Если есть другой способ сделать это, пожалуйста, дайте мне знать!