Trong bài viết này chúng ta sẽ tiếp tục tìm hiểu một tính năng mạnh mẽ nhất của Vuejs đó chính là Component trong Vuejs. Vậy Component là gì chúng ta sẽ tìm hiểu về nó ngay sau đây nhé
Component dịch ra tiếng Việt có nghĩa là thành phần thế nhưng trong khuôn khổ của loạt bài học này chúng ta sẽ giữ nguyên từ Component bởi vì đây là thuật ngữ được sử dụng nhiều trong Vue.
1. Component là gì?
Component là một trong các tính năng mạnh mẽ nhất của Vue.js. Component trong vuejs giúp cho chúng ta gom nhóm các mã HTML lại để tái sử dụng cho các module tương tự.
Ở mức nâng cao thì component là một thành phần được Vue.js biên dịch để xử lý các hành vi. Và trong một vài trường hợp thì nó cũng có thể xuất hiện như một phần tử HTML với các attribute đặc biệt (is
- sẽ nói ở bên dưới).
Một component trong Vue về bản chất là một đối tượng Vue với các tùy chọn cho trước. Để dễ hình dung những ứng dụng quy mô lớn trong Vue đều được tạo thành từ những phần tử nhỏ độc lập và thường được tái sử dụng, các phần tử đó gọi là component. Nếu bạn để ý, gần như bất kì một loại giao diện ứng dụng nào cũng có thể được trừu tượng hóa thành một tập hợp dạng cây của các phần tử con. Một hệ thống các component góp phần tạo thành 1 cây ứng dụng trong Vue.
2. Using Components.
Registration
Trong Vue.js để khai báo một component ở mức độ global thì chúng ta sử dụng cú pháp:
Vue.component('tag', options);
Trong đó:
tag
là tên mà bạn muốn gán cho component đó.options
là một object chứa các tham số là template hay dữ liệu kèm theo.
Lưu ý: Vue.js không thực thi các quy tắc của W3C cho tên của các component tag (tất cả đều là chữ thường, và phải có dấu nối giữa các từ) mặc dù theo như nhận xét thì chuẩn này tốt.
VD: Mình sẽ đăng ký một component và gọi nó luôn ở trong ứng dụng.
<div id="app">
<tdc-component></tdc-component>
</div>
<script type="text/javascript"></script> <script type="text/javascript">
//đăng ký component
Vue.component('tdc-component',{
template: '<h5>Chào mừng bạn đến với website Hoc.tv</h5>'});
var app = new Vue({
el: '#app',
});
</script>
Local Registration
Nếu như bạn không muốn đăng ký một component ở trạng thái global nữa thì bạn cũng có thể đăng ký nó ở một phạm vi sử dụng nào đó (Vue.js gọi đó là local) thì bạn cũng có thể khai báo nó trong Vue instance.
Ví dụ: Chuyển component ở ví dụ trên về trạng thái local.
<div id="app"> <tdc-component></tdc-component> </div> <script type="text/javascript"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', components: { 'tdc-component': { template : '<h5>Chào mừng bạn đến với website Hoc.tv</h5>' } } }); </script>Chạy Code hoặc bạn cũng có thể khai báo như sau cho dễ nhìn.
<div id="app">
<tdc-component></tdc-component> </div> <script type="text/javascript">
</script> <script type="text/javascript">
var temp = {
template : '<h5>Chào mừng bạn đến với website Hoc.tv</h5>'
};
var app = new Vue({
el: '#app',
components: {
'tdc-component': temp
}
}); </script>
DOM Template Parsing Caveats.
Trong trường hợp chúng ta muốn sử dụng DOM như các template, thì chúng ta sẽ phải tuân thủ theo 1 số các hạn chế lên quan đến cách hoạt động của HTML. Bởi Vue.js sẽ chỉ có thể truy xuất được nội dung khi mà trình duyệt đã xử lý và làm chuẩn hóa chúng (ở đây là các thẻ HTML). Điển hình như các tag ul
, ol
, table
,...
VD: Như khi chúng ta sử dụng các tr trong table.
<div id="app"> <table> <tdc-component></tdc-component> </table> </div> <script type="text/javascript"></script> <script type="text/javascript"> var temp = { template : '<tr>Học Vuejs tại Hoc.tv</tr>' }; var app = new Vue({ el: '#app', components: { 'tdc-component': temp } }); </script>
Theo dõi phần Result để xem kết quả:
Dễ dàng nhận thấy kết quả hiển thị sai ko có bảng nào hiện ra cả mà hiện mã HTML như sau:
<tr>Học Vuejs tại Hoc.tv</tr> <table></table>
Để khắc phục vấn đề trên thì chúng ta sẽ sử dụng is
như một attribute của HTML để bind component vào nó.
VD: Khắc phục ví dụ trên.
<div id="app"> <table> <tr is="tdc-component"></tr> </table> </div> <script type="text/javascript"></script> <script type="text/javascript"> var temp = { template : '<tr>Học Vuejs tại Hoc.tv</tr>' }; var app = new Vue({ el: '#app', components: { 'tdc-component': temp } }); </script>Chạy Code thì trình duyệt đã render ra cho chúng ta kết đúng:
<table>
<tbody>
<tr>
Học Vuejs tại Hoc.tv</tr>
</tbody> </table>
Thế nhưng không phải chuyện gì cũng hoàn hảo Vue.js sẽ không khắc phục được nếu như bạn sử dụng template ở các trường hợp sau:
<script type="text/x-template">
- Javascript inline string.
.vue
component.
Data must be a function
Trong Vue instance data
scope là một object còn trong Component thì data scope phải là 1 function. Nếu bạn cố gắng sử dụng data như một object thì Vue sẽ cảnh báo và khuyên bạn nên khái báo data là một hàm.
Đối với trường hợp data
là hàm thì chúng ta cũng sử dụng tương tự như với object.
VD:
<div id="app"> <tdc-component></tdc-component> </div> <script type="text/javascript"></script> <script type="text/javascript"> var data = { message: 'Hoc.tv' }; Vue.component('tdc-component', { template: '<h1></h1>', data: function() { return data; } }); var app = new Vue({ el: '#app' }); </script>
Ví dụ: Trường hợp gọi một component nhiều lần.
<div id="app"> <tdc-component></tdc-component> <tdc-component></tdc-component> <tdc-component></tdc-component> </div> <script type="text/javascript"></script> <script type="text/javascript"> var data = { count : 0 }; Vue.component('tdc-component', { template: '<button v-on:click="count += 1"></button>', data: function() { return data; } }); var app = new Vue({ el: '#app' }); </script>Chạy Code
Kiểm tra kết quả chúng ta sẽ thấy sau khi thử nhấn vào bất kỳ 1 nút nào thì cả 3 nút đều thay đổi. Lý do là do khai báo data ở trạng thái global
nên khi tác động thì nó sẽ tác động đến cả 3 button. Để khắc phục điều đó thì chúng ta chỉ cần chuyển nó về dạng local
là được.
<div id="app"> <tdc-component></tdc-component> <tdc-component></tdc-component> <tdc-component></tdc-component> </div> <script type="text/javascript"></script> <script type="text/javascript"> Vue.component('tdc-component', { template: '<button v-on:click="count += 1"></button>', data: function() { return { count : 0 }; } }); var app = new Vue({ el: '#app' }); </script>
Kiểm tra lại kết quả
Composing components
Một trong những tính năng hay của của omposing components trong Vue.js là các component được sử dụng cùng nhau và có thể có mối quan hệ khăng khít với nhau. Tà thông thường nhất các bạn có thể nhìn thấy là mối quan hệ parent-child (cha con) tức là "Component A có thể sử dụng được componet B ở trong template của riêng nó, và nó không nhất thiết cần phải giao tiếp với nhau mà vẫn có thể gửi thông điệp cho nhau được".
Ví dụ minh họa:
Vue.component('component-a', { template: '<font v-bind:color="color">Hoc.tv</font>', data: function () { return { color: "magenta" } } }); Vue.component('component-b', { template: '<h5><component-a></component-a></h5>', }); var app = new Vue({ el: '#app' });
Tuy nhiên, để tiện cho việc bảo trì và tái sử dụng lại component chúng ta nên tách nó ra các interface khác nhau. Cụ thể trong Vue.js nó có thể được tóm gọn lại như props down hay events up - parent truyền props cho child và child phản hồi lại cho parent bằng event.
- Component cha truyền Props cho component con
- Component con phản hồi lại cho Component cha bằng Event
Bạn có thể tham khảo mô hình sau để hiểu hơn về nó.
Qua bài viết này chắc hẳn các bạn đã có được cái nhìn tổng quan về component và áp dụng nó vào trong các dự án của riêng mình rồi phải không nào. Chi tiết hơn về component trong Vue.js chúng ta sẽ tìm hiểu trong bài sau nhé. Hẹn gặp lại các bạn!