Ra mắt hai series mới cực hot Trí tuệ nhân tạo A đến ZPython công cụ không thể thiếu khi nghiên cứu Data science, Machine learning.

Vue.js component xây dựng ứng dụng theo cách module hóa

Trong lập trình, việc lặp đi lặp lại một đoạn code gây ra nhiều rắc rối:

  • Khó sử dụng lại
  • Tăng thời gian viết code
  • Khó quản lý các đoạn code lặp, khi có thay đổi thì cần thay đổi ở tất cả các đoạn code lặp lại.

Với ngôn ngữ thông thường, chúng ta có các hàm, các đối tượng để giảm đi các đoạn code trùng lặp. Vue.js cũng cung cấp một khái niệm mới component (thành phần) giúp cho code được cấu trúc thành các thành phần cơ bản. Đến đây bạn cũng có thể phần nào đoán được Vue.js component là gì? nhưng tại sao nó lại quan trọng và cách sử dụng có phức tạp không, chúng ta sẽ cùng tìm hiểu tiếp nhé.

Vue.js component

1. Component trong framework Vue.js là gì?

Trong các ngôn ngữ lập trình để tránh lặp lại code, các khái niệm function, class... Vue.js cũng cho phép viết các phương thức trong thuộc tính methods của Vue instance, tuy nhiên nó chỉ giúp tránh lặp lại code trong phần xử lý Javascript. Một website khi được tạo ra là sự kết hợp của cả ba ngôn ngữ HTML, Javascript và CSS vậy làm cách nào để tránh lặp lại code của một đối tượng nào đó được sử dụng lại, ví dụ: một ô hiển thị sản phẩm sẽ bao gồm: - Mã HTML xây dựng nội dung cơ bản của sản phẩm.

  • Mã Javascript để xử lý các tương tác người dùng với nội dung sản phẩm.
  • Mã CSS để làm cho nội dung sản phẩm đẹp hơn.

Vue.js nhóm các code HTML, Javascript, CSS liên quan đến một đối tượng vào trong một khối logic và gọi là nó thành phần cơ bản (component - từ giờ đến cuối bài chúng ta sẽ chỉ dùng thuật ngữ component cho ngắn gọn). Như vậy có thể nói Component trong Vue.js giống như các module, với việc module hóa như vậy chúng ta có khả năng làm việc theo nhóm, xây dựng những hệ thống website sẽ đơn giản và dễ dàng bảo trì. Khái niệm tạo ra các khối giao diện có đủ cả nội dung và cách hành xử có khả năng sử dụng lại là cực kỳ quan trọng, tuy nhiên Vue.js component không phải là người đầu tiên đưa ra mà nó đã xuất hiện ở một hình hài khác ở trong React, Polymer hay Web component. Vue.js đã mở rộng khái niệm component xa hơn và thật sự độc đáo, những ưu việt của Vue component sẽ được giới thiệu sau, giờ đây chúng ta bắt tay vào tạo những component đầu tiên.

2. Tạo và đăng ký component vào hệ thống

Trong tài liệu hướng dẫn Vue.js component chính thức chúng ta thấy để đăng ký một component chúng ta sử dụng phương thức toàn cục Vue.component(), ví dụ dưới đây được viết lại như tài liệu hướng dẫn.

<html>
<head>
    <title>Component Vue.js - Example 1 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <div class="container" id="app">
        <button-counter></button-counter>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('button-counter', {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<div><h1>Ví dụ 1 về component trong Vue.js</h1><button class="btn btn-success" v-on:click="count++">Bạn đã nhấn {{ count }} lần.</button></div>'
        })
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

[jsfiddle url="https://jsfiddle.net/allaravel/srkyndqw/2/" height="300px" include="result,html,js" font-color="39464E" menu-background-color="FFFFFF" code-background-color="f3f5f6" accent-color="1C90F3"]

Tuy nhiên tài liệu này đã che giấu đi những phần phức tạp ẩn chứa đằng sau phương thức Vue.component, nếu bạn chỉ cần biết đăng ký component như thế nào thì ví dụ trên đây là quá đủ. Trước khi trở lại phương thức Vue.component() chúng ta cùng tìm hiểu về Vue.extend(). Vue.extend() được sử dụng để tạo ra các "lớp con" (subclass) của contructor của Vue với tham số đầu vào là một đối tượng chứa các tùy chọn của component. Trong Vue.extend, tùy chọn data phải là một function. Ví dụ:

<html>
<head>
    <title>Component Vue.js - Example 2 - Allaravel.com</title>
</head>
<body>
    <div id="mount-point"></div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        // Tạo constructor
        var Profile = Vue.extend({
            template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
            data: function () {
                return {
                    firstName: 'Walter',
                    lastName: 'White',
                    alias: 'Heisenberg'
                }
            }
        })
        // Tạo Profile instance và mount nó với thành phần có id là #mount-point
        new Profile().$mount('#mount-point')
    </script>
</body>
</html>

Tại sao phải nhắc đến Vue.extend() vì bản chất việc tạo và đăng ký component là đầu tiên tạo ra một contructor lớp con của Vue bằng Vue.extend(), sau đó sử dụng phương thức toàn cục Vue.component() để đăng ký phương thức khởi tạo này. Ví dụ đầu tiên có thể được viết lại như sau:

<html>
<head>
    <title>Component Vue.js - Example 3 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <div class="container" id="app">
        <button-counter></button-counter>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        var ButtonCounter = Vue.extend({
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button class="btn btn-success" v-on:click="count++">Bạn đã nhấn {{ count }} lần.</button>'
        })
        Vue.component('button-counter', ButtonCounter)
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

Chúng ta bàn về sự khác nhau giữa Vue.extend() và Vue.component(). Vue tự bản thân nó là một contructor, Vue.extend() là một lớp kế thừa phương thức (class inheritance method), nhiệm vụ của nó là tạo ra một subclass của Vue. Vue.component() thì khác, nó là một phương thức đăng ký thuộc tính giống như Vue.directive(), Vue.filter(), nhiệm vụ của nó là gắn kết một contructor với một chuỗi id mà Vue.js sử dụng để đưa template này vào khi render. Chú ý: Khi truyền đối tượng chứa các tùy chọn trực tiếp vào Vue.component(), nó sẽ tự động gọi đến Vue.extend(). Như vậy Vue.component() có thể coi như "sugar syntax" (cú pháp nhanh gọn) cho việc tạo và đăng ký một component. Một lý do khác tồn tại cả Vue.extend() và Vue.component là do Vue.js hỗ trợ cả hai kiểu API:

  • Kiểu class-based ví dụ ButtonCounter
  • Kiểu markup-based ví dụ <button-counter>

Mỗi kiểu API có những hữu ích riêng và Vue.js cung cấp cả hai cách như vậy sự mềm dẻo khi lập trình là tối đa. Dài dòng như vậy nhưng chốt lại để tạo và đăng ký component chỉ đơn giản là sử dụng phương thức Vue.component() với tham số là một đối tượng chứa các tùy chọn gồm:

  • template: Chứa mã HTML có cả các câu lệnh, chỉ thị của Vue.js như v-if, v-for, v-on... và toàn bộ mã phải nằm trong một thẻ HTML gọi là thành phần gốc.
  • data: Chứa dữ liệu liên quan đến component, chú ý data phải là dạng function do nếu không nó không độc lập ở các instance khác nhau của component.

Tên component có thể viết theo kiểu kebab-case, phân cách các từ bằng dấu gạch ngang hoặc PascalCase viết hoa các ký tự đầu tiên của từ. Xem thêm Các quy chuẩn đặt tên biến trong lập trình.

3. Khai báo template trong mã HTML

Với cách tạo một component bằng Vue.component() ở trên, chúng ta khai báo template trong tùy chọn template. Đây là một chuỗi, vậy nếu template này tương đối phức tạp thì sao chẳng lẽ cũng lại tống hết vào một chuỗi duy nhất, chưa kể là code không được định dạng thò ra thụt vào sẽ rất khó đọc cũng như debug lỗi sau này. Vue.js cho phép khai báo template này với một thẻ đặc biệt là thẻ <template>, ví dụ đầu tiên có thể viết lại như sau:

<html>
<head>
    <title>Component Vue.js - Example 4 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <template id="button-template">
        <div>
            <h1>Ví dụ 1 về component trong Vue.js</h1>
            <button class="btn btn-success" v-on:click="count++">Bạn đã nhấn {{ count }} lần.</button>
        </div>
    </template>
    <div class="container" id="app">
        <button-counter></button-counter>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('button-counter',{
            data: function () {
                return {
                    count: 0
                }
            },
            template: '#button-template'
        })
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

Kết quả thì vẫn như vậy thôi nhưng bạn thấy đấy code HTML của template đã được viết trong phần mã HTML body và có thể thò ra thụt vào rất dễ đọc, đặc biệt với các component phức tạp.

4. Sử dụng lại component

Component là khái niệm quan trọng nhất của Vue.js và việc sử dụng lại các component đã tạo nên sức mạnh cho Vue component. Ví dụ tiếp theo đây, khi bạn tạo ra 3 button như trong ví dụ 1:

<html>
<head>
    <title>Component Vue.js - Example 5 - Allaravel.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <template id="button-template">
        <button class="btn btn-success" v-on:click="count++">Bạn đã nhấn {{ count }} lần.</button>
    </template>
    <div class="container" id="app">
        <h1>Ví dụ 5: Sử dụng lại component trong Vue.js</h1>
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </div>
    <script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
        Vue.component('button-counter',{
            data: function () {
                return {
                    count: 0
                }
            },
            template: '#button-template'
        })
        new Vue({
            el: '#app'
        });
    </script>
</body>
</html>

[jsfiddle url="https://jsfiddle.net/allaravel/0ndxpaob/" height="300px" include="result,html,js" font-color="39464E" menu-background-color="FFFFFF" code-background-color="f3f5f6" accent-color="1C90F3"]

Việc sử dụng lại component thật đơn giản phải không, các component sử dụng lại vẫn có đầy đủ các tính năng về nội dung và hoạt động trên nó. ## 5. Đăng ký component toàn cục và cục bộ

5.1 Đăng ký toàn cục

Khi bạn đăng ký component bằng phương thức Vue.component() thì các component này được đăng ký toàn cục (globally registered), nghĩa là chúng có thể được sử dụng ở bất kỳ đầu trong Vue instance gốc được tạo ra bằng câu lệnh new Vue. Ví dụ:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

Khi đăng ký bằng Vue.component() các component-a, component-b, component-c có thể sử dụng ở bất kỳ đâu mà Vue instance mount vào, thậm chí 1 trong 3 component này có thể đưa vào bên trong các component khác.

5.2 Đăng ký cục bộ

Đăng ký toàn cục gặp phải một vấn đề khi sử dụng với các hệ thống build code như Webpack, các component toàn cục vẫn được đóng gói vào phiên bản cuối cùng mặc dù có thể nó không được gọi đến, việc này làm cho dung lượng ứng dụng không được tối ưu do có dư thừa code Javascript. Trong trường hợp này, chúng ta cần định nghĩa các component ở dạng các đối tượng đơn thuần trong Javascript:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

Sau đó định nghĩa các component trong tùy chọn components của Vue instance:

new Vue({
  el: '#app'
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

Với cách đăng ký cục bộ (locally registered) các component không thể lồng vào nhau như ở đăng ký toàn cục. Do vậy nếu muốn sử dụng component A trong component B chúng ta buộc phải code như sau:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

6. Kết luận

Vue component thật sự là quá hay, giờ đây với các ứng dụng thay vì bắt tay code chúng ta cần xem những thành phần nào có thể "component hóa" giúp cho code cực kỳ ngắn gọn súc tích. Mỗi khi cần thay đổi các thành phần theo yêu cầu, chúng ta chỉ đơn giản thay đổi ở một nơi và tất cả những nơi sử dụng lại component sẽ được áp dụng ngay. Bài viết thuộc chương 4 Khóa học Vue.js 2 miễn phí, các khái niệm cơ bản nhất về Vue.js component, những bài viết tiếp theo chúng ta sẽ cùng nhau đi sâu vào một số khái niệm phức tạp hơn.


CÁC BÀI VIẾT KHÁC

FirebirD

Đam mê Toán học, Lập trình. Sở thích chia sẻ kiến thức, Phim hài, Bóng đá, Cà phê sáng với bạn bè.

Vue.js Devtools công cụ debug khi viết ứng dụng

Computed property tăng hiệu suất Vue.js với thuộc tính "bộ đệm"

6 Bình luận trong "Vue.js component xây dựng ứng dụng theo cách module hóa"

  1. Vuer

    2 years ago

    Phản hồi
    Em là lính mới với Vuejs, bác nào có thể diễn giải kỹ hơn về props trong component giúp được không ạ, tiếng Anh em hơi đuối, đọc tài liệu gốc ở trang https://vuejs.org/v2/guide/components.html thấy khoai quá
    1. FirebirD

      2 years ago

      Phản hồi
      Đã cập nhật thêm phần kiến thức làm việc giữa các component trong một project, có liên quan đến props và event
  2. truong

    2 years ago

    Phản hồi
    thanks ad
  3. truong

    2 years ago

    Phản hồi
    thanks ad nhieu a
  4. phuong2t

    1 year ago

    Phản hồi
    Tuyệt cú mèo
  5. Huy

    1 year ago

    Phản hồi
    Trong nội dung bài học vẫn thấy thiếu một số link như Áp dụng hệ thống module cùng component. Vậy làm sao để tìm bài này đọc vậy Add. Nên bổ sung đầy đủ link cho mọi người tham khảo. Thanks add

Thêm bình luận