ref
Trong Vue 3, hàm setup được sử dụng để định nghĩa dữ liệu và phương thức của component. Bạn có thể sử dụng các API phản hồi như ref, reactive và computed trong setup để quản lý trạng thái. Dưới đây là ví dụ minh họa:
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const tinnhan = ref('Xin chào thế giới');
function hienthinhan() {
alert(tinnhan.value);
}
return {
tinnhan,
hienthinhan
};
}
});
Trong ví dụ này, chúng ta sử dụng ref để tạo biến tinnhan có giá trị ban đầu là 'Xin chào thế giới'. Hàm hienthinhan sẽ hiển thị giá trị này khi được gọi. Các biến và phương thức được trả về từ setup sẽ có sẵn trong template.
Template component sử dụng cú pháp nội suy và v-on để truy cập trạng thái:
<template>
<div>
<p>{{ tinnhan }}</p>
<button @click="hienthinhan">Hiển thị thông báo</button>
</div>
</template>
Cú pháp {{ tinnhan }} hiển thị giá trị biến, còn @click gắn sự kiện click vào nút để kích hoạt hàm hienthinhan.
Dưới đây là ví dụ ứng dụng đếm số:
<template>
<div>
<p>{{ dem }}</p>
<button @click="tangGiaTri">Tăng 1</button>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const dem = ref(0);
function tangGiaTri() {
dem.value++;
}
return {
dem,
tangGiaTri
};
}
});
</script>
Biến dem được khởi tạo bằng 0 và hàm tangGiaTri tăng giá trị của nó lên 1 mỗi khi nút được nhấn.
Có thể viết lại hàm tangGiaTri dưới dạng arrow function:
<template>
<div>
<p>{{ dem }}</p>
<button @click="tangGiaTri">Tăng 1</button>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const dem = ref(0);
const tangGiaTri = () => {
dem.value++;
};
return {
dem,
tangGiaTri
};
}
});
</script>
Cách viết này gọn gàng hơn và không cần bind this, rất phổ biến trong Vue 3.
reactive
reactive là API tạo ra đối tượng phản hồi từ object JavaScript thông thường. Mọi thay đổi trên thuộc tính của đối tượng này sẽ tự động cập nhật giao diện.
Ví dụ sử dụng reactive:
import { reactive } from 'vue';
const trangthai = reactive({
dem: 0,
tinnhan: 'Chào mừng đến với Vue!',
});
Ví dụ hoàn chỉnh:
<template>
<div>
<p>Đếm: {{ trangthai.dem }}</p>
<p>Thông báo: {{ trangthai.tinnhan }}</p>
<button @click="tangDem">Tăng</button>
<button @click="doiThongBao">Đổi thông báo</button>
</div>
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const trangthai = reactive({
dem: 0,
tinnhan: 'Chào mừng đến với Vue!',
});
function tangDem() {
trangthai.dem++;
}
function doiThongBao() {
trangthai.tinnhan = 'Chào mừng đến với Vue 3!';
}
return {
trangthai,
tangDem,
doiThongBao,
};
},
};
</script>
Trong ví dụ này, trangthai là đối tượng phản hồi chứa các thuộc tính dem và tinnhan. Các hàm tangDem và doiThongBao thay đổi giá trị các thuộc tính này, khiến giao diện tự động cập nhật.
Sự khác biệt giữa ref và reactive:
ref: Phù hợp cho kiểu dữ liệu nguyên thủy (number, string, boolean). Truy cập giá trị qua thuộc tính.value.reactive: Tạo object phản hồi với nhiều thuộc tính. Truy cập trực tiếp các thuộc tính mà không cần.value.
Ví dụ so sánh:
<template>
<div>
<!-- Ví dụ ref -->
<p>Giá trị đếm: {{ dem }}</p>
<button @click="tangDem">+1</button>
<!-- Ví dụ reactive -->
<p>Tên người: {{ thongtin.ten }}</p>
<p>Độ tuổi: {{ thongtin.tuoi }}</p>
<button @click="doiTen">Đổi tên</button>
<button @click="tangTuoi">Tăng tuổi</button>
</div>
</template>
<script>
import { ref, reactive } from 'vue';
export default {
setup() {
// Ví dụ ref
const dem = ref(0);
const tangDem = () => {
dem.value++;
};
// Ví dụ reactive
const thongtin = reactive({
ten: 'Nguyen Van A',
tuoi: 25
});
const doiTen = () => {
thongtin.ten = 'Tran Van B';
};
const tangTuoi = () => {
thongtin.tuoi++;
};
return {
dem,
tangDem,
thongtin,
doiTen,
tangTuoi
};
}
}
</script>
toRefs
toRefs chuyển đổi tất cả thuộc tính của object reactive thành các ref tương ứng. Điều này hữu ích khi cần giải cấu trúc object hoặc truyền vào API yêu cầu ref.
Ví dụ sử dụng toRefs:
<template>
<div>
<p>Đếm: {{ dem.value }}</p>
<p>Thông báo: {{ thongbao.value }}</p>
<button @click="tangDem">Tăng</button>
</div>
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
setup() {
const duLieu = reactive({
dem: 0,
thongbao: 'Chào mừng!'
})
const tangDem = () => {
duLieu.dem++
}
return {
...toRefs(duLieu),
tangDem
}
}
}
</script>
Trong ví dụ này, toRefs chuyển đổi các thuộc tính của duLieu thành ref, sau đó sử dụng toán tử spread ... để trả về các ref này cùng với hàm tangDem. Các thay đổi trên ref sẽ đồng bộ với object reactive gốc.