Skip to content

Commit 9e19b31

Browse files
docs: translate file src/guide/essentials/computed.md (#17)
Co-authored-by: Phan An <[email protected]>
1 parent 3783578 commit 9e19b31

File tree

1 file changed

+30
-30
lines changed

1 file changed

+30
-30
lines changed

src/guide/essentials/computed.md

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Computed Properties
1+
# Thuộc tính computed
22

3-
## Basic Example
3+
## Ví dụ cơ bản
44

5-
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, if we have an object with a nested array:
5+
Các biểu thức (expression) trong template rất tiện lợi, nhưng chỉ nên dùng cho các tác vụ đơn giản. Đặt quá nhiều logic có thể template phình to ra và khó bảo trì. Ví dụ, nếu chúng ta có object trong chứa một mảng:
66

77
<div class="options-api">
88

@@ -39,16 +39,16 @@ const author = reactive({
3939

4040
</div>
4141

42-
And we want to display different messages depending on if `author` already has some books or not:
42+
Và chúng ta muốn hiển thị những thông điệp khác nhau dựa trên điều kiện `author` đã có sách hay chưa:
4343

4444
```vue-html
4545
<p>Has published books:</p>
4646
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
4747
```
4848

49-
At this point, the template is getting a bit cluttered. We have to look at it for a second before realizing that it performs a calculation depending on `author.books`. More importantly, we probably don't want to repeat ourselves if we need to include this calculation in the template more than once.
49+
Tại điểm này, template �bắt đầu trở nên lộn xộn. �Ta phải mất một chút mới nhận ra là template thực hiện một tính toán dựa trên `author.books`. Quan trọng hơn, chúng ta không muốn lặp lại code nếu cần thêm tính toán này vào template nhiều lần.
5050

51-
That's why for complex logic that includes reactive data, it is recommended to use a **computed property**. Here's the same example, refactored:
51+
Đó là lý do vì sao đối với những logic phức tạp có kèm dữ liệu reactive, bạn nên sử dụng một **thuộc tính computed**. Đây là ví dụ trên được viết lại:
5252

5353
<div class="options-api">
5454

@@ -81,15 +81,15 @@ export default {
8181
<span>{{ publishedBooksMessage }}</span>
8282
```
8383

84-
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYXV0aG9yOiB7XG4gICAgICAgIG5hbWU6ICdKb2huIERvZScsXG4gICAgICAgIGJvb2tzOiBbXG4gICAgICAgICAgJ1Z1ZSAyIC0gQWR2YW5jZWQgR3VpZGUnLFxuICAgICAgICAgICdWdWUgMyAtIEJhc2ljIEd1aWRlJyxcbiAgICAgICAgICAnVnVlIDQgLSBUaGUgTXlzdGVyeSdcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgY29tcHV0ZWQ6IHtcbiAgICBwdWJsaXNoZWRCb29rc01lc3NhZ2UoKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdXRob3IuYm9va3MubGVuZ3RoID4gMCA/ICdZZXMnIDogJ05vJ1xuICAgIH1cbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPHA+SGFzIHB1Ymxpc2hlZCBib29rczo8L3A+XG4gIDxzcGFuPnt7IGF1dGhvci5ib29rcy5sZW5ndGggPiAwID8gJ1llcycgOiAnTm8nIH19PC9zcGFuPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
84+
[Thử trong Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYXV0aG9yOiB7XG4gICAgICAgIG5hbWU6ICdKb2huIERvZScsXG4gICAgICAgIGJvb2tzOiBbXG4gICAgICAgICAgJ1Z1ZSAyIC0gQWR2YW5jZWQgR3VpZGUnLFxuICAgICAgICAgICdWdWUgMyAtIEJhc2ljIEd1aWRlJyxcbiAgICAgICAgICAnVnVlIDQgLSBUaGUgTXlzdGVyeSdcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgY29tcHV0ZWQ6IHtcbiAgICBwdWJsaXNoZWRCb29rc01lc3NhZ2UoKSB7XG4gICAgICByZXR1cm4gdGhpcy5hdXRob3IuYm9va3MubGVuZ3RoID4gMCA/ICdZZXMnIDogJ05vJ1xuICAgIH1cbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPHA+SGFzIHB1Ymxpc2hlZCBib29rczo8L3A+XG4gIDxzcGFuPnt7IGF1dGhvci5ib29rcy5sZW5ndGggPiAwID8gJ1llcycgOiAnTm8nIH19PC9zcGFuPlxuPC90ZW1wbGF0ZT4iLCJpbXBvcnQtbWFwLmpzb24iOiJ7XG4gIFwiaW1wb3J0c1wiOiB7XG4gICAgXCJ2dWVcIjogXCJodHRwczovL3NmYy52dWVqcy5vcmcvdnVlLnJ1bnRpbWUuZXNtLWJyb3dzZXIuanNcIlxuICB9XG59In0=)
8585

86-
Here we have declared a computed property `publishedBooksMessage`.
86+
Ở đây chúng ta đã khai báo một thuộc tính computed `publishedBooksMessage`.
8787

88-
Try to change the value of the `books` array in the application `data` and you will see how `publishedBooksMessage` is changing accordingly.
88+
Thử thay đổi giá trị của mảng `books` trong `data` của app và bạn sẽ thấy `publishedBooksMessage` thay đổi tương ứng.
8989

90-
You can data-bind to computed properties in templates just like a normal property. Vue is aware that `this.publishedBooksMessage` depends on `this.author.books`, so it will update any bindings that depend on `this.publishedBooksMessage` when `this.author.books` changes.
90+
Bạn có thể ràng buộc (data-bind) các thuộc tính computed vào template giống bình thường. Vue biết rằng `this.publishedBooksMessage` phụ thuộc vào `this.author.books` và sẽ cập nhật mọi ràng buộc phụ thuộc vào `this.publishedBooksMessage` khi `this.author.books` thay đổi.
9191

92-
See also: [Typing Computed Properties](/guide/typescript/options-api.html#typing-computed-properties) <sup class="vt-badge ts" />
92+
Xem thêm: [Đặt kiểu cho computed property](/guide/typescript/options-api.html#typing-computed-properties) <sup class="vt-badge ts" />
9393

9494
</div>
9595

@@ -120,19 +120,19 @@ const publishedBooksMessage = computed(() => {
120120
</template>
121121
```
122122

123-
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlYWN0aXZlLCBjb21wdXRlZCB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgYXV0aG9yID0gcmVhY3RpdmUoe1xuICBuYW1lOiAnSm9obiBEb2UnLFxuICBib29rczogW1xuICAgICdWdWUgMiAtIEFkdmFuY2VkIEd1aWRlJyxcbiAgICAnVnVlIDMgLSBCYXNpYyBHdWlkZScsXG4gICAgJ1Z1ZSA0IC0gVGhlIE15c3RlcnknXG4gIF1cbn0pXG5cbi8vIGEgY29tcHV0ZWQgcmVmXG5jb25zdCBwdWJsaXNoZWRCb29rc01lc3NhZ2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gIHJldHVybiBhdXRob3IuYm9va3MubGVuZ3RoID4gMCA/ICdZZXMnIDogJ05vJ1xufSlcbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxwPkhhcyBwdWJsaXNoZWQgYm9va3M6PC9wPlxuICA8c3Bhbj57eyBwdWJsaXNoZWRCb29rc01lc3NhZ2UgfX08L3NwYW4+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
123+
[Thử trong Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlYWN0aXZlLCBjb21wdXRlZCB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgYXV0aG9yID0gcmVhY3RpdmUoe1xuICBuYW1lOiAnSm9obiBEb2UnLFxuICBib29rczogW1xuICAgICdWdWUgMiAtIEFkdmFuY2VkIEd1aWRlJyxcbiAgICAnVnVlIDMgLSBCYXNpYyBHdWlkZScsXG4gICAgJ1Z1ZSA0IC0gVGhlIE15c3RlcnknXG4gIF1cbn0pXG5cbi8vIGEgY29tcHV0ZWQgcmVmXG5jb25zdCBwdWJsaXNoZWRCb29rc01lc3NhZ2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gIHJldHVybiBhdXRob3IuYm9va3MubGVuZ3RoID4gMCA/ICdZZXMnIDogJ05vJ1xufSlcbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxwPkhhcyBwdWJsaXNoZWQgYm9va3M6PC9wPlxuICA8c3Bhbj57eyBwdWJsaXNoZWRCb29rc01lc3NhZ2UgfX08L3NwYW4+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
124124

125-
Here we have declared a computed property `publishedBooksMessage`. The `computed()` function expects to be passed a getter function, and the returned value is a **computed ref**. Similar to normal refs, you can access the computed result as `publishedBooksMessage.value`. Computed refs are also auto-unwrapped in templates so you can reference them without `.value` in template expressions.
125+
Ở đây chúng ta đã khai báo một thuộc tính computed `publishedBooksMessage`. Hàm `computed()` nhận vào một hàm getter (hàm dùng để lấy giá trị), và giá trị được trả về là một **computed ref (tham chiếu)**. Tương tự như các ref thông thường, bạn có thể truy cập giá trị của nó thông qua `publishedBooksMessage.value`. Khi dùng trong template, `ref`sẽ được unwrap tự động nên bạn có thể tham chiếu tới nó mà không cần `.value`.
126126

127-
A computed property automatically tracks its reactive dependencies. Vue is aware that the computation of `publishedBooksMessage` depends on `author.books`, so it will update any bindings that depend on `publishedBooksMessage` when `author.books` changes.
127+
Một thuộc tính computed sẽ tự động theo dõi các phụ thuộc có tính reactive. Vue biết rằng giá trị của `publishedBooksMessage` phụ thuộc vào `author.books`, nên nó sẽ cập nhật mọi ràng buộc vào `publishedBooksMessage` khi `author.books` thay đổi.
128128

129-
See also: [Typing Computed](/guide/typescript/composition-api.html#typing-computed) <sup class="vt-badge ts" />
129+
Xem thêm: [Đặt kiểu cho thuộc tính computed](/guide/typescript/composition-api.html#typing-computed) <sup class="vt-badge ts" />
130130

131131
</div>
132132

133-
## Computed Caching vs Methods
133+
## So sánh computed được cache và method
134134

135-
You may have noticed we can achieve the same result by invoking a method in the expression:
135+
Có thể bạn đã để ý rằng chúng ta có thể đạt được kết quả tương tự bằng cách dùng gọi một phương thức:
136136

137137
```vue-html
138138
<p>{{ calculateBooksMessage() }}</p>
@@ -162,9 +162,9 @@ function calculateBooksMessage() {
162162

163163
</div>
164164

165-
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 `author.books` has not changed, multiple access to `publishedBooksMessage` will immediately return the previously computed result without having to run the getter function again.
165+
Chúng ta có thể định nghĩa chính hàm của thuộc tính computed dạng một phương thức. Hai cách tiếp cận đều cho kết quả hoàn toàn như nhau. Tuy nhiên, điều khác biệt ở đây là **các thuộc tính computed được cache dựa trên những sự phụ thuộc có tính reactive của nó.** Một thuộc tính computed sẽ chỉ được tính lại khi một số sự phụ thuộc của nó thay đổi. Điều này có nghĩa là miễn `author.books` không thay đổi, thì mọi lần truy cập vào `publishedBooksMessage` đều ngay lập tức trả về kết quả đã được tính toán trước đó mà không chạy lại hàm getter.
166166

167-
This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
167+
Điều này cũng có nghĩa là thuộc tính computed dưới đây sẽ không bao giờ được cập nhật, bởi vì `Date.now()` không phải là một sự phụ thuộc có tính reactive.
168168

169169
<div class="options-api">
170170

@@ -186,13 +186,13 @@ const now = computed(() => Date.now())
186186

187187
</div>
188188

189-
In comparison, a method invocation will **always** run the function whenever a re-render happens.
189+
Trong khi đó, một lệnh gọi phương thức sẽ **luôn** chạy hàm đó bất cứ khi nào việc render lại xảy ra.
190190

191-
Why do we need caching? Imagine we have an expensive computed property `list`, 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 `list`. Without caching, we would be executing `list`’s getter many more times than necessary! In cases where you do not want caching, use a method call instead.
191+
Tại sao chúng ta cần cache? Giả sử ta có một thuộc tính computed `list`, thuộc tính này đòi hỏi lặp qua một mảng khổng lồ và thực hiện rất nhiều phép tính. Tiếp theo đó, chúng ta có thể có những thuộc tính computed khác phụ thuộc vào `list`. Nếu không có cache, chúng ta sẽ phải thực thi hàm getter của `list` nhiều hơn mức cần thiết rất nhiều! Trong những trường hợp bạn không muốn cache, hãy sử dụng phương thức thay vì thuộc tính computed.
192192

193-
## Writable Computed
193+
## Thuộc tính computed có thể ghi
194194

195-
Computed properties are by default getter-only. If you attempt to assign a new value to a computed property, you will receive a runtime warning. In the rare cases where you need a "writable" computed property, you can create one by providing both a getter and a setter:
195+
Mặc định thì những thuộc tính computed là chỉ đọc (chỉ có getter). Nếu bạn cố ghi giá trị mới vào một thuộc tính computed, bạn sẽ nhận được một cảnh báo runtime. Trong các trường hợp hãn hữu bạn cần một thuộc tính computed có thể ghi, bạn có thể cung cấp cả getter setter cho nó:
196196

197197
<div class="options-api">
198198

@@ -220,7 +220,7 @@ export default {
220220
}
221221
```
222222

223-
Now when you run `this.fullName = 'John Doe'`, the setter will be invoked and `this.firstName` and `this.lastName` will be updated accordingly.
223+
Giờ khi bạn chạy `this.fullName = 'John Doe'`, setter sẽ được gọi rồi `this.firstName` `this.lastName` sẽ được cập nhật tương ứng.
224224

225225
</div>
226226

@@ -247,16 +247,16 @@ const fullName = computed({
247247
</script>
248248
```
249249

250-
Now when you run `fullName.value = 'John Doe'`, the setter will be invoked and `firstName` and `lastName` will be updated accordingly.
250+
Giờ khi bạn chạy `fullName.value = 'John Doe'`, setter sẽ được gọi rồi `firstName` vả `lastName` sẽ được cập nhật tương ứng.
251251

252252
</div>
253253

254-
## Best Practices
254+
## Lời khuyên khi dùng thuộc tính computed
255255

256-
### Getters should be side-effect free
256+
### Getter không nên có hiệu ứng phụ
257257

258-
It is important to remember that computed getter functions should only perform pure computation and be free of side effects. For example, don't make async requests or mutate the DOM inside a computed getter! Think of a computed property as declaratively describing how to derive a value based on other values - its only responsibility should be computing and returning that value. Later in the guide we will discuss how we can perform side effects in reaction to state changes with [watchers](./watchers).
258+
Điều quan trọng cần phải nhớ là hàm getter chỉ nên thực hiện duy nhất một việc tính toán đơn thuần và không có hiệu ứng phụ. Ví dụ, đừng tạo một request đồng bộ hoặc thay đổi DOM bên trong một hàm getter! Hãy xem thuộc tính computed như một khai báo về cách để lấy giá trị dựa trên những giá trị khác – nó chỉ có trách nhiệm tính toán và trả về giá trị đó mà thôi. Ở phần sau của hướng dẫn, chúng ta sẽ thảo luận về cách để thực hiện một hiệu ứng phụ dựa trên sự thay đổi của state bằng [watcher](./watchers).
259259

260-
### Avoid mutating computed value
260+
### Tránh thay đổi các giá trị đã tính
261261

262-
The returned value from a computed property is derived state. Think of it as a temporary snapshot - every time the source state changes, a new snapshot is created. It does not make sense to mutate a snapshot, so a computed return value should be treated as read-only and never be mutated - instead, update the source state it depends on to trigger new computations.
262+
Giá trị được trả về từ một thuộc tính computed là trạng thái được suy luận ra. Hãy xem nó như một snapshot (ảnh chụp) tạm thời – mỗi khi các trạng thái mà nó phụ thuộc bị thay đổi, thì một snapshot mới được tạo ra. Việc thay đổi một snapshot là không hợp lý, vậy một giá trị được trả về bởi computed nên được xem là chỉ đọc và không bao giờ bị thay đổi – thay vào đó, hãy cập nhật trạng thái mà nó phụ thuộc để kích hoạt những tính toán mới.

0 commit comments

Comments
 (0)