Vuejs life cycle – hiểu sao cho đúng

6587

Bài viết được sự cho phép của tác giả Kiên Nguyễn

Nếu bạn chưa nắm rõ về Vuejs Life Cycle, hãy nghe lời tôi, đọc và ghi nhớ hết các hooks trong bài viết này. Tôi thề là nó sẽ có ích cho bạn.

  Cách sử dụng các plugins jQuery trong VueJS
  Call API trong VueJS theo cách thông minh nhất

1. Creation (Initialization) – Khởi tạo component

Đầu tiên, bất cứ component nào cũng cần được khởi tạo. Các methods được thực thi ở Creation sẽ được xác nhận (perform actions) trước khi các component này được thêm vào DOM.

Nếu các bạn chưa hiểu nhiều về DOM và cách Browser render website, có thể đọc thêm bài viết này ở kieblog.vn

Hầu hết các xử lí được thực hiện ở Creation thường là thao tác giữa Client và Server (Xác thực đăng nhập, fetch data từ API). Nhưng tại sao lại thế?

Creation là bước đầu tiên trong chuỗi Vuejs life cycle, ở bước này, chúng ta chưa có quyền truy cập vào DOM tree, target mounting element (this.$el) cũng không thể truy cập

1.1 beforeCreate – trước khi tạo ra component

Before Create là sự kiện khởi đầu trong Vuejs Life Cycle, tất các các component trước khi khởi tạo đều gọi qua beforeCreate().

Chú ý rằng bất cứ dữ được nào được lấy ra ở bước này đều không ánh xạ đi đâu. Các sự kiện ở trên component cũng không work ở đây

export default {
beforeCreate() {
alert('Không có event nào được gọi trước beforeCreate!')
}
}

CHỐT: beforeCreate LUÔN ĐƯỢC GỌI VÀ GỌI ĐẦU TIÊN

1.2 created – đã tạo ra component

Ở event created, ta có thể xử lý các dữ liệu trả về từ beforeCreated. Các event handle trên component cũng có thể được xử lý ở đây.

Tuy nhiên, do các method mounted (gắn kết) và rendered (hiển thị) chưa được gọi. Không thể thực hiện các thao tác trên DOM ở bước này.

Ex: document.getElementById, byTag, …

2. Mounting (DOM Insertion) – Thao tác với DOM tree

Rõ ràng mà nói, không phải component nào cũng fetchData hay call API, xử lí dữ liệu phức tạp ở Creation event. Chính vì vậy, trong tất cả các event của Vuejs Life Cycle, event được gọi nhiều nhất luôn là Mounting.

Hãy nhớ rằng Mounting rất linh động, nó cho phép ta truy cập tới các thành phần trên DOM TRƯỚC HOẶC SAU LẦN RENDER ĐẦU TIÊN.

Vậy nếu chúng ta cần sửa đổi, truy cập tới một phần tử trước và sau khi DOM render. Các methods nên được viết ở phần mounting, còn nếu bạn muốn set data khởi tạo cho các component, các method fetch dữ liệu nên được viết ở created.

Theo kinh nghiệm riêng của mình, khi fetch hoặc update lại data ở component viết ở Mouting, không có vẻ gì là sai nhưng lúc component thay đổi data liên tục realtime. Các component sẽ giật giật tung cả chảo. =)))

vuejs-life-cycle-hooksEvent created and beforeMount

2.1 beforeMount – trước khi mount

Tất nhiên, nhìn thấy before là hiểu. Event này sẽ run trước lần render đầu tiên của component. beforeMount() cũng được gọi trước khi các điều kiện render (conditional render) trên template được gọi.

Chính vì vậy, đừng set giá trị cho các biến để kiểm tra khi render ở event này.

Ra thế, tôi mới bảo các bạn hãy nắm chắc Vuejs Life Cycle, sẽ rất dễ để biết bước nào nên làm gì?

export default {
beforeMount() {
console.log(`this.$el sẽ là undefined ở beforeMount`)
}
}

CHỐT: CÁC ELEMENT trên DOM chưa thể truy cập được ở BEFORE MOUNT

2.2 mounted – đã thao tác xong với DOM tre

Kế tiếp sau event beforeMount là mounted. Thì hoàn thành với ed ở đây cho biết rằng template và DOM đã render xong. Ta có thể truy xuất các giá trị thông qua this.$el (element).

Event này cũng thường được sử dụng để gán data cho các child component (thông qua this)

<template>
<h1>This is title, we can access it after beforeMount()</h1>
</template>

<script>
export default {
mounted() {
console.log(this.$el.textContent) // This is title, we can access it after beforeMount()
}
}
</script>

CHỐT: ở event Mounted, có thể truy cập được tới các element trên DOM.

3. Updating (Diff & Re-render) – phản ánh thay đổi và re-render lại DOM tree

Đối với component, khi có bất cứ thay đổi nào ở DOM, một element nào trên component được hiển thị lại.

3.1 beforeUpdate – trước khi cập nhật

beforeUpdate hooks sẽ chạy trước khi sự kiện update trên component bắt đầu. Một component sau khi được render lên DOM sẽ có thể được cập nhật lại.

Tất nhiên, chỉ component nào sau khi render và được cập nhật lại mới gọi tới methods này.

<script>
export default {
data() {
return {
firstTimeItem: "Firsttime"
}
},

beforeUpdate() {
console.log(this.firstTimeItem) // Mỗi lần upadte sẽ gọi tới method này
},

created() {
setInterval(() => {
this.firstTimeItem = "Yo bro, i want to update"
}, 1000)
}
}
</script>

3.2 updated – sau khi update

Trong Vuejs Life Cycle, event updated sẽ bắt đầu chạy sau khi CÔNG VIỆC RENDER NỘI DUNG UPDATE TRÊN DOM hoàn tất.

Nếu ta muốn thao tác thay đổi trên DOM tree sau khi nội dung đã update thì thực hiện ở updated là an toàn nhất. Nguyên nhân là vì updated chỉ được gọi sau khi DOM đã update xong.

<template>
<p ref="dom-element">{{counter}}</p>
</template>
<script>
export default {
data() {
return {
counter: 0
}
},

updated() {
// Được gọi sau khi DOM update. Giá trị luôn bằng giá trị tăng của counter
console.log(+this.$refs['dom-element'].textContent === this.counter)
},

created() {
setInterval(() => {
this.counter++
}, 1000)
}
}
</script>

4. Destruction (Teardown) – hủy bỏ

Destruction hooks là những actions cho phép ta handle sự kiện hủy bỏ các component. Thực hiện trước khi component được khóa khỏi cây DOM.

4.1 beforeDestroy – trước khi hủy

Ở event này, trước khi nó được gọi, component vẫn có đầy đủ các thành phần (present) và chứng năng (functional). Nếu một event hoặc một variable gây tốn kém về bộ nhớ (nếu không được dọn dẹp sau khi khởi tạo), ta có thể xử lý chúng ở đây.

<script>
export default {
data() {
return {
variableLeakMem: 'When component destroy, please remove me'
}
},

beforeDestroy() {
// Loại bỏ variable hay các event listening sẽ đỡ lãng phí bộ nhớ
this.variableLeakMem = null
delete this.variableLeakMem
}
}
</script>

4.2 destroyed – đã hủy component

Event destroyed hooks trong Vuejs life cycle đóng vai trò là event kiểm chứng cho những gì đã destroy ở beforeDestroy. Ở event này, tất cả các đối tượng, các event đã bị hủy bỏ ở beforeDestroy sẽ không còn nữa

<script>
import MyCreepyAnalyticsService from './somewhere-bad'

export default {
destroyed() {
console.log(this) // There's practically nothing here!
MyCreepyAnalyticsService.informService('Component destroyed. All assets move in on target on my mark.')
}
}
</script>

CHỐT: EVENT DESTROY CÓ THỂ DÙNG ĐỂ KIỂM CHỨNG CHO VIỆC MUỐN DESTROY CÁC ĐỐI TƯỢNG MONG MUỐN.

5. Hãy nắm chắc Vuejs Life Cycle

Qua bài viết này, mong các bạn sẽ hiểu thêm về Vuejs Life Cycle. Hiểu rõ về cycle sẽ giúp chúng ta xử lý tốt trên các page hoặc component.

vuejs-life-cycle-hooksLưu ý rằng life cycle có thể khác biệt giữa các phiên bản của Vuejs nhé

Nếu bug phát sinh, cũng dễ dàng xử lí (vì chúng ta biết nó xuất hiện ở step nào). Sắp tới sẽ có một loạt bài viết về Vuejs. Mời các bạn đón đọc. Chân thành cảm ơn!.

6. Reference – tham khảo

Nếu đã quen với Vuejs, hãy tìm hiểu thêm về React. Đối thủ không đội trời chung của Vuejs.

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev