Tính chất Tính toán và Giám sát trong Vue.js

Sử dụng Biểu thức và Phương thức thay thế Tính chất Tính toán

Trong một ứng dụng Vue, việc hiển thị dữ liệu phụ thuộc có thể được thực hiện bằng nhiều cách khác nhau.

1. Sử dụng Biểu thức nội suy trực tiếp

<div id="application">
  <input type="text" v-model="ten">
  <input type="text" v-model="ho">
  <span>{{ ten }} - {{ ho }}</span>
</div>

2. Sử dụng Phương thức

const vm = new Vue({
  el: '#application',
  data: {
    ten: 'Nguyễn',
    ho: 'Văn A'
  },
  methods: {
    tenDayDu() {
      return this.ten + '=' + this.ho;
    }
  }
});
<!-- Gọi phương thức trong template -->
<span>{{ tenDayDu() }}</span>

Phương thức sẽ được gọi lại mỗi khi có bất kỳ sự thay đổi nào trong dữ liệu, kể cả khi các giá trị không liên quan thay đổi.

Giới thiệu Tính chất Tính toán (Computed Properties)

Tính chất tính toán cung cấp một giải pháp tối ưu hơn với cơ chế lưu trữ bộ nhớ đệm.

const vm = new Vue({
  el: '#application',
  data: {
    ten: 'Nguyễn',
    ho: 'Văn A'
  },
  computed: {
    tenDayDu: {
      get() {
        console.log('Tính toán giá trị');
        return this.ten + '-' + this.ho;
      },
      set(giaTriMoi) {
        const mang = giaTriMoi.split('-');
        this.ten = mang[0];
        this.ho = mang[1];
      }
    }
  }
});

Tính chất tính toán chỉ được tính toán lại khi các dữ liệu phụ thuộc thay đổi. Các lần truy cập sau đó sẽ lấy giá trị từ bộ nhớ đệm.

Cú pháp viết tắt cho Tính chất Tính toán

Khi một tính chất tính toán chỉ có getter, có thể sử dụng cú pháp viết tắt dưới dạng hàm.

computed: {
  // Cách viết đầy đủ với chỉ getter
  tenDayDu01: {
    get() {
      return this.ten + '-' + this.ho;
    }
  },

  // Cú pháp viết tắt dạng hàm
  tenDayDu02: function() {
    return this.ten + '-' + this.ho;
  },

  // Cú pháp viết tắt ES6
  tenDayDu03() {
    return this.ten + '-' + this.ho;
  }
}

Ví dụ về Giám sát Thuộc tính (Watch) với Thay đổi Trạng thái

<div id="application">
  <p>Thời tiết {{ nhiet ? 'Nóng' : 'Mát' }}</p>
  <p>Thời tiết {{ trangThaiThoiTiet }}</p>
  <button @click="doiThoiTiet">Đổi thời tiết</button>
  <button @click="nhiet = !nhiet">Đổi trực tiếp</button>
</div>
const vm = new Vue({
  el: '#application',
  data: {
    nhiet: true
  },
  methods: {
    doiThoiTiet() {
      this.nhiet = !this.nhiet;
    }
  },
  computed: {
    trangThaiThoiTiet() {
      return this.nhiet ? 'Nóng' : 'Mát';
    }
  }
});

Cơ bản về Giám sát Thuộc tính

Giám sát thuộc tính cho phép thực hiện các thao tác phụ khi dữ liệu thay đổi.

const vm = new Vue({
  el: '#application',
  data: {
    nhiet: true
  },
  methods: {
    doiThoiTiet() {
      this.nhiet = !this.nhiet;
    }
  },
  watch: {
    nhiet: {
      immediate: true, // Gọi handler ngay khi khởi tạo
      handler(giaTriMoi, giaTriCu) {
        console.log(`Giá trị thay đổi từ ${giaTriCu} thành ${giaTriMoi}`);
      }
    }
  }
});

Giám sát thuộc tính cũng có thể được cấu hình sau khi khởi tạo Vue instance.

vm.$watch('nhiet', {
  immediate: true,
  handler(giaTriMoi, giaTriCu) {
    console.log('Giám sát với $watch');
  }
});

Giám sát sâu (Deep Watch)

Mặc định, watch chỉ phát hiện thay đổi khi chính thuộc tính được theo dõi thay đổi giá trị trực tiếp. Đối với các đối tượng lồng nhau, cần sử dụng deep watch.

const vm = new Vue({
  el: '#application',
  data: {
    soLuong: {
      x: 1,
      y:课后
    },
    sanPham: {
      gia: 100,
      soLuong: 50
    }
  },
  watch: {
    // Giám sát thuộc tính lồng nhau
    'soLuong.x': {
      handler() {
        console.log('Thuộc tính x thay đổi');
      }
    },
    // Giám sát toàn bộ đối tượng (không phát hiện thay đổi bên trong)
    soLuong: {
      handler() {
        console.log('Đối tượng soLuong thay đổi (chỉ địa chỉ)');
      }
    },
    // Giám sát sâu cho đối tượng
    sanPham: {
      deep: true, // Kích hoạt giám sát sâu
      handler() {
        console.log('Có thay đổi bên trong sanPham');
      }
    }
  }
});

Cú pháp viết tắt cho Giám sát Thuộc tính

Khi không cần các tùy chọn như immediate hoặc deep, có thể sử dụng cú pháp viết tắt.

watch: {
  // Cú pháp viết tắt khi chỉ có handler
  nhiet(giaTriMoi, giaTriCu) {
    console.log(giaTriMoi, giaTriCu);
  }
}

// Cú pháp viết tắt với $watch
vm.$watch('coHieuLuc', function(giaTriMoi, giaTriCu) {
  console.log(giaTriMoi, giaTriCu);
});

So sánh Giám sát Thuộc tính và Tính chất Tính toán

Cả hai tính năng đều cho phép phản ứng với sự thay đổi dữ liệu, nhưng có những điểm khác biệt quan trọng:

  • Tính chất tính toán phù hợp cho các giá trị được tính toán từ dữ liệu hiện có và được sử dụng trong template.
  • Giám sát thuộc tính phù hợp cho các thao tác phụ khi dữ liệu thay đổi, bao gồm các thao tác không đồng bộ.
  • Tính chất tính toán không thể thực hiện các thao tác không đồng bộ trực tiếp trong getter.
  • Trong các hàm được quản lý bởi Vue (methods, computed, watch handler), nên sử dụng hàm thông thường để this trỏ đến Vue instance.
  • Trong các hàm không được quản lý bởi Vue (callback của setTimeout, AJAX), nên sử dụng arrow function để this trỏ đến Vue instance.
// Ví dụ về xử lý không đồng bộ trong watch
watch: {
  ten() {
    // Có thể thực hiện thao tác không đồng bộ
    setTimeout(() => {
      this.tenDayDu = this.ten + this.ho;
    },7

Thẻ: Vue.js Computed Properties Watchers Vue Methods Vue Data Binding

Đăng vào ngày 25 tháng 8 lúc 16:23