Trong Vue2, việc trao đổi thông tin giữa các thành phần có thể được thực hiện bằng một số cách sau:
- Props và Events
Đây là phương pháp cơ bản và thường được sử dụng nhất để liên lạc giữa các thành phần cha-con trong Vue2. Thành phần cha truyền dữ liệu đến thành phần con thông qua thuộc tính, và thành phần con gửi dữ liệu ngược lên thành phần cha thông qua sự kiện.
Thành phần cha truyền dữ liệu cho thành phần con:
<template>
<div>
<con-thanh-phan :thong-diep="thongDiepCha"></con-thanh-phan>
</div>
</template>
<script>
import ConThanhPhan from './ConThanhPhan.vue';
export default {
components: {
ConThanhPhan
},
data() {
return {
thongDiepCha: 'Xin chào thế giới!'
}
}
}
</script>
Thành phần con nhận dữ liệu từ thành phần cha
<template>
<div>{{ thongDiep }}</div>
</template>
<script>
export default {
props: {
thongDiep: String
}
}
</script>
Thành phần con gửi dữ liệu lên thành phần cha:
<template>
<div>
<button @click="$emit('cap-nhat-thong-diep', 'Xin chào Vue!')">Cập nhật thông điệp</button>
</div>
</template>
Thành phần cha lắng nghe sự kiện từ thành phần con:
<template>
<div>
<con-thanh-phan @cap-nhat-thong-diep="onCapNhatThongDiep"></con-thanh-phan>
</div>
</template>
<script>
import ConThanhPhan from './ConThanhPhan.vue';
export default {
components: {
ConThanhPhan
},
methods: {
onCapNhatThongDiep(thongDiep) {
console.log(thongDiep);
}
}
}
</script>
- $parent và $children
Mỗi phiên bản thành phần trong Vue2 đều có thuộc tính $parent và $children, dùng để truy cập vào các thành phần cha và con tương ứng.
Thành phần cha có thể truy cập vào thành phần con thông qua $children:
<template>
<div>
<con-thanh-phan></con-thanh-phan>
</div>
</template>
<script>
import ConThanhPhan from './ConThanhPhan.vue';
export default {
components: {
ConThanhPhan
},
mounted() {
console.log(this.$children[0].thongDiep);
}
}
</script>
Thành phần con có thể truy cập vào thành phần cha thông qua $parent:
<template>
<div>{{ $parent.thongDiep }}</div>
</template>
<script>
export default {
mounted() {
console.log(this.$parent.thongDiep);
}
}
</script>
- $refs
Trong Vue2, $refs có thể được sử dụng để truy cập trực tiếp vào các thành phần con đã được khai báo. Thông qua $refs, bạn có thể gọi các phương thức hoặc truy xuất thuộc tính của thành phần con.
<template>
<div>
<con-thanh-phan ref="conThanhPhan"></con-thanh-phan>
<button @click="capNhatThongDiep">Cập nhật thông điệp</button>
</div>
</template>
<script>
import ConThanhPhan from './ConThanhPhan.vue';
export default {
components: {
ConThanhPhan
},
methods: {
capNhatThongDiep() {
this.$refs.conThanhPhan.capNhatThongDiep('Xin chào Vue!');
}
}
}
</script>
Thành phần con xử lý yêu cầu cập nhật:
<template>
<div>{{ thongDiep }}</div>
</template>
<script>
export default {
data() {
return {
thongDiep: 'Xin chào thế giới!'
}
},
methods: {
capNhatThongDiep(moiThongDiep) {
this.thongDiep = moiThongDiep;
}
}
}
</script>
- Event Bus
Event Bus trong Vue2 hoạt động như một trung tâm sự kiện độc lập, cho phép bất kỳ thành phần nào phát hoặc lắng nghe sự kiện. Để tạo một Event Bus:
// EventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
Phát sự kiện từ một thành phần:
<template>
<div>
<button @click="capNhatThongDiep">Cập nhật thông điệp</button>
</div>
</template>
<script>
import { EventBus } from './EventBus.js';
export default {
methods: {
capNhatThongDiep() {
EventBus.$emit('cap-nhat-thong-diep', 'Xin chào Vue!');
}
}
}
</script>
Lắng nghe sự kiện trong một thành phần khác:
<template>
<div>{{ thongDiep }}</div>
</template>
<script>
import { EventBus } from './EventBus.js';
export default {
data() {
return {
thongDiep: 'Xin chào thế giới!'
}
},
mounted() {
EventBus.$on('cap-nhat-thong-diep', moiThongDiep => {
this.thongDiep = moiThongDiep;
});
}
}
</script>
- Vuex
Khi các thành phần cần chia sẻ dữ liệu phức tạp hoặc ở nhiều nơi khác nhau, Vuex là lựa chọn phù hợp. Vuex cung cấp một mô hình quản lý trạng thái tập trung cho các ứng dụng Vue.js.
Tạo store:
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
thongDiep: 'Xin chào thế giới!'
},
mutations: {
capNhatThongDiep(state, noiDungMoi) {
state.thongDiep = noiDungMoi;
}
},
actions: {
capNhatThongDiep(context, noiDungMoi) {
context.commit('capNhatThongDiep', noiDungMoi);
}
}
});
Truy cập dữ liệu từ store trong thành phần:
<template>
<div>{{ thongDiep }}</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['thongDiep'])
}
}
</script>
Gọi action từ thành phần:
<template>
<div>
<button @click="capNhatThongDiep">Cập nhật thông điệp</button>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions(['capNhatThongDiep'])
}
}
</script>