[VueJS] Dependency Injection Component

Dependency Injection là 1 khuôn mẫu (pattern) tuyệt vời khi chúng ta xây dựng một ứng dụng to lớn và phức tạp.

Thử thách khi xây dựng những ứng dụng như vậy là tạo ra những component ít phụ thuộc vào nhau nhất có thể (loosely coupled). Và đây là lý do dependency là một trong những yếu tố cần đặc biệt chú ý đến.

Ở trong bài này mình sẽ phân tích những lợi và hại khi dùng Dependency trong VueJS (Lý thuyết này cũng có thể áp dụng cho những ngôn ngữ khác)

Dependency Injection là gì?

Dependency Injection là một khuôn mẫu (pattern) quy định các thực thể không nên phụ thuộc chặt chẽ vào nhau mà chỉ nên kết nối với nhau thông qua một đối tượng trung gian.

Lý do vì sao? Tưởng tượng rằng nhà bạn là A và nhà hàng xóm là B. Bây giờ nếu nhà bạn và nhà hàng xóm liên kết chặt chẽ với nhau. Tức là chung một bức tường và cửa ra vào. Thì khi nhà A sửa đổi hoặc xây mới một cái gì đó. Thì nhà B cũng sẽ chịu ảnh hưởng và ngược lại.

Nhưng nếu nhà A và B cách nhau 1 con đường. thì nhà A khi sửa chữa sẽ không ảnh hưởng hoặc ít tới nhà B hơn.

Con đường ở đây chính là Dependency Injection đó các bạn. Chính nhờ con đường mà A và B có thể tương tác với nhau nhưng không phụ thuộc quá nhiều vào nhau.

Tại sao lại cần Dependency Injection trong Vue?

Trong quá trình làm việc với VueJS chắc hẳn bạn đã có nhu cầu truyền dữ liệu từ component cha xuống các component con thông qua prop rồi đúng không nào?

Nhưng mà bạn có bao giờ gặp tính huống truyền prop xuống 3 cấp hoặc là nhiều hơn chưa? vd: “ông nội” muốn truyền data xuống component “cháu” thì phải thông qua component “cha” đúng không? Tham khảo hình minh họa bên dưới

Ông nội muốn truyền data xuống cháu phải thông qua trung gian

Ở tình huống trên có một điểm không hợp lý, là component “cha” (ở giữa) không thực sự cần thuộc tính đó. Nhưng mà vẫn phải viết code xử lý cho thuộc tính đó. Việc này gây ra lãng phí tài nguyên công sức và gây khó khăn cho việc sửa đổi bảo trì. Hiện tượng này gọi là “props drilling” (nôm na là props chạy & gây ảnh hưởng khắp nơi, mình không thể dịch cho sát nghĩa được)

Vue giải quyết bài toán này như thế nào?

Rất may đối với VueJS chúng ta đã có được sự hỗ trợ của Framework thuông qua 2 khái niệm Provide & Inject.

  • Provide: Component root cung cấp Data
  • Inject: Component cần data truyền từ root gọi ra và sử dụng

Hình minh họa dưới đây sẽ mô tả cách thức hoạt động của Provide và Inject

Root khai báo sau đó Deepchild gọi và sử dụng

Bạn thấy đấy, với Dependency Injection mình đã loại bỏ được bớt 1 sự phụ thuộc là component Footer rồi đúng không nào? Việc này khiến cho code dễ đọc và hiểu hơn, cũng như khi fix bug cũng sẽ dễ dàng hơn. +1 cho VueJS

Sau đây là đoạn code mẫu

ComponentOngNoi.vue

export default {
  data() {
    return {
      message: 'hello!'
    }
  },
  provide() {
    // use function syntax so that we can access `this`
    return {
      message: this.message
    }
  }
}

ComponentCha.vue

<script setup>
import ComponentChau from './ComponentChau.vue'
</script>

<template>
  <ComponentChau />
</template>

ComponentChau.vue

export default {
  inject: ['message'],
  created() {
    console.log(this.message) // injected value
  }
}

Lợi ích khi dùng Dependency Injection

  1. Tăng khả năng dùng lại code
  2. Loại bỏ sự lặp lại 1 đoạn code nhiều lần (boilerplate)
  3. Dễ dàng mock để unit test vì có ít sự phụ thuộc hơn
  4. Phân tách logic component rõ ràng
  5. Dễ dàng đọc hiểu & bảo trì code
  6. Tăng khả năng mở rộng của chương trình

Có hại nào không?

  1. Phải có kiến thức tổng quát về project để có thể design dependency injection chuẩn. Nếu không nó sẽ là 1 con dao 2 lưỡi
  2. Hơi khó hiểu cho các bạn mới học Vue

Còn gì nữa không?

Tất nhiên là còn, tuy nhiên mình sẽ để các bạn tự tìm hiểu thêm thì mới nhớ lâu được. Tự học thêm nhé

Tham khảo:

https://vuejs.org/guide/components/provide-inject.html#inject

https://blog.logrocket.com/dependency-injection-vue-advantages-caveats/

F G+ T

tuandph

Khởi đầu với .NET từ năm 2013 đến nay. Hiện tại mình đang làm full-stack developer. Yêu thích lập trình & chia sẽ kiến thức. Thời gian rảnh thường làm những tool vui vui và viết lách kể lệ sự đời.