Toidicode.com

Toidicode.com

BASIC TO ADVANCE

Bài 10: Component trong Vue.js

Tiếp tục series phần này chúng ta sẽ tìm hiểu về Components trong Vue.js

Ở đây component dịch ra tiếng việt thì có nghĩa là thành phần. Nhưng mình sẽ không viết nó dưới dạng Tiếng Việt vì nó là một thuật ngữ trong Vue.js

1, Component là gì?

-Component là một trong các tính năng mạnh mẽ nhất của Vue.js. Nó 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ột mức độ 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).

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: '<h1>Chào mừng bạn đến với website Toidicode.com</h1>'
    });
    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.

VD: 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 : '<h1>Chào mừng bạn đến với website Toidicode.com</h1>'
            }
        }
    });
</script>

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 : '<h1>Chào mừng bạn đến với website Toidicode.com</h1>'
    };
    var app = new Vue({
        el: '#app',
        components: {
            'tdc-component': temp
        }
    });
</script>

DOM Template Parsing Caveats.

Khi bạn muốn sử dụng DOM như các template, thì bạn sẽ phải tuân thủ theo một 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 Lập Trình Online Toidicode.com</tr>'
    };
    var app = new Vue({
        el: '#app',
        components: {
            'tdc-component': temp
        }
    });
</script>

Lúc này trình duyệt nó sẽ render thành:

<tr>Học Lập Trình Online Toidicode.com</tr>
<table></table>

Nhưng các bạn không cần phải lo, vì cái gì cũng có hướng giải quết của nó, hơn nữa với độ phổ biến của Vue.js hiện giờ thì... Để 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 Lập Trình Online Toidicode.com</tr>'
    };
    var app = new Vue({
        el: '#app',
        components: {
            'tdc-component': temp
        }
    });
</script>

Lúc này thì trình duyệt đã render ra cho chúng ta kết đúng:

<table>
    <tbody>
        <tr>Học Lập Trình Online Toidicode.com</tr>
    </tbody>
</table>

Nhưng Vue.js cũng đã tuyên bố rằng, nó 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.

(Những cái này mình sẽ nói sau)

Data must be a function

Ở phần component thì có khác hơn so với bình thường một chút, là đối với data scope thì nó phải là một function , chú không phải là một object như ở Vue instance nữa. Nếu như bạn cố gắng sử dụng data là object thì nó sẽ có cảnh báo khuyên bạn lên khai 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: 'Toidicode.com'
    };
    Vue.component('tdc-component', {
        template: '<h1>{{ message }}</h1>',
        data: function() {
            return data;
        }
    });
    var app = new Vue({
        el: '#app'
    });
</script>

Và các bạn hãy tham khảo thêm một ví dụ sau nữa với 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">{{ count }}</button>',
        data: function() {
            return data;
        }
    });
    var app = new Vue({
        el: '#app'
    });
</script>

Sau khi chạy thử thì các bạn cũng thấy là khi click vào một button thì data của cả 3 nút đều thay đổi theo. Lý do là do chũng ta 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. Và để 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">{{ count }}</button>',
        data: function() {
            return { count : 0 };
        }
    });
    var app = new Vue({
        el: '#app'
    });
</script>

Composing components

Trong Vue.js, các component được sử dụng cùng nhau, và thông thường nhất chúng ta có thể nhìn thấy là mối quan hệ parent-child (cha con) : "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".

VD:

Vue.component('component-a', {
    template: '<font v-bind:color="color">Toidicode.com</font>',
    data: function () {
        return { color: "red" }
    }
});
Vue.component('component-b', {
    template: '<h1><component-a></component-a></h1>',
});
var app = new Vue({
    el: '#app'
});

Tuy nhiên, chúng ta nên tách nó ra các interface khác nhau để tiện cho việc bảo trì và có thể tái sử dụng lại nhiều lần. Và 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.

Bạn có thể tham khảo mô hình sau để hiểu hơn về nó.

props và event trong component Vue.js

Cụ thể về nó thì phần sau chúng ta sẽ tìm hiểu.

4, Lời kết.

-Như vậy bài này chúng ta đã được tìm hiểu sơ qua về component trong Vue.js rồi. Qua đó mình hy vọng rằng mọi người sẽ 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 bạn. Phần sau chúng ta sẽ tìm hiểu nốt về những gì liên quan đến component trong Vue.js

Đăng ký nhận tin.

Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!

Vũ Thanh Tài

About author
The best way to learn is to share
Xem tất cả bài đăng

2 Comments

mong anh sửa lỗi chính tả ạ huhu

nên

5 năm trước

ok em trai

khoapug

4 năm trước

Bình luận

Captcha