Cơ bản về component — Vue.js

Related Articles

Ví dụ cơ bản

Đây là ví dụ về một component trong Vue :

Vue.component(' button-counter ', {

data:

function ()

{

return {

count: 0



}

} ,

template:

''



} )

Component là các đối tượng Vue có thể sử dụng lại được với một cái tên: trong trường hợp này là . Chúng ta có thể dùng component này như là một phần tử bên trong đối tượng Vue gốc được tạo bởi new Vue:

new Vue({ el: ' # components-demo ' })



Vì là những đối tượng Vue tái sử dụng được, các component cùng nhận các tùy chọn như new Vue, ví dụ data, computed, watch, methods, và các hook vòng đời. Các ngoại lệ duy nhất là một số ít tùy chọn đặc biệt cho root như el.

Tái sử dụng component

Bạn hoàn toàn có thể tái sử dụng component bao nhiêu lần tùy ý :

Để ý là khi bấm các nút trên đây, mỗi nút giữ một giá trị count riêng hoàn toàn tách biệt. Điều này là vì mỗi khi bạn dùng một component, một đối tượng của component đó được tạo mới.

data phải là một hàm

Bạn có thể cũng đã để ý thấy rằng khi định nghĩa component , chúng ta không truyền thẳng một object vào data như thế này:

data : {

count: 0



}

Thay vào đó, tùy chọn data của component phải là một hàm. Bằng cách này, mỗi đối tượng của component có thể duy trì một bản sao riêng biệt của đối tượng data được trả về:

data:

function ()

{

return {

count: 0



}

}

Nếu Vue không có quy tắc này, bấm một nút sẽ tác động ảnh hưởng đến tài liệu của hàng loạt những đối tượng người dùng khác, như thế này :

Tổ chức component

Một ứng dụng thường được tổ chức triển khai dưới dạng một cây component lồng nhau :

Cây component

Ví dụ, bạn hoàn toàn có thể có những component cho header, sidebar, khu vực nội dung, mỗi component này lại chứa những component dành cho trình đơn, blog post, vân vân .

Để có thể được sử dụng trong các template, component phải được đăng kí. Có hai cách đăng kí component: toàn cụccục bộ. Trên đây chúng ta chỉ mới đăng kí component ở cấp toàn cục với Vue.component:

Vue.component(' my-component-name ', {

} )

Component đăng kí ở cấp toàn cục có thể được dùng trong template của bất kì đối tượng Vue gốc (new Vue) nào được tạo ra sau đó – và trong tất cả các component con trên cây component của đối tượng đó.

Lúc này thì đó là toàn bộ những gì bạn cần biết về đăng kí component, nhưng sau khi đọc xong trang này và hiểu thêm về component, bạn nên quay lại và đọc bản hướng dẫn không thiếu về đăng kí component .

Truyền dữ liệu xuống component con bằng prop

Trên đây tất cả chúng ta có nhắc đến việc tạo component cho những bài viết trên blog. Vấn đề là, component không có ích gì nếu không có tài liệu truyền vào, ví dụ tựa đề và nội dung của bài đăng. Đó là lúc tất cả chúng ta cần đến prop .

Prop là các thuộc tính tùy chỉnh mà bạn có thể đăng kí trên một component. Khi một giá trị được truyền vào một prop, nó trở thành một “_prop_erty” của đối tượng component đó. Để truyền tựa đề (title) vào component bài viết (blog-post), chúng ta sử dụng tùy chọn props:

Vue.component(' blog-post ', {

props: [' title '],

template:

'

{{ title }}

'

} )

Một component có thể có bao nhiêu prop tùy ý, và prop có thể nhận bất kì giá trị gì. Trong template trên đây, bạn có thể thấy là chúng ta có thể truy xuất giá trị này trên đối tượng component, giống như với data.

Một khi prop đã được đăng kí, bạn hoàn toàn có thể truyền tài liệu vào như một thuộc tính tùy chỉnh, ví dụ :


Tuy nhiên, trong một ứng dụng điển hình, bạn có lẽ sẽ có một mảng các bài viết trong data:

new Vue({

el: ' # blog-post-demo ',



data : {

posts : [

{ id: 1, title: ' Giới thiệu về Vue ' },

{ id: 2, title: ' Các khái niệm trong Vue ' },

{ id: 3, title: ' Vue cơ bản và vô cùng nâng cao ' }



]

}

} )

và sau đó render một component cho mỗi bài viết :

v-for=" post in posts "

v-bind : key=" post.id "

v-bind : title=" post.title "

>

Trên đây, bạn có thể thấy là chúng ta dùng v-bind để truyền động prop. Cách làm này đặc biệt hữu ích khi bạn không biết trước được chính xác nội dung bạn sẽ render, như khi lấy bài viết từ một API.

Lúc này thì đó là tổng thể những gì bạn cần biết về prop, nhưng sau khi đọc xong trang này và hiểu thêm về component, bạn nên quay lại và đọc bản hướng dẫn khá đầy đủ về props .

Một phần tử gốc đơn lập

Khi xây dựng component cho bài viết, thế nào rồi template của bạn cũng sẽ chứa nhiều thứ hơn là mỗi title. Ít nhất bạn cũng sẽ có thêm nội dung bài viết:

{{ post.title }}

Nhưng nếu bạn sử dụng template này, Vue sẽ thông báo lỗi every component must have a single root element (mỗi component phải có một phần tử gốc đơn lập). Bạn có thể sửa lỗi này bằng cách bọc template trong một phần tử cha, ví dụ:



{{ post.title }}

Gửi thông tin đến đối tượng cha bằng sự kiện

Khi xây dựng component , một số tính năng có thể cần giao tiếp ngược lên đối tượng cha. Ví dụ, chúng ta muốn thêm tính năng phóng to font chữ của bài viết mà vẫn giữ nguyên các thành phần khác trên trang.

Chúng ta có thể hỗ trợ tính năng này bằng cách thêm thuộc tính postFontSize trong data của đối tượng cha:

new Vue({

el: ' # blog-posts-events-demo ',



data : {

posts : [ ] ,

postFontSize: 1



}

} )

Thuộc tính này hoàn toàn có thể được dùng trong template để quản lí cỡ chữ của tổng thể những bài viết :





v-for=" post in posts "

v-bind : key=" post.id "

v-bind : post=" post "

>

Bây giờ hãy thêm một nút để tăng cỡ chữ ngay trước nội dung của mỗi bài viết :

Vue.component(' blog-post ', {

props: [' post '],

template: `





{{ post.title }}



Phóng to



`

} )

Ví dụ trên đây và một số ít ví dụ tiếp theo sử dụng template literal để giúp template nhiều dòng dễ đọc hơn. Tính năng này không hoạt động giải trí trên Internet Explorer ( IE ), do đó nếu phải tương hỗ IE và không sử dụng những thư viện hoặc ngôn từ biên dịch ( như Babel hoặc TypeScript ), bạn hoàn toàn có thể dùng dấu chéo ngược thay thế sửa chữa .

Tuy nhiên, nút này hiện không làm gì cả :



Phóng to

Khi nút Phóng to được bấm, chúng ta muốn yêu cầu đối tượng cha phóng to cỡ chữ của tất cả các bài viết. May thay, các đối tượng Vue cung cấp một hệ thống sự kiện tùy biến để giải quyết vấn đề này. Để phát ra (emit) một sự kiện, chúng ta có thể gọi phương thức $emit cho sẵn và truyền vào tên của sự kiện:



Phóng to

Sau đó trong component , chúng ta có thể lắng nghe sự kiện này bằng v-on giống như với các sự kiện DOM:

...

v-on : enlarge-text=" postFontSize + = 0.1 "

>

Gửi giá trị khi phát ra sự kiện

Đôi khi bạn cần gửi một giá trị cụ thể nào đó kèm với một sự kiện. Ví dụ, chúng ta có thể cho quyền quyết định mức độ phóng đại của cỡ chũ. Trong những trường hợp này, ta có thể dùng tham số thứ hai của $emit:



Phóng to

Sau đó, khi lắng nghe sự kiện này ở đối tượng cha, chúng ta có thể truy xuất đến giá trị của sự kiện được phát ra với $event:

...

v-on : enlarge-text=" postFontSize + = USD sự kiện "

>

Hoặc, nếu đó là một phương pháp xử lí sự kiện :

...

v-on : enlarge-text=" onEnlargeText "

>

thì giá trị sẽ được truyền vào dưới dạng tham số tiên phong của phương pháp đó :

methods : {

onEnlargeText:

function (enlargeAmount)

{

this.postFontSize += enlargeAmount



}

}

Sử dụng v-model với component

Các sự kiện tùy biến có thể được sử dụng để tạo ra các tùy biến hoạt động với v-model. Nhớ rằng:



là trọn vẹn tương đương với :

v-bind : value=" searchText "

v-on : input=" searchText = USD event.target.value "

>



Khi sử dụng trên một component, v-model là tương đồng với:

v-bind : value=" searchText "

v-on : input=" searchText = USD sự kiện "

>

Tuy nhiên để hoạt động được, phần tử trong component phải:

  • Ràng buộc thuộc tính value với một prop value
  • Trong sự kiện input, phát ra sự kiện input tùy biến với giá trị mới

Một đoạn code hoàn hảo nhìn tương tự như như thế này :

Vue.component(' custom-input ', {

props: [' value '],

template: `



v-bind : value = " value "

v-on : input = " USD emit ( ' input ', USD event.target.value )

>

`



} )

Giờ thì v-model sẽ hoạt động ổn thỏa:


Lúc này thì đó là tổng thể những gì bạn cần biết về những sự kiện tùy biến của component, nhưng sau khi đọc xong trang này và hiểu thêm về component, bạn nên quay lại và đọc bản hướng dẫn vừa đủ về sự kiện tùy biến .

Phân phối nội dung với slot

Cũng như so với những thành phần HTML, việc hoàn toàn có thể truyền nội dung vào một component thường là rất hữu dụng, ví dụ :



Đã xảy ra cái gì gì đó .

hoàn toàn có thể render thành :

Đã xảy ra cái gì gì đó .

Việc này là rất đơn giản với phần tử tùy biến của Vue:

Vue.component(' alert-box ', {

template: `



Lỗi!





`

} )

Như bạn đã thấy trên đây, chúng ta chỉ cần thêm vào nơi cần thể hiện nội dung, và thế là xong!

Hiện nay thì đó là tổng thể những gì bạn cần biết về slot, nhưng sau khi đọc xong trang này và hiểu thêm về component, bạn nên quay lại và đọc bản hướng dẫn khá đầy đủ về slot trong component .

Component động

Đôi khi bạn muốn chuyển qua lại giữa những component, ví dụ như trên một giao diện tab :

Ví dụ trên hoạt động nhờ thuộc tính đặc biệt is của một component trong Vue:



Trong ví dụ trên, currentTabComponent có thể chứa:

  • tên của một component đã được đăng kí, hoặc
  • object chứa các tùy chọn của một component

Bạn hoàn toàn có thể xem và thử biến hóa mã nguồn của ví dụ trên trên JSFiddle. Bạn cũng hoàn toàn có thể dùng phiên bản này để xem ví dụ về cách ràng buộc vào object tùy chọn thay vì tên của component .

Lúc này thì đó là tổng thể những gì bạn cần biết về component động, nhưng sau khi đọc xong trang này và hiểu thêm về component, bạn nên quay lại và đọc bản hướng dẫn khá đầy đủ về component động và không đồng nhất .

Lưu ý về việc parse DOM template

Bên trong các phần tử như

    ,

      ,

      chúng ta chỉ có thể chứa một số phần tử nhất định (chẳng hạn

        chỉ chấp nhận

      • ), trong khi đó các phần tử như lại chỉ có thể được đặt trong một số phần tử nhất định khác như , , hay .

        Điều này sẽ dẫn đến một số ít yếu tố khi dùng component với những thành phần có những hạn chế vừa nêu, ví dụ :

        
        

        Ở đây component sẽ bị xem là một phần tử không hợp lệ bên trong

        và bị đẩy ra ngoài (hoisted out), dẫn đến lỗi khi render. Để giải quyết vấn đề này, ta có thể dùng thuộc tính đặc biệt is:

        More on this topic

        Comments

        LEAVE A REPLY

        Please enter your comment!
        Please enter your name here

        Advertismentspot_img

        Popular stories