Skip to content

Commit 28f360b

Browse files
committed
reactivity in depth translated
1 parent f1e084c commit 28f360b

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed

src/guide/reactivity.md

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,80 +4,80 @@ type: guide
44
order: 15
55
---
66

7-
We've covered most of the basics - now it's time to take a deep dive! One of Vue's most distinct features is the unobtrusive reactivity system. Models are just plain JavaScript objects. When you modify them, the view updates. It makes state management very simple and intuitive, but it's also important to understand how it works to avoid some common gotchas. In this section, we are going to dig into some of the lower-level details of Vue's reactivity system.
7+
Мы разобрали большую часть основ — пришло время нырнуть поглубже! Одна из наиболее примечательных возможностей Vue — это ненавязчивая реактивность. Модели — это просто простые JavaScript-объекты. Когда вы изменяете их, представление данных обновляется. Управление состоянием приложения, таким образом, становится очень простым и интуитивно-понятным. Но для того чтобы избежать распространённых неприятностей, необходимо понимать, как это работает. В этой секции руководства мы немного покопаемся в низкоуровневых деталях реализации системы реактивности Vue.
88

9-
## How Changes Are Tracked
9+
## Как Отслеживаются Изменения
1010

11-
When you pass a plain JavaScript object to a Vue instance as its `data` option, Vue will walk through all of its properties and convert them to getter/setters using [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). This is an ES5-only and un-shimmable feature, which is why Vue doesn't support IE8 and below.
11+
Когда вы передаёте в инстанс Vue простой JavaScript-объект в качестве опции `data`, Vue проходит по всем его полям и превращаит их в пары геттеров/сеттеров, используя [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty). Эта возможность имеется в JavaScript только начиная с версии ES5, и в более ранних версиях её сэмулировать не удаётся — по этой-то причине Vue и не поддерживает браузеры IE8 и старше.
1212

13-
The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified. One caveat is that browser consoles format getter/setters differently when converted data objects are logged, so you may want to install [vue-devtools](https://github.com/vuejs/vue-devtools) for a more inspection-friendly interface.
13+
Геттеры/сеттеры не видны пользователю, но именно они являются тем внутренним механизмом, что позволяет Vue отслеживать зависимости и детектировать изменение данных. Одним из недостатков этого подхода является то, что консоли браузера обычно форматируют геттеры/сеттеры отличным образом от обыкновенных объектов при их логировании, поэтому вам может пригодится [vue-devtools](https://github.com/vuejs/vue-devtools) с более удобным интерфейсом.
1414

15-
Every component instance has a corresponding **watcher** instance, which records any properties "touched" during the component's render as dependencies. Later on when a dependency's setter is triggered, it notifies the watcher, which in turn causes the component to re-render.
15+
Каждый инстанс компонента имеет связанный с ним инстанс **наблюдателя**, который помечает все "затронутые" при рендеринге компонента поля как зависимости. В дальнейшем, когда вызывается сеттер помеченного как зависимость поля, он уведомляет наблюдателя, который в свою очередь инициирует перерендеринг компонента.
1616

17-
![Reactivity Cycle](/images/data.png)
17+
![Цикл Реактивности](/images/data.png)
1818

19-
## Change Detection Caveats
19+
## Проблемы с Определением Изменений
2020

21-
Due to the limitations of modern JavaScript (and the abandonment of `Object.observe`), Vue **cannot detect property addition or deletion**. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the `data` object in order for Vue to convert it and make it reactive. For example:
21+
В силу ограничений современного JavaScript (и отказа от `Object.observe`), Vue **не может определить добавление или удаление свойства**. Поскольку Vue производит превращение полев в пары геттер/сеттер в процессе инициализации инстанса, все поля должны присутствовать в объекте `data` изначально, чтобы быть сконвертированы и стать реактивными. Например:
2222

2323
``` js
2424
var vm = new Vue({
2525
data: {
2626
a: 1
2727
}
2828
})
29-
// `vm.a` is now reactive
29+
// `vm.a` теперь — реактивное поле
3030

3131
vm.b = 2
32-
// `vm.b` is NOT reactive
32+
// `vm.b` НЕ реактивно
3333
```
3434

35-
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it's possible to add reactive properties to a nested object using the `Vue.set(object, key, value)` method:
35+
Vue не позволяет динамическое добавление новых корневых реактивных свойств в уже существующий инстанс. Однако, возможно добавление реактивных свойств во вложенные объекты, используя метод `Vue.set(object, key, value)`:
3636

3737
``` js
3838
Vue.set(vm.someObject, 'b', 2)
3939
```
4040

41-
You can also use the `vm.$set` instance method, which is just an alias to the global `Vue.set`:
41+
Вы можете также использовать метод инстанса `vm.$set`, который является просто псевдонимом к глобальному `Value.set`:
4242

4343
``` js
4444
this.$set(this.someObject, 'b', 2)
4545
```
4646

47-
Sometimes you may want to assign a number of properties to an existing object, for example using `Object.assign()` or `_.extend()`. However, new properties added to the object will not trigger changes. In such cases, create a fresh object with properties from both the original object and the mixin object:
47+
Иногда вы можете захотеть добавить несколько свойств в существующий объект, например используя `Object.assign()` или `_.extend()`. Однако, новые свойства, добавленные к объекту, не вызовут реактивной обработки изменений. В таких случаях, создавайте новый объект, содержащий поля как оригинального объекта, так и объекта-примеси:
4848

4949
``` js
50-
// instead of `Object.assign(this.someObject, { a: 1, b: 2 })`
50+
// вместо `Object.assign(this.someObject, { a: 1, b: 2 })`
5151
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
5252
```
5353

54-
There are also a few array-related caveats, which were discussed earlier in the [list rendering section](/guide/list.html#Caveats).
54+
Существует также несколько ограничений, связанных с массивами. Их мы рассмотрели ранее в [секции об отображении списков](/guide/list.html#Caveats).
5555

56-
## Declaring Reactive Properties
56+
## Объявление реактивных свойств
5757

58-
Since Vue doesn't allow dynamically adding root-level reactive properties, this means you have to initialize you instances by declaring all root-level reactive data properties upfront, even just with an empty value:
58+
Поскольку Vue не позволяет динамически добавлять корневые реактивные свойства, это означает что все корневые поля необходимо инициализировать изначально, хотя бы пустыми значениями:
5959

6060
``` js
6161
var vm = new Vue({
6262
data: {
63-
// declare message with an empty value
63+
// объявляем поле message со значением пустой строки
6464
message: ''
6565
},
6666
template: '<div>{{ message }}</div>'
6767
})
68-
// set `message` later
68+
// впоследствии задаём значение `message`
6969
vm.message = 'Hello!'
7070
```
7171

72-
If you don't declare `message` in the data option, Vue will warn you that the render function is trying to access a property that doesn't exist.
72+
Если поле `message` в опции data не указать, Vue предупредит вас что функция рендеринга пытается получить доступ к несуществующему свойству.
7373

74-
There are technical reasons behind this restriction - it eliminates a class of edge cases in the dependency tracking system, and also makes Vue instances play nicer with type checking systems. But there is also an important consideration in terms of code maintainability: the `data` object is like the schema for your component's state. Declaring all reactive properties upfront makes the component code easier to understand when revisited later or read by another developer.
74+
Есть технические причины для этого ограничения — оно позволяет устранить целый класс краевых случаев в системе учёта зависимостей, а так же позволяет Vue лучше взаимодействовать с системами проверки типов. Но кроме того существует ещё и важный момент с точки зрения поддерживаемости кода: объект `data` похож на схему для состояния вашего компонента. Явное объявление всех реактивных свойств делает код компонента проще для понимания при последующем прочтении, или для стороннего разработчика.
7575

76-
## Async Update Queue
76+
## Асинхронная Очередь Обновлений
7777

78-
In case you haven't noticed yet, Vue performs DOM updates **asynchronously**. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations. Then, in the next event loop "tick", Vue flushes the queue and performs the actual (already de-duped) work. Internally Vue tries native `Promise.then` and `MutationObserver` for the asynchronous queuing and falls back to `setTimeout(fn, 0)`.
78+
На случай если вы ещё не заметили: Vue выполняет обновления DOM **асинхронно**. Каждый раз, когда обнаруживается изменение в данных, создаётся очередь, в которую буферизируются все остальные изменения, происходящие в том же самом event loop. Если тот же наблюдатель вызывается несколько раз, в очередь он попадёт всё равно лишь единожды. Эта буферизация и де-дупликация важны, так как позволяют избежать излишних вычислений и манипуляций с DOM. Затем, по следующему "тику" event loop, Vue разбирает очередь и выполняет актуальную (уже не содержащую дубликатов) работу. Внутренние детали реализации этого процесса таковы: Vue пробует применить нативные `Promise.then` и `MutationObserver` для асинхронной постановки задач во очередь, а в случае их недоступности использует старую добрую `setTimeout(fn, 0)`.
7979

80-
For example, when you set `vm.someData = 'new value'`, the component will not re-render immediately. It will update in the next "tick", when the queue is flushed. Most of the time we don't need to care about this, but it can be tricky when you want to do something that depends on the post-update DOM state. Although Vue.js generally encourages developers to think in a "data-driven" fashion and avoid touching the DOM directly, sometimes it might be necessary to get your hands dirty. In order to wait until Vue.js has finished updating the DOM after a data change, you can use `Vue.nextTick(callback)` immediately after the data is changed. The callback will be called after the DOM has been updated. For example:
80+
Например, когда вы обновляете `vm.someData = 'new value'`, компонент не будет перерендерен сразу же. Он обновится на следующий "тик", при разборе очереди. Чаще всего у нас нет нужды принимать это в расчёт, но не если вы хотите сделать что-то, зависящее от состояния DOM после обновления. Хотя Vue в целом поощряет мышление "от данных" и не рекомендует напрямую трогать DOM, иногда приходится засучить рукава. Для того чтобы дождаться завершения обновления DOM после изменения данных, вы можете использовать `Vue.nextTick(callback)` сразу после того, как данные изменены. Функция обратного вызова будет вызвана после обновления DOM. Например:
8181

8282
``` html
8383
<div id="example">{{ message }}</div>
@@ -90,29 +90,29 @@ var vm = new Vue({
9090
message: '123'
9191
}
9292
})
93-
vm.message = 'new message' // change data
94-
vm.$el.textContent === 'new message' // false
93+
vm.message = 'новое сообщение' // изменяем данные
94+
vm.$el.textContent === 'новое сообщение' // false
9595
Vue.nextTick(function () {
96-
vm.$el.textContent === 'new message' // true
96+
vm.$el.textContent === 'новое сообщение' // true
9797
})
9898
```
9999

100-
There is also the `vm.$nextTick()` instance method, which is especially handy inside components, because it doesn't need global `Vue` and its callback's `this` context will be automatically bound to the current Vue instance:
100+
Существует также метод инстанса `vm.$nextTick()`, особенно удобный для использования внутри компонент, поскольку он не требует обращения к глобальной переменной `Vue`, а также автоматически связывает контекст `this` функции обратного вызова с текущим инстансом Vue:
101101

102102
``` js
103103
Vue.component('example', {
104104
template: '<span>{{ message }}</span>',
105105
data: function () {
106106
return {
107-
message: 'not updated'
107+
message: 'не обновлено'
108108
}
109109
},
110110
methods: {
111111
updateMessage: function () {
112-
this.message = 'updated'
113-
console.log(this.$el.textContent) // => 'not updated'
112+
this.message = 'обновлено'
113+
console.log(this.$el.textContent) // => 'не обновлено'
114114
this.$nextTick(function () {
115-
console.log(this.$el.textContent) // => 'updated'
115+
console.log(this.$el.textContent) // => 'обновлено'
116116
})
117117
}
118118
}

0 commit comments

Comments
 (0)