Разработка сайтов в Донецке, ДНР. Понимание новой системы реактивности в Vue 3

Системы реактивности — одна из ключевых частей современных интерфейсных фреймворков. Это волшебная палочка, которая делает приложения очень интерактивными, динамичными и отзывчивыми. Понимание того, что такое система реактивности и как ее можно применять на практике, является важным навыком для каждого веб-разработчика.

Система реактивности — это механизм, который автоматически поддерживает синхронизацию источника данных (модели) со слоем представления данных (представления). Каждый раз, когда модель изменяется, представление перерисовывается, чтобы отразить изменения.

В качестве примера возьмем простой редактор Markdown. Обычно он имеет две панели: одну для написания кода Markdown (который изменяет базовую модель) и одну для предварительного просмотра скомпилированного HTML (который показывает обновленное представление). Когда вы пишете что-то в области письма, это немедленно и автоматически просматривается в области предварительного просмотра. Конечно, это всего лишь простой пример. Часто все гораздо сложнее.

Во многих случаях данные, которые мы хотим отобразить, зависят от некоторых других данных. В таком сценарии зависимости отслеживаются, и данные обновляются соответствующим образом. Например, предположим, что у нас есть fullNameсвойство, которое зависит от firstNameи lastNameсвойств. При изменении любой из его зависимостей fullNameсвойство автоматически переоценивается, и результат отображается в представлении.

Теперь, когда мы установили, что такое реактивность, пришло время узнать, как работает новая реактивность Vue 3 и как мы можем использовать ее на практике. Но прежде чем мы это сделаем, мы кратко рассмотрим реактивность старого Vue 2 и ее предостережения.

Краткое исследование реактивности Vue 2

Реактивность в Vue 2 более или менее «скрыта». Что бы мы ни помещали в dataобъект, Vue неявно делает его реактивным. С одной стороны, это упрощает работу разработчика, а с другой — снижает гибкость.

За кулисами Vue 2 использует ES5 Object.defineProperty () для преобразования всех dataсвойств объекта в геттеры и сеттеры. Для каждого экземпляра компонента Vue создает экземпляр наблюдателя зависимостей. Любые свойства, собранные/отслеживаемые как зависимости во время рендеринга компонента, записываются наблюдателем. Позже, когда запускается установщик зависимости, наблюдатель уведомляется, а компонент повторно отображает и обновляет представление. В основном так работает вся магия. К сожалению, есть некоторые оговорки.

Предупреждения об обнаружении изменений

Из-за ограничений Object.defineProperty (), есть некоторые изменения данных, которые Vue не может обнаружить. Это включает:

добавление/удаление свойства в/из объекта (например, obj.newKey = value)

установка элементов массива по индексу (например, arr[index] = newValue)

изменение длины массива (например, arr.length = newLength)

К счастью, чтобы справиться с этими ограничениями, Vue предоставляет нам метод API Vue.set, который добавляет свойство к реактивному объекту, гарантируя, что новое свойство также будет реактивным и, таким образом, запускает обновления представления.

Давайте рассмотрим вышеуказанные случаи на следующем примере:

 

 

Hello! My name is {{ person.name }}. I’m {{ person.age }} years old.

Here are my favorite activities:

 

  • v-for="item, index in activities": key="index">

     

    {{ item }}

 

 

const App = new Vue ({

el: '#app’,

data: {

person: {

name: «David»

},

activities: [

«Reading books»,

«Listening music»,

«Watching TV»

]

},

methods: {

// 1. Add a new property to an object

addAgeProperty () {

this.person.age = 30

},

// 2. Setting an array item by index

editActivity (index) {

const newValue = prompt ('Input a new value’)

if (newValue) {

this.activities[index] = newValue

}

},

// 3. Modifying the length of the array

clearActivities () {

this.activities.length = 0

}

}

}) ;

Вот пример CodePen.

В приведенном выше примере мы видим, что ни один из трех методов не работает. Мы не можем добавить новое свойство к personобъекту. Мы не можем редактировать элемент activitiesмассива, используя его индекс. И мы не можем изменить длину activitiesмассива.

Конечно, для этих случаев есть обходные пути, и мы рассмотрим их в следующем примере:

const App = new Vue ({

el: '#app’,

data: {

person: {

name: «David»

},

activities: [

«Reading books»,

«Listening music»,

«Watching TV»

]

},

methods: {

// 1. Adding a new property to the object

addAgeProperty () {

Vue.set (this.person, 'age’, 30)

},

// 2. Setting an array item by index

editActivity (index) {

const newValue = prompt ('Input a new value’)

if (newValue) {

Vue.set (this.activities, index, newValue)

}

},

// 3. Modifying the length of the array

clearActivities () {

this.activities.splice (0)

}

}

}) ;

Вот пример CodePen.

В этом примере мы используем Vue.setметод API для добавления нового ageсвойства к personобъекту и для выбора/изменения определенного элемента из массива действий. В последнем случае мы просто используем встроенный в JavaScript splice () метод массива.

Как мы видим, это работает, но немного хакерски и приводит к несогласованности в кодовой базе. К счастью, в Vue 3 это было решено. Давайте посмотрим на магию в действии на следующем примере:

const App = {

data () {

return {

person: {

name: «David»

},

activities: [

«Reading books»,

«Listening music»,

«Watching TV»

]

}

},

methods: {

// 1. Adding a new property to the object

addAgeProperty () {

this.person.age = 30

},

// 2. Setting an array item by index

editActivity (index) {

const newValue = prompt ('Input a new value’)

if (newValue) {

this.activities[index] = newValue

}

},

// 3. Modifying the length of the array

clearActivities () {

this.activities.length = 0

}

}

}

Vue.createApp (App).mount ('#app’)

Вот пример CodePen.

В этом примере, в котором используется Vue 3, мы возвращаемся к встроенным функциям JavaScript, использовавшимся в первом примере, и теперь все методы работают как часы.

В Vue 2.6 был введен метод API Vue.observable (). Он в некоторой степени раскрывает систему реактивности, позволяющую разработчикам явно делать объекты реактивными. На самом деле, это тот же самый метод, который Vue использует внутри для упаковки dataобъекта, и он полезен для создания минимального межкомпонентного хранилища состояний для простых сценариев. Но, несмотря на свою полезность, этот единственный метод не может сравниться по мощности и гибкости с полным, многофункциональным API реактивности, который поставляется с Vue 3. И мы увидим, почему в следующих разделах.

Примечание: Object.defineProperty () Vue 2 не поддерживает IE8 и более ранние версии, так как эта функция предназначена только для ES5 и не поддерживает шиммирование.

Как работает реактивность Vue 3

Система реактивности в Vue 3 была полностью переписана, чтобы использовать API-интерфейсы ES6 Proxy и Reflect. Новая версия предоставляет многофункциональный API реактивности, который делает систему гораздо более гибкой и мощной, чем раньше.

Proxy API позволяет разработчикам перехватывать и изменять низкоуровневые объектные операции над целевым объектом. Прокси — это клон/оболочка объекта (называемого целевым) и предлагающий специальные функции (называемые ловушками), которые реагируют на определенные операции и переопределяют встроенное поведение объектов JavaScript. Если вам по-прежнему нужно использовать поведение по умолчанию, вы можете использовать соответствующий Reflection API, методы которого, как следует из названия, отражают методы Proxy API. Давайте рассмотрим пример, чтобы увидеть, как эти API используются в Vue 3:

let person = {

name: «David»,

age: 27

};

const handler = {

get (target, property, receiver) {

// track (target, property)

console.log (property) // output: name

return Reflect.get (target, property, receiver)

},

set (target, property, value, receiver) {

// trigger (target, property)

console.log (`${property}: ${value}`) // output: «age: 30» and «hobby: Programming»

return Reflect.set (target, property, value, receiver)

}

}

let proxy = new Proxy (person, handler) ;

console.log (person)

// get (reading a property value)

console.log (proxy.name) // output: David

// set (writing to a property)

proxy.age = 30;

// set (creating a new property)

proxy.hobby = «Programming»;

console.log (person)

Вот пример CodePen.

Для создания нового прокси мы используем new Proxy (target, handler) конструктор. Он принимает два аргумента: целевой объект (personобъект) и объект-обработчик, определяющий, какие операции будут перехватываться (getи setоперации). В handlerобъекте мы используем ловушки getи setдля отслеживания, когда свойство читается и когда свойство изменяется/добавляется. Мы устанавливаем операторы консоли, чтобы убедиться, что методы работают правильно.

Ловушки getи setпринимают следующие аргументы:

target: целевой объект, который обернут прокси

property: имя свойства

value: значение свойства (этот аргумент используется только для операций над множествами)

receiver: объект, над которым происходит операция (обычно прокси)

Методы Reflect API принимают те же аргументы, что и соответствующие им прокси-методы. Они используются для реализации поведения по умолчанию для заданных операций, которые для getпрерывания возвращают имя свойства, а для setпрерывания возвращается trueнезависимо от того, установлено ли свойство или falseнет.

Комментарии track () и trigger () функции характерны для Vue и используются для отслеживания, когда свойство читается и когда свойство изменяется/добавляется. В результате Vue повторно запускает код, использующий это свойство.

В последней части примера мы используем оператор консоли для вывода исходного personобъекта. Затем мы используем другой оператор для чтения свойства nameобъекта proxy. Затем мы изменяем ageсвойство и создаем новое hobbyсвойство. Наконец, мы personснова выводим объект, чтобы убедиться, что он был обновлен правильно.

Вот как вкратце работает реактивность Vue 3. Конечно, реальная реализация намного сложнее, но, надеюсь, приведенного выше примера достаточно, чтобы вы уловили основную идею.

Есть также несколько соображений, когда вы используете реактивность Vue 3:

он работает только в браузерах, поддерживающих ES6+

реактивный прокси не равен исходному объекту

Изучение API реактивности Vue 3

Наконец, мы добрались до самого API реактивности Vue 3. В следующих разделах мы рассмотрим методы API, разделенные на логические группы. Я объединяю методы в группы, потому что думаю, что их легче запомнить, когда они представлены таким образом. Начнем с основ.

Основные методы

К первой группе относятся самые основные методы контроля реактивности данных:

refпринимает примитивное значение или простой объект и возвращает реактивный и изменяемый объект ссылки. Объект ref имеет только одно свойство value, указывающее на примитивное значение или простой объект.

reactiveпринимает объект и возвращает реактивную копию объекта. Преобразование является глубоким и влияет на все вложенные свойства.

readonlyпринимает ссылку или объект (обычный или реактивный) и возвращает объект только для чтения оригиналу. Преобразование является глубоким и влияет на все вложенные свойства.

markRawвозвращает сам объект и предотвращает его преобразование в прокси-объект.

Давайте теперь посмотрим на эти методы в действии:

Hello, Vue 3 Reactivity API!:)

 


 

Counter: {{ counter }}


 

 


 

Hello! My name is {{ person.name }}. I’m {{ person.age }} years old.

Edit person’s name

v-model="person.name" placeholder="name" /> and age

v-model="person.age" placeholder="age" />

 


 

PI: {{ math.PI }}

(The console output after the button is clicked: «Set operation on key 'PI’ failed: target is readonly.»)

 


 

Alphabet Numbers

 

 

 

 

 

 

 

 

 

 

 

v-for="(value, key) in alphabetNumbers">

 

 

 

 

 

 

 

 

Letter Number
{{ key }} {{ value }}

 

(Actually the letter B is changed to number 3 —, but it’s not tracked by Vue.)

import { ref, reactive, readonly, markRaw, isRef, isReactive, isReadonly, isProxy, onMounted } from 'vue’;

export default {

setup () {

const counter = ref (0)

const person = reactive ({

name: 'David’,

age: 36

})

const math = readonly ({

PI: 3.14

})

const alphabetNumbers = markRaw ({

A: 1,

B: 2,

C: 3

})

const showValue = () => {

alert (`The value of B is ${alphabetNumbers.B}`)

}

onMounted (() => {

console.log (isRef (counter)) // true

console.log (isReactive (person)) // true

console.log (isReadonly (math)) // true

console.log (isProxy (alphabetNumbers)) // false

})

return {

counter,

person,

math,

alphabetNumbers,

showValue

}

}

};

В этом примере мы исследуем использование четырех основных методов реактивности.

Сначала мы создаем counterобъект ref со значением 0. Затем в представлении мы помещаем две кнопки, которые увеличивают и уменьшают значение счетчика. Когда мы используем эти кнопки, мы видим, что счетчик действительно реактивный.

Во-вторых, мы создаем personреактивный объект. Затем в представлении мы помещаем два элемента управления вводом для редактирования человека nameи человека ageсоответственно. Когда мы редактируем свойства человека, они сразу же обновляются.

В-третьих, мы создаем mathобъект только для чтения. mathЗатем в представлении устанавливаем кнопку удвоения значения PIсвойства. Но когда мы нажимаем кнопку, в консоли отображается сообщение об ошибке, сообщающее нам, что объект доступен только для чтения и что мы не можем изменять его свойства.

Наконец, мы создаем alphabetNumbersобъект, который не хотим преобразовывать в прокси, и помечаем его как необработанный. Он содержит все буквы алфавита с соответствующими им номерами (здесь для краткости используются только первые три буквы). Этот порядок вряд ли будет изменен, поэтому мы намеренно оставили этот объект простым, что хорошо для производительности. Мы визуализируем содержимое объекта в таблице и устанавливаем кнопку, которая изменяет значение Bсвойства на 3. Мы делаем это, чтобы показать, что хотя объект и может быть изменен, это не приводит к повторному рендерингу представления.

markRawотлично подходит для объектов, которые не должны быть реактивными, таких как длинный список кодов стран, названий цветов и соответствующих им шестнадцатеричных чисел и т. д.

Наконец, мы используем методы проверки типов, описанные в следующем разделе, для проверки и определения типа каждого созданного нами объекта. Мы запускаем эти проверки при первоначальном рендеринге приложения с помощью onMounted () хука жизненного цикла.

Методы проверки типа

Эта группа содержит все четыре средства проверки типов, упомянутые выше:

isRefпроверяет, является ли значение объектом ссылки.

isReactiveпроверяет, является ли объект реактивным прокси, созданным reactiveили созданным readonlyпутем обертывания другого прокси, созданного reactive.

isReadonlyпроверяет, является ли объект прокси-сервером только для чтения, созданным readonly.

isProxyпроверяет, является ли объект прокси, созданным с помощью reactiveили readonly.

Дополнительные методы ссылок

Эта группа содержит дополнительные методы ref:

unrefвозвращает значение ссылки.

triggerRefвыполняет любые эффекты, привязанные к a shallowRefвручную.

customRefсоздает настроенную ссылку с явным контролем над ее отслеживанием зависимостей и запуском обновлений.

Мелкие методы

Методы этой группы являются «поверхностными» эквивалентами методов ref, reactivity, и readonly:

shallowRefсоздает ссылку, которая отслеживает только свое valueсвойство, не делая его значение реактивным.

shallowReactiveсоздает реактивный прокси, который отслеживает только свои собственные свойства, исключая вложенные объекты.

shallowReadonlyсоздает прокси-сервер только для чтения, который делает только свои собственные свойства доступными только для чтения, исключая вложенные объекты.

Давайте упростим понимание этих методов, рассмотрев следующий пример:

Hello, Vue 3 Reactivity API!:)

 


 

Shallow Ref

Settings: {{settings}}


 

Width: v-model="settings.width" />

Height: v-model="settings.height" />


 

 

 

 


 

Shallow Reactive

SettingsA: {{settingsA}}


 

Width: v-model="settingsA.width" />

Height: v-model="settingsA.height" />


 

X: v-model="settingsA.coords.x" />

Y: v-model="settingsA.coords.y" />

 


 

Shallow Readonly

SettingsB: {{settingsB}}


 

Width: v-model="settingsB.width" />

Height: v-model="settingsB.height" />


 

(The console output after trying to change the width or height is: «Set operation on key 'width/height’ failed: target is readonly.»)


 

X: v-model="settingsB.coords.x" />

Y: v-model="settingsB.coords.y" />

import {ref, shallowRef, shallowReactive, shallowReadonly, isRef, isReactive, isReadonly, onMounted } from 'vue’;

export default {

setup () {

const settings = shallowRef ({

width: 100,

height: 60

})

const settingsA = shallowReactive ({

width: 110,

height: 70,

coords: {

x: 10,

y: 20

}

})

const settingsB = shallowReadonly ({

width: 120,

height: 80,

coords: {

x: 20,

y: 40

}

})

onMounted (() => {

console.log (isReactive (settings)) // false

console.log (isReactive (settingsA)) // true

console.log (isReactive (settingsA.coords)) // false

console.log (isReadonly (settingsB)) // true

console.log (isReadonly (settingsB.coords)) // false

})

return {

settings,

settingsA,

settingsB

}

}

};

Этот пример начинается с создания settingsповерхностного объекта ref. Затем в представлении мы добавляем два элемента управления вводом, чтобы редактировать его widthи heightсвойства. Но когда мы пытаемся изменить их, мы видим, что они не обновляются. Чтобы исправить это, мы добавляем кнопку, которая изменяет весь объект со всеми его свойствами. Теперь это работает. Это связано valueс тем, что содержимое (widthи heightкак отдельные свойства) не преобразуется в реактивный объект, но мутация value (объекта в целом) все еще отслеживается.

Затем мы создаем settingsAнеглубокий реактивный прокси, который содержит свойства widthи heightи вложенный coordsобъект со свойствами xи. yЗатем в представлении мы устанавливаем элемент управления вводом для каждого свойства. Когда мы изменяем свойства widthи height, мы видим, что они реактивно обновляются. Но когда мы пытаемся изменить свойства xи y, мы видим, что они не отслеживаются.

Наконец, мы создаем settingsBнеглубокий объект только для чтения с теми же свойствами, что и settingsA. Здесь, когда мы пытаемся изменить свойство widthили height, в консоли отображается сообщение об ошибке, сообщающее нам, что объект доступен только для чтения, и мы не можем изменить его свойства. С другой стороны, свойства xи yмогут быть изменены без проблем.

Вложенный coordsобъект из обоих последних примеров не затрагивается преобразованием и остается простым. Это означает, что его можно свободно модифицировать, но ни одна из его модификаций не будет отслеживаться Vue.

Методы преобразования

Следующие три метода используются для преобразования прокси в ref (s) или обычный объект:

toRefсоздает ссылку для свойства исходного реактивного объекта. Ссылка сохраняет реактивное соединение со своим исходным свойством.

toRefsпреобразует реактивный объект в простой объект. Каждое свойство простого объекта является ссылкой, указывающей на соответствующее свойство исходного объекта.

toRawвозвращает необработанный, простой объект reactiveили readonlyпрокси.

Давайте посмотрим, как эти преобразования работают в следующем примере:

Hello, Vue 3 Reactivity API!:)

 


 

Hello! My name is {{ person.name }}.

I’m {{ person.age }} years old.

My hobby is programming.

 


 

To Ref

Name (ref): v-model="name" />

Person’s name: v-model="person.name" />

 


 

To Refs

PersonDetails’ age (ref): v-model="personDetails.age.value" />

Person’s age: v-model="person.age" />

 


 

To Raw

RawPerson’s hobby: {{rawPerson.hobby}}


 

RawPerson’s hobby: v-model="rawPerson.hobby" />

import { reactive, toRef, toRefs, toRaw, isReactive, isRef, onMounted } from 'vue’;

export default {

setup () {

const person = reactive ({

name: 'David’,

age: 30,

hobby: 'programming’

})

const name = toRef (person, 'name’)

const personDetails = toRefs (person)

const rawPerson = toRaw (person)

onMounted (() => {

console.log (isRef (name)) // true

console.log (isRef (personDetails.age)) // true

console.log (isReactive (rawPerson)) // false

})

return {

person,

name,

personDetails,

rawPerson

}

}

};

В этом примере мы сначала создаем базовый personреактивный объект, который будем использовать в качестве исходного объекта.

Затем мы конвертируем nameсвойство человека в ссылку с тем же именем. Затем в представлении мы добавляем два элемента управления вводом — один для nameссылки и один для nameсвойства человека. Когда мы изменяем один из них, другой соответственно обновляется, поэтому реактивная связь между ними сохраняется.

Затем мы преобразуем все свойства человека в отдельные ссылки, содержащиеся в personDetailsобъекте. Затем в представлении мы снова добавляем два элемента управления вводом, чтобы протестировать одну из только что созданных ссылок. Как мы видим, свойство personDetails ageполностью синхронизировано со ageсвойством человека, как и в предыдущем примере.

Наконец, мы преобразуем personобъект реактивности в rawPersonпростой объект. Затем в представлении мы добавляем элемент управления вводом для редактирования свойства rawPerson hobby. Но, как мы видим, преобразованный объект не отслеживается Vue.

Вычислительные и контрольные методы

Последняя группа методов предназначена для вычисления сложных значений и «шпионажа» за определенными значениями:

computedпринимает функцию получения в качестве аргумента и возвращает неизменяемый реактивный объект ссылки.

watchEffectнемедленно запускает функцию и реактивно отслеживает ее зависимости и повторно запускает ее всякий раз, когда зависимости изменяются.

watchявляется точным эквивалентом API параметров this. $watch и соответствующей watchопции. Он отслеживает определенный источник данных и применяет побочные эффекты в функции обратного вызова, когда отслеживаемый источник изменился.

Рассмотрим следующий пример:

Hello, Vue 3 Reactivity API!:)

 


 

Hello! My name is {{ fullName }}.

First Name: v-model="firstName" />

Last Name: v-model="lastName" />

 


 

Volume: {{volume}}


 

 


 

State: {{state}}


 

import { ref, computed, watch, watchEffect } from 'vue’;

export default {

setup () {

// computed

const firstName = ref ('David’)

const lastName = ref ('Wilson’)

const fullName = computed (() => {

return firstName.value + ' ' + lastName.value

})

// watchEffect

const volume = ref (0)

watchEffect (() => {

if (volume.value≠ 0 && volume.value% 3 == 0) {

alert («The volume’s value can be divided into 3»)

}

})

// watch

const state = ref ('playing’)

watch (state, (newValue, oldValue) =>

alert (`The state was changed from ${oldValue} to ${newValue}`)

)

return {

firstName,

lastName,

fullName,

volume,

state

}

}

};

В этом примере мы создаем fullNameвычисляемую переменную, которая основывает свои вычисления на ссылках firstNameи lastName. Затем в представлении добавляем два элемента управления вводом для редактирования двух частей полного имени. И, как мы видим, когда мы изменяем какую-либо часть, fullNameпроисходит перерасчет и результат обновляется.

Далее мы создаем volumeреф и устанавливаем для него эффект часов. Каждый раз volumeпри изменении эффект запускает функцию обратного вызова. Чтобы доказать это, мы добавляем в представление кнопку, которая увеличивает громкость на единицу. Мы устанавливаем условие в функции обратного вызова, которое проверяет, можно ли разделить значение объема на 3, и когда оно возвращает значение true, отображается предупреждающее сообщение. Эффект запускается один раз, когда приложение инициируется и устанавливается значение громкости, а затем снова каждый раз, когда значение громкости изменяется.

Наконец, мы создаем stateссылку и устанавливаем функцию отслеживания для отслеживания изменений. Как только stateизменения будут выполнены, функция обратного вызова будет выполнена. В этом примере мы добавляем кнопку, которая переключает состояние между playingи paused. Каждый раз, когда это происходит, отображается предупреждающее сообщение.

watchEffectи watchвыглядят почти одинаково с точки зрения функциональности, но у них есть некоторые отличия:

watchEffectрассматривает все реактивные свойства, включенные в функцию обратного вызова, как зависимости. Таким образом, если обратный вызов содержит три свойства, все они отслеживаются на наличие изменений неявным образом.

watchотслеживает только те свойства, которые мы включили в качестве аргументов обратного вызова. Кроме того, он предоставляет как предыдущее, так и текущее значение наблюдаемого свойства.

Как видите, API реактивности Vue 3 предлагает множество методов для различных вариантов использования. API довольно большой, и в этом руководстве я изучил только основы. Для более глубокого изучения, подробностей и пограничных случаев посетите документацию Reactivity API.

Вывод

В этой статье мы рассмотрели, что такое система реактивности и как она реализована в Vue 2 и Vue 3. Мы увидели, что у Vue 2 есть некоторые недостатки, которые успешно устранены в Vue 3. Реактивность Vue 3 — это полная переработка на основе современного JavaScript. Особенности. Резюмируем его преимущества и недостатки.

Преимущества:

Его можно использовать как отдельный пакет. Вы можете использовать его, например, с React.

Он предлагает гораздо больше гибкости и мощности благодаря многофункциональному API.

Он поддерживает больше структур данных (Map, WeakMap, Set, WeakSet).

Он имеет лучшую производительность. Только необходимые данные становятся реактивными.

Предупреждения о манипулировании данными из Vue 2 устранены.

Недостатки:

Он работает только в браузерах, поддерживающих ES6+.

Реактивный прокси не равен исходному объекту с точки зрения сравнения идентичности (===).

Это требует больше кода по сравнению с «автоматической» реактивностью Vue 2.

Суть в том, что реактивность Vue 3 — это гибкая и мощная система, которую могут использовать как разработчики Vue, так и не-Vue. Каким бы ни был ваш случай, просто возьмите его и начните создавать удивительные вещи.

Делитесь нашими материалами с друзьями!

 

 

Заказать разработку сайта