You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/guide/essentials/computed.md
+30-30Lines changed: 30 additions & 30 deletions
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
-
# Computed Properties
1
+
# Thuộc tính computed
2
2
3
-
## Basic Example
3
+
## Ví dụ cơ bản
4
4
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:
6
6
7
7
<divclass="options-api">
8
8
@@ -39,16 +39,16 @@ const author = reactive({
39
39
40
40
</div>
41
41
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:
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.
50
50
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:
52
52
53
53
<divclass="options-api">
54
54
@@ -81,15 +81,15 @@ export default {
81
81
<span>{{ publishedBooksMessage }}</span>
82
82
```
83
83
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=)
85
85
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`.
87
87
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.
89
89
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.
91
91
92
-
See also: [Typing Computed Properties](/guide/typescript/options-api.html#typing-computed-properties) <supclass="vt-badge ts" />
92
+
Xem thêm: [Đặt kiểu cho computed property](/guide/typescript/options-api.html#typing-computed-properties) <supclass="vt-badge ts" />
[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==)
124
124
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`.
126
126
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.
128
128
129
-
See also: [Typing Computed](/guide/typescript/composition-api.html#typing-computed) <supclass="vt-badge ts" />
129
+
Xem thêm: [Đặt kiểu cho thuộc tính computed](/guide/typescript/composition-api.html#typing-computed) <supclass="vt-badge ts" />
130
130
131
131
</div>
132
132
133
-
## Computed Caching vs Methods
133
+
## So sánh computed được cache và method
134
134
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:
136
136
137
137
```vue-html
138
138
<p>{{ calculateBooksMessage() }}</p>
@@ -162,9 +162,9 @@ function calculateBooksMessage() {
162
162
163
163
</div>
164
164
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.
166
166
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.
168
168
169
169
<divclass="options-api">
170
170
@@ -186,13 +186,13 @@ const now = computed(() => Date.now())
186
186
187
187
</div>
188
188
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.
190
190
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 là`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.
192
192
193
-
## Writable Computed
193
+
## Thuộc tính computed có thể ghi
194
194
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 và setter cho nó:
196
196
197
197
<divclass="options-api">
198
198
@@ -220,7 +220,7 @@ export default {
220
220
}
221
221
```
222
222
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`và`this.lastName`sẽ được cập nhật tương ứng.
224
224
225
225
</div>
226
226
@@ -247,16 +247,16 @@ const fullName = computed({
247
247
</script>
248
248
```
249
249
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.
251
251
252
252
</div>
253
253
254
-
## Best Practices
254
+
## Lời khuyên khi dùng thuộc tính computed
255
255
256
-
### Getters should be side-effect free
256
+
### Getter không nên có hiệu ứng phụ
257
257
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).
259
259
260
-
### Avoid mutating computed value
260
+
### Tránh thay đổi các giá trị đã tính
261
261
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