Mục lục

1. Diagram

2. Tổng quan

3. Basic Example

4. Computed Caching vs Methods

5. Writable Computed

6. Getting Previous Value (Vue 3.4+)

7. Best Practices

8. Common Use Cases

9. Kết luận


1. Diagram

Computed Properties Flow

            Component Instance (Data / Methods / Computed)
                           |
                           v
                    Vue Template (HTML-based)
                           |
        ------------------------------------------------
        |                      |                      |
   {{ interpolation }}     v-bind / :attr         v-on / @event
        |                      |                      |
     Text Node           Attribute Binding        Event Listener
        |                      |                      |
        -------------------- Reactivity --------------------
                           |
                           v
                    Virtual DOM Diff
                           |
                           v
                       Real DOM Update

Computed vs Methods

+-------------------+      +-------------------+
|   Computed Prop   |      |      Method       |
+-------------------+      +-------------------+
| - Định nghĩa trong |      | - Định nghĩa trong |
|   phần `computed` |      |   phần `methods`  |
| - Tự động tính toán|      | - Cần gọi thủ công|
|   và cập nhật      |      |   khi sử dụng     |
| - Luôn luôn trả về  |      | - Có thể trả về   |
|   giá trị mới nhất  |      |   giá trị tĩnh    |
+-------------------+      +-------------------+

Writable Computed

+-------------------+      +-------------------+
|   Read-only CP    |      |   Writable CP     |
+-------------------+      +-------------------+
| - Không thể gán giá|      | - Có thể gán giá  |
|   trị mới         |      |   trị mới         |
| - Sử dụng khi chỉ  |      | - Sử dụng khi cần |
|   cần đọc dữ liệu  |      |   thay đổi dữ liệu |
+-------------------+      +-------------------+

Dependency Tracking

+-------------------+      +-------------------+
|   Computed Prop   |      |   Writable Prop   |
+-------------------+      +-------------------+
| - Theo dõi sự thay|      | - Theo dõi sự thay|
|   đổi của phụ thuộc|      |   đổi của phụ thuộc|
| - Tự động cập nhật  |      | - Cần gọi hàm cập |
|   khi phụ thuộc thay|      |   nhật thủ công   |
+-------------------+      +-------------------+

Performance Comparison

+-------------------+      +-------------------+
|   Computed Prop   |      |      Method       |
+-------------------+      +-------------------+
| - Được tối ưu hóa  |      | - Không được tối  |
|   cho hiệu suất cao|      |   ưu hóa tự động  |
| - Thích hợp cho các |      | - Thích hợp cho các|
|   phép tính nặng   |      |   tác vụ nhẹ      |
+-------------------+      +-------------------+

2. Tổng quan

  • Computed properties là gì?
    • Là các thuộc tính được tính toán tự động dựa trên dữ liệu phản ứng (reactive data).
    • Giúp tối ưu hiệu suất và tổ chức code tốt hơn.
  • Khi nào nên dùng computed properties?
    • Khi cần tính toán giá trị từ dữ liệu mà không muốn viết logic phức tạp trong template.
    • Khi cần theo dõi và phản ứng với sự thay đổi của dữ liệu.

3. Basic Example

Vấn đề với Template Expression

  • Giả sử có một bài toán đơn giản: hiển thị tên đầy đủ dựa trên tên và họ.
  • Dùng template expression:
    <span></span>
    
  • Vấn đề:
    • Nếu tên hoặc họ thay đổi, Vue sẽ phải re-render toàn bộ phần tử.
    • Không tối ưu cho hiệu suất.

Giải pháp: Computed Property

  • Định nghĩa computed property trong component:
    computed: {
      fullName() {
        return this.firstName + ' ' + this.lastName;
      }
    }
    
  • Sử dụng trong template:
    <span></span>
    
  • Lợi ích:
    • Tối ưu hiệu suất: chỉ re-render khi firstName hoặc lastName thay đổi.
    • Code rõ ràng, dễ bảo trì.

4. Computed Caching vs Methods

So sánh

Tiêu chí Computed Properties Methods
Định nghĩa Trong phần computed của component Trong phần methods của component
Gọi hàm Tự động khi phụ thuộc thay đổi Cần gọi thủ công trong template
Caching Có, giá trị được lưu cache Không, luôn luôn tính toán lại
Hiệu suất Tối ưu hơn, nhất là với phép tính nặng Thấp hơn, vì không có caching

Ví dụ

  • Ví dụ về computed properties:
    computed: {
      // Giá trị đầy đủ của người dùng
      fullName() {
        return `${this.firstName} ${this.lastName}`;
      },
      // Kiểm tra người dùng đã đăng nhập hay chưa
      isLoggedIn() {
        return !!this.userToken;
      }
    }
    
  • Ví dụ về methods:
    methods: {
      // Đăng nhập người dùng
      login() {
        // Gọi API đăng nhập
      },
      // Đăng xuất người dùng
      logout() {
        // Xóa token, thông tin người dùng
      }
    }
    

Khi nào computed KHÔNG update?

  • Khi nào computed properties không tự động cập nhật giá trị?
    • Khi không có sự thay đổi nào ở các thuộc tính phụ thuộc.
    • Khi component không re-render do các lý do khác (ví dụ: không có sự kiện nào xảy ra).

5. Writable Computed

Mặc định: Read-only

  • Computed properties trong Vue mặc định là read-only.
  • Nghĩa là không thể gán giá trị mới cho computed property.
  • Ví dụ:
    computed: {
      // Computed property chỉ đọc
      readOnlyProp() {
        return this.someData;
      }
    }
    
  • Nếu cố gắng gán giá trị:
    this.readOnlyProp = "new value"; // Không được phép
    

Tạo Writable Computed

  • Để tạo writable computed, cần định nghĩa cả getter và setter.
  • Ví dụ:
    computed: {
      // Computed property có thể ghi
      writableProp: {
        // Getter
        get() {
          return this.someData;
        },
        // Setter
        set(value) {
          this.someData = value;
        }
      }
    }
    
  • Sử dụng trong template:
    <input v-model="writableProp" />
    

Use Case

  • Khi nào nên sử dụng writable computed?
    • Khi cần một thuộc tính vừa có thể đọc, vừa có thể ghi.
    • Khi muốn kết hợp giữa computed properties và v-model.

6. Getting Previous Value (Vue 3.4+)

Read-only Computed

  • Từ Vue 3.4, có thể dễ dàng lấy giá trị trước đó của một computed property.
  • Ví dụ:
    computed: {
      // Lấy giá trị trước đó của fullName
      previousFullName: {
        get() {
          return this.$options.computed.fullName.call(this, true);
        },
        // Không định nghĩa setter, chỉ đọc
      }
    }
    

Writable Computed

  • Với writable computed, cũng có thể lấy giá trị trước đó tương tự như read-only.
  • Ví dụ:
    computed: {
      // Lấy giá trị trước đó của writableProp
      previousWritableProp: {
        get() {
          return this.$options.computed.writableProp.get.call(this, true);
        },
        set(value) {
          this.$options.computed.writableProp.set.call(this, value);
        }
      }
    }
    

7. Best Practices

1. Getters Should Be Side-Effect Free

  • Các getter của computed properties không nên có side effects.
  • Nghĩa là không nên thay đổi trạng thái của ứng dụng, gọi API, hay thực hiện các tác vụ không đồng bộ.
  • Ví dụ sai:
    computed: {
      // Sai, vì có side effect
      userData() {
        fetchUserData(); // Gọi API
        return this._userData;
      }
    }
    
  • Ví dụ đúng:
    computed: {
      // Đúng, không có side effect
      userData() {
        return this._userData;
      }
    }
    

2. Avoid Mutating Computed Value

  • Không nên thay đổi giá trị của computed property từ bên ngoài.
  • Điều này có thể gây nhầm lẫn và khó debug.
  • Thay vào đó, nên sử dụng các phương thức hoặc action để thay đổi trạng thái.

3. Computed vs Watchers

  • Khi nào nên dùng computed properties, khi nào nên dùng watchers?
    • Dùng computed properties khi cần tính toán và trả về giá trị.
    • Dùng watchers khi cần thực hiện tác vụ không đồng bộ hoặc có side effect.

4. Keep Computed Simple

  • Các computed properties nên được giữ đơn giản và dễ hiểu.
  • Tránh viết quá nhiều logic phức tạp trong đó.
  • Nếu một computed property quá phức tạp, hãy xem xét tách nó thành nhiều computed property nhỏ hơn.

8. Common Use Cases

  • Một số trường hợp thường gặp khi sử dụng computed properties:
    • Tính toán giá trị từ nhiều nguồn dữ liệu khác nhau.
    • Định dạng dữ liệu trước khi hiển thị.
    • Lọc hoặc sắp xếp danh sách dựa trên các tiêu chí nhất định.

9. Kết luận

  • Computed properties là một phần quan trọng trong Vue.js, giúp tối ưu hiệu suất và tổ chức code tốt hơn.
  • Hiểu và sử dụng đúng cách computed properties sẽ giúp bạn viết được những ứng dụng Vue.js mạnh mẽ và hiệu quả.