來源 |?https://xueyuanjun.com/post/21929除了前面介紹的基本語法之外,Vue.js 還支持通過組件構(gòu)建復(fù)雜的功能模塊,組件可以稱得上是 Vue.js 的靈魂,是 Vue.js 框架提供的最強大的功能之一。接下來,我們就來給大家由淺入深地介紹如何在 Vue.js 中通過組件構(gòu)建不同的功能模塊。我們在列表渲染這篇教程中實現(xiàn)過一個 Web 編程語言列表功能,這里我們通過組件功能對之前的代碼進行重構(gòu)。在 vue_learning 目錄下新建一個 component 子目錄,然后新建一個 demo.html 文件存放本篇教程的代碼。Vue 組件的基本使用
在這個 HTML 文檔中,基于組件功能實現(xiàn) Web 編程語言列表渲染功能如下:<html lang="en"><head> <meta charset="UTF-8"> <title>Vue 組件開發(fā)入門title> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js">script>head><body> <div id="app"> <p> Web 編程語言:p> <languages>languages> div> <script> Vue.component('languages', { data: function () { return { languages: ['PHP', 'JavaScript', 'Golang'] } }, template: '' }) var app = new Vue({ el: '#app', });script>body>html>
可以看到,在這段代碼中,我們在初始化 Vue 實例之前通過 Vue.component 函數(shù)定義了一個名為 languages 的組件(通過第一個參數(shù)指定組件名):Vue.component('languages', { data: function () { return { languages: ['PHP', 'JavaScript', 'Golang'] } }, template: ''})
然后在第二個參數(shù)中定義這個組件的對象屬性,它的基本結(jié)構(gòu)和 Vue 全局對象實例類似,只是沒有通過 el 映射對應(yīng)的 HTML 視圖容器。我們通過 data 定義了這個組件的數(shù)據(jù)屬性(和 Vue 對象不同的是這里的 data 屬性返回的是函數(shù)而非對象),通過 template 定義了組件模板代碼,組件模板中可以使用 Vue 的所有基本語法,還可以引用該組件的 data 數(shù)據(jù)屬性。最后我們要渲染這個組件模板,可以在 HTML 視圖層中插入?即可,插入的位置必須位于 Vue 全局對象作用的 HTML 容器內(nèi),否則不會生效。在瀏覽器中預(yù)覽上述 HTML 文檔,渲染效果如下:注:組件定義代碼要放到 Vue 全局對象實例化之前,否則在對象容器初始化的時候無法識別?languages?元素。如果用類比的方式來看,Vue 組件和全局 Vue 對象很相似,繼承了它的幾乎所有屬性,除了 HTML 根元素,然后在全局對象作用的容器中通過組件名引入即可實現(xiàn)該組件的渲染,渲染時使用的是組件對象的 template 屬性,這通常是一段 HTML 代碼,我們可以在 template 字符串中通過調(diào)用組件的 data、methods、computed 等屬性/方法實現(xiàn)動態(tài)效果。這樣一來,如果把 Vue 組件名對應(yīng)的 HTML 元素看作組件對應(yīng)的根元素容器,那么 Vue 組件其實就是和 Vue 全局對象有著一致語法的「小生態(tài)」,這樣一來就極大降低了 Vue 組件的學(xué)習(xí)成本,也方便了不同組件之間的組合、嵌套、架構(gòu)。最終,Vue.js 框架可以在 Vue 全局對象容器作用域內(nèi)通過這樣的一個個語法結(jié)構(gòu)一致、實現(xiàn)功能不同的組件(這些組件之間或并行、或嵌套)的相互協(xié)同下,構(gòu)建出各種復(fù)雜的頁面功能和模塊。接下來,我們就來逐一介紹 Vue 組件支持的語法、組件間的通信和嵌套,并基于這些功能特性構(gòu)建復(fù)雜的功能模塊。組件嵌套和代碼復(fù)用
為了提高組件代碼的復(fù)用性,我們可以將上面列表中的列表項單獨拆分出來構(gòu)建一個粒度更細的組件 langugae:Vue.component('language', { template: '<li><slot>slot>li>'}
這里我們使用了??表示從調(diào)用該組件的父作用域中傳遞文本來渲染,該功能稱之為插槽,后面我們會詳細介紹插槽的使用和語法,這里先了解即可。接下來,我們定義一個調(diào)用 language 組件的父級組件 languages:Vue.component('languages', { data: function () { return { languages: ['PHP', 'JavaScript', 'Golang'] } }, template: ''})
這樣一來,我們就實現(xiàn)了在 languages 父組件中嵌套調(diào)用子組件 language 進行渲染的功能,相應(yīng)的代碼很簡單,唯一需要注意的是就是我們在父組件的模板代碼中調(diào)用 language 組件時,通過?{{ language }}?將對應(yīng)的文本傳遞給了子組件,這樣對應(yīng)的語言字符串就會替換子組件中的??插槽渲染出來。在瀏覽器中刷新這個 HTML 文檔,渲染效果和之前完全一樣:如果我們打開開發(fā)者工具中的 Vue Devtools 擴展標簽頁,可以看到現(xiàn)在的 Components 中已經(jīng)包含了 languages 和 language 組件:除了插槽之外,還可以通過 props 在父組件和子組件之間傳遞數(shù)據(jù),我們將在下篇教程給大家演示 Vue 組件之間的通信和事件處理。