Skip to content

computed.md translation #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 18, 2020
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 52 additions & 52 deletions src/v2/guide/computed.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
---
title: Обчислювані властивості та спостерігачі
title: Обчислені поля та спостерігачі
type: guide
order: 5
---

## Computed Properties
## Обчислені поля
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Варто зауважити, що "поля" звично перекладаються з слова fields. Хоч це є синонімом в даному контексті, але я б лишив таки як Обчислювані властивості. Обчислені — це вже доконана дія, тобто більше обчислювання не очікується. Обчислювані — тому що вони постійно обчислюються при змінах в реактивних змінних, від яких вони залежать.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++


<div class="vueschool"><a href="https://vueschool.io/lessons/vuejs-computed-properties?friend=vuejs" target="_blank" rel="sponsored noopener" title="Learn how computed properties work with Vue School">Learn how computed properties work with a free lesson on Vue School</a></div>
<div class="vueschool"><a href="https://vueschool.io/lessons/vuejs-computed-properties?friend=vuejs" target="_blank" rel="sponsored noopener" title="Вивчи, як обчислені поля працюють з Vue School">Вивчи, як обчислені поля працюють на безкоштовних уроках Vue School</a></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Звертання на "ви" зараз вжито у інших сторінках даного перекладу. Думаю, добре було б так вживати скрізь заради консистентності.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++


In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example:
Шаблонні вирази дуже зручні, але вони призначені для простих операцій. Додавання великої кількості логіки до шаблонів може зробити їх переповненими і складними для підтримки. Наприклад:

``` html
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
```

At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it displays `message` in reverse. The problem is made worse when you want to include the reversed message in your template more than once.
Тепер шаблон більше не простий і декларативний. Тобі необхідно дивитися на нього протягом секунди щоб зрозуміти що він показує `message` в зворотньому напрямку. Проблема укладнюється якщо ти хочеш включити перевернуте повідомлення в шаблон більше одного разу.

That's why for any complex logic, you should use a **computed property**.
Ось чому для будь якої комплексної логіки тобі потрібно використовувати **обчислені поля**

### Basic Example
### Простий приклад

``` html
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
<p>Оригінальне повідомлення: "{{ message }}"</p>
<p>Обчислене перевернуте повідомлення: "{{ reversedMessage }}"</p>
</div>
```

Expand All @@ -36,21 +36,21 @@ var vm = new Vue({
message: 'Hello'
},
computed: {
// a computed getter
// обчислений поле
reversedMessage: function () {
// `this` points to the vm instance
// `this` вказую на екземпляр vm
return this.message.split('').reverse().join('')
}
}
})
```

Result:
Результат:

{% raw %}
<div id="example" class="demo">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
<p>Оригінальне повідомлення: "{{ message }}"</p>
<p>Обчислене перевернуте повідомлення: "{{ reversedMessage }}"</p>
</div>
<script>
var vm = new Vue({
Expand All @@ -67,38 +67,38 @@ var vm = new Vue({
</script>
{% endraw %}

Here we have declared a computed property `reversedMessage`. The function we provided will be used as the getter function for the property `vm.reversedMessage`:
Тут ми вказали обчислене поле `reversedMessage`. Функція, яку ми подали буде використовуватися як функція-читач для поля `vm.reversedMessage`:

``` js
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
```

You can open the console and play with the example vm yourself. The value of `vm.reversedMessage` is always dependent on the value of `vm.message`.
Ви можете відкрити консоль і гратися з vm з прикладу самостійно. Значення `vm.reversedMessage` завжди залежить від значення `vm.message`.

You can data-bind to computed properties in templates just like a normal property. Vue is aware that `vm.reversedMessage` depends on `vm.message`, so it will update any bindings that depend on `vm.reversedMessage` when `vm.message` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
Ви можете прив'язатися до обчислених полів в шаблонах так само як до звичайного поля. Vue відомо, що `vm.reversedMessage` залежить від `vm.message`, тому буде оновлено кожна прив'язка, яка залежить від `vm.reversedMessage`, коли `vm.message` змінюється. І найкраще це те, що ми створили це відношення залежності декларативно: обчислена функція читач не має побічних впливів, що робить її тестування і розуміння простішими.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

оновлено → оновлена
функція читач → функція-читач

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"функція-читач" замінив на "отримувач" для консистентності з наступним текстом


### Computed Caching vs Methods
### Обчислене Кешування проти Методів

You may have noticed we can achieve the same result by invoking a method in the expression:
Ви могли помітити, що ми можемо досягнути того ж самого результату викликом методу у виразі:

``` html
<p>Reversed message: "{{ reverseMessage() }}"</p>
<p>Перевернуте повідомлення: "{{ reverseMessage() }}"</p>
```

``` js
// in component
// в компоненті
methods: {
reverseMessage: function () {
return this.message.split('').reverse().join('')
}
}
```

Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on their reactive dependencies.** A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as `message` has not changed, multiple access to the `reversedMessage` computed property will immediately return the previously computed result without having to run the function again.
Замість обчсленого поля, ми можемо задати таку ж саму функцію в якості методу. Для кінцевого результату два підходи дійсно однакові. Однак, різниця в тому, що **обчислені поля кешовані основуючись на їх реактивних залежностях**. Обчислене поле буде перераховане тільки в тому випадку, якщо хоча б одна з його рективних залежностей змінилася. Тобто поки поле `message` не змінилося, багаторазовий доступ до обчисленого поля `reversedMessage` буде одразу повертати попередньо обчислений результат без необхідності знову викликати функцію.

This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
Це також означає, що наступне обчислене поле ніколи не буде оновлюватися, тому, що `Date.now()` не реактивна залежність:

``` js
computed: {
Expand All @@ -108,13 +108,13 @@ computed: {
}
```

In comparison, a method invocation will **always** run the function whenever a re-render happens.
Для порівняння, виклик методу **завжди** запускатиме функцію під час повторного відображення.

Why do we need caching? Imagine we have an expensive computed property **A**, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on **A**. Without caching, we would be executing **A**’s getter many more times than necessary! In cases where you do not want caching, use a method instead.
Навіщо нам потрібне кешування? Уявіть, що у нас є складне обчислене поле **A**, яке вимагає обробки в циклі величезного масиву та проведення багатьох обчислень. Тоді можемо мати інші обчислені поля, які в свою чергу залежать від **A**. Без кешування ми б запускали отримувач **A** набагато більше разів, ніж потрібно! У випадках, коли вам не потрібне кешування, скористайтеся методом.

### Computed vs Watched Property
### Обчислене проти Спостереженого поля

Vue does provide a more generic way to observe and react to data changes on a Vue instance: **watch properties**. When you have some data that needs to change based on some other data, it is tempting to overuse `watch` - especially if you are coming from an AngularJS background. However, it is often a better idea to use a computed property rather than an imperative `watch` callback. Consider this example:
Vue надає більш загальний спосіб оглядати і реагувати на зміни даних в екземплярі Vue: **спостережені поля**. Якщо у вас є деякі дані, які повинні змінюватись основуючись на інших даних, це провокує перевикористання `watch` - особливо якщо ви прийшли з підгрунтям AngularJS. Однак, часто кращою ідеєю є використання обчислених полів аніж імперативна функція виклику `watch`. Розглянемо цей приклад:

``` html
<div id="demo">{{ fullName }}</div>
Expand All @@ -139,7 +139,7 @@ var vm = new Vue({
})
```

The above code is imperative and repetitive. Compare it with a computed property version:
Вищевказаний код є імперативним та повторюваним. Порівняйте його з версією обчисленого поля:

``` js
var vm = new Vue({
Expand All @@ -156,21 +156,21 @@ var vm = new Vue({
})
```

Much better, isn't it?
Набагато краще, чи не так?

### Computed Setter
### Обчислений задавач

Computed properties are by default getter-only, but you can also provide a setter when you need it:
Обчислені поля за замовчуванням використовуються лише для отримання, але ви також можете надати задавач, коли вам це потрібно:

``` js
// ...
computed: {
fullName: {
// getter
// отримувач
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вище у Вашому перекладі setter було перекладено як "читач". Думаю, варто дотримуватися єдиної термінології. Як на мене, обидва "читач" та "отримувач" доводять думку до користувача. В парі з "задавач" слово "отримувач" звучить більш доцільно. На мою думку, варто "функцію-читач" перекласти теж як "функція-отримувач".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
// задавач
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
Expand All @@ -180,14 +180,13 @@ computed: {
}
// ...
```
Тепер, коли ви запустите `vm.fullName = 'John Doe'`, задавач буде викликано, і` vm.firstName` та `vm.lastName` буде оновлено відповідно.

Now when you run `vm.fullName = 'John Doe'`, the setter will be invoked and `vm.firstName` and `vm.lastName` will be updated accordingly.

## Watchers
## Спостерігачі

While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That's why Vue provides a more generic way to react to data changes through the `watch` option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
Хоча обчислені поля є більш доцільними у більшості випадків, є випадки, коли спеціальний спостерігач необхідний. Ось чому Vue пропонує більш загальний спосіб реагування на зміни даних за допомогою опції `watch`. Це найбільш корисно, коли ви хочете виконувати асинхронні чи складні операції у відповідь на зміну даних.

For example:
Наприклад:

``` html
<div id="watch-example">
Expand All @@ -200,10 +199,10 @@ For example:
```

``` html
<!-- Since there is already a rich ecosystem of ajax libraries -->
<!-- and collections of general-purpose utility methods, Vue core -->
<!-- is able to remain small by not reinventing them. This also -->
<!-- gives you the freedom to use what you're familiar with. -->
<!-- Оскільки вже існує багата екосистема бібліотек ajax -->
<!-- і колекції методів загального призначення, база Vue -->
<!-- здатна залишатися малою, не вигадуючи їх. Це також -->
<!-- дає вам свободу використовувати те, що вам знайоме. -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
Expand All @@ -214,20 +213,20 @@ var watchExampleVM = new Vue({
answer: 'I cannot give you an answer until you ask a question!'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хіба не варто перекладати дані рядки в прикладах теж? Це б їх зробило більше ближчими для користувача.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

},
watch: {
// whenever question changes, this function will run
// ця функція буде запускатися кожного разу коли змінюватиметься `question`
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
created: function () {
// _.debounce is a function provided by lodash to limit how
// often a particularly expensive operation can be run.
// In this case, we want to limit how often we access
// yesno.wtf/api, waiting until the user has completely
// finished typing before making the ajax request. To learn
// more about the _.debounce function (and its cousin
// _.throttle), visit: https://lodash.com/docs#debounce
// _.debounce - це функція, надана lodash для обмеження частоти
// з якою може бути запущена особливо складна операція.
// У цьому випадку ми хочемо обмежити, як часто ми отримуємо доступ
// до yesno.wtf/api, чекаючи, коли користувач повністю завершить
// вводити текст, перш ніж робити ajax запит. Для
// докладнішого вивчення про функцію _.debounce (та його двоюрідного брата
// _.throttle), відвідайте: https://lodash.com/docs#debounce
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
},
methods: {
Expand Down Expand Up @@ -300,6 +299,7 @@ var watchExampleVM = new Vue({
</script>
{% endraw %}

In this case, using the `watch` option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property.
У цьому випадку використання `watch` дозволяє нам виконувати асинхронну операцію (доступ до API), обмежувати частоту виконання цієї операції та встановлювати проміжні стани, поки ми не отримаємо остаточну відповідь. Нічого з цього не було б можливим із обчисленим полем.

Окрім `watch`, ви також можете використовувати імперативний [vm.$watch API](../api/#vm-watch).

In addition to the `watch` option, you can also use the imperative [vm.$watch API](../api/#vm-watch).