組件介紹
組件系統(tǒng)是Vue.js其中一個重要的概念,他提供了一種抽象,讓我們可以使用獨(dú)立可復(fù)用的小組件來構(gòu)建大型應(yīng)用,任意類型的應(yīng)用界面都可以抽象為一個組件樹。

<b>那么什么是組件呢?</b>
組件可以擴(kuò)展HTML元素,封裝可重用的HTML代碼,我們可以將組件看做自定義的HTML元素。
組件的創(chuàng)建和注冊
<b>基本步驟</b>
Vue.js的組件的使用有3個步驟:構(gòu)建組件構(gòu)造器、注冊組件和使用組件。

運(yùn)行結(jié)果如下

可以看到,使用組件合使用普通的HTML元素沒什么區(qū)別。
<b>理解組件的創(chuàng)建和注冊</b>
我們用以下幾個步驟來理解組件的創(chuàng)建和注冊:
- Vue.extent()是Vue構(gòu)造器的拓展,調(diào)用Vue.extend()創(chuàng)建的是一個組件構(gòu)造器,而不是一個具體的組件實(shí)例。
- Vue.extend()構(gòu)造器有一個選項(xiàng)對象,選項(xiàng)對象的template屬性用于定義組件要宣言的HTML。
- 使用Vue.component()注冊組件時,需要提供2個參數(shù),第1個參數(shù)是組件的標(biāo)簽,第2個參數(shù)是組件構(gòu)造器?!炯?:組件名稱,2:組件模板】
- Vue.component()方法內(nèi)容不會調(diào)用組件構(gòu)造器,創(chuàng)建一個組件實(shí)例。
- 組件應(yīng)該掛在到某個Vue實(shí)例下,否則它不會生效。
全局組建和局部組件
調(diào)用Vue.component()注冊組件時,組件的注冊時全局的,這意味著該組件可以在任意Vue實(shí)例下使用。
如果不需要全局注冊,或者是讓組件使用在其他組件內(nèi),可以用選項(xiàng)對象的<b>components</b>屬性實(shí)現(xiàn)局部注冊。

由于my-component組件時注冊在#app元素對應(yīng)的Vue實(shí)例下的,所以他不能在其他Vue實(shí)例下使用。


如果你這樣做了,瀏覽器會提示一個錯誤:

父組件和子組件
我們可以再組件中定義并使用其他組件,這就構(gòu)成了父子組件的關(guān)系。

這段代碼的運(yùn)行結(jié)果如下:

我們分幾個步驟來理解這段代碼:
- var Child=Vue.extend(...)定義了一個Child組件構(gòu)造器
- var Parent=Vue.extend(...)定義了一個Parent組件構(gòu)造器
- components:{'child-component':Child},將Child組件注冊到Parent組件,并將Child組件的標(biāo)簽設(shè)置為child-component
- template:'< p >This is a Parent component< /p ><child-component></child-component>' ,將Parent組件內(nèi)以標(biāo)簽的形式使用Child組件
- Vue.component('parent-component',Parent)全局注冊Parent組件
-
在頁面內(nèi)使用<parent-component>標(biāo)簽渲染Paren組件的內(nèi)容,同時Child組件的內(nèi)容也被渲染出來
Child組件是在Parent組件中注冊的,它只能在Parent組件中使用,確切地說:子組件只能在父組件的template中使用。
<b>請注意下面兩種子組件的使用方式是錯誤的:</b>
-
以子標(biāo)簽的形式在父組件中使用
為什么這種方式無效呢?應(yīng)為當(dāng)子組件注冊到父組件時,Vue.js會編譯好父組件的模板內(nèi)容,模板的內(nèi)容已經(jīng)決定了父組件要渲染的HTML。
<parent-component>...</parent-component>相當(dāng)于運(yùn)行時,它的一些子標(biāo)簽只會被當(dāng)做普通的HTML來執(zhí)行,<child-component></child-component>不是標(biāo)準(zhǔn)的HTML標(biāo)簽,會被瀏覽器直接忽略掉。 - 在父組件標(biāo)簽外使用子組件
運(yùn)行這段代碼,瀏覽器會提示一下錯誤
組件注冊語法糖
以上組件注冊的方式有些繁瑣,Vue.js為了簡化這個過程,提供了注冊<a >語法糖</a>。
使用Vue.component()直接創(chuàng)建和注冊組件:

Vue.component()的第1個參數(shù)是標(biāo)簽名稱,第2個參數(shù)是一個選項(xiàng)對象,使用選項(xiàng)對象的template屬性定義組件模板。
使用這種方式,Vue會自動調(diào)用Vue.extend()。
在選項(xiàng)對象的components屬性中實(shí)現(xiàn)局部注冊:

使用script或template標(biāo)簽
盡管語法糖簡化了組件注冊,但在template選項(xiàng)中拼接HTML元素比較麻煩,這也導(dǎo)致了HTML和JavaScript的高耦合性。
Vue.js提供了兩種方法將定義在JavaScript中的HTML模板分離出來。
<b>使用< script >標(biāo)簽</b>

template選線現(xiàn)在不再是HTML元素,而是一個id,Vue.js根據(jù)這個id查找對應(yīng)的元素,然后將這個元素內(nèi)的HTML作為模板進(jìn)行編譯。

<b>注意:</b>使用< script >標(biāo)簽時,type指定為text/x-template,意在告訴瀏覽器這不是一段js腳本,瀏覽器在解析HTML文檔時會忽略< script >標(biāo)簽內(nèi)定義的內(nèi)容。

使用< script >或< template >標(biāo)簽來定義組件的HTML模板,使得HTML代碼和JavaScript代碼是分離的,便于閱讀和維護(hù)。
組件的el和data選項(xiàng)
傳入Vue構(gòu)造器的多數(shù)選項(xiàng)可以用在Vue.extend()或Vue.component()中,不過有兩個特例:data和el。
Vue.js規(guī)定:在定義組件的選項(xiàng)是,data和el選項(xiàng)必須使用函數(shù)。
如果data選項(xiàng)指向某個對象,這意味著所有的組件實(shí)例共用一個data。我們應(yīng)當(dāng)使用一個函數(shù)作為data選項(xiàng),讓這個函數(shù)返回一個新對象:

使用props
組件實(shí)例的作用域是孤立的,這意味著不能并且不應(yīng)該在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)??梢允褂胮rops把數(shù)據(jù)傳遞個子組件。
<b>props基礎(chǔ)示例</b>
下面代碼定義了一個子組件my-component,在Vue實(shí)例中定義了data選項(xiàng)。

為了便于理解,可以將這個Vue實(shí)例看做my-component的父組件。如果我們想使用父組件的數(shù)據(jù),則必須先在子組件中定義props屬性,也就是props:['myName','myAge']這行代碼。
定義子組件的HTML模板:

將父組件數(shù)據(jù)通過已定義好的props屬性傳遞給子組件:

<b>注意:</b>在子組件中定義prop時,使用了camelCase命名法。由于HTML特性不區(qū)分大小寫,camelCase的prop用于特性時,需要轉(zhuǎn)為kabab-case(短橫線隔開)。例如,在prop中定義的myName,在用作特性時需要轉(zhuǎn)換成my-name。

父組件是如何將數(shù)據(jù)傳遞給子組件的呢?




