組件是可複用的 Vue 實例。html
本質上是一個對象,該對象包含data
、computed
、watch
、methods
、filters
以及生命週期鉤子等成員屬性。vue
組件結構:編程
{ data(){ return { // } }, computed:{ displayName(){ return ''; } }, methods:{ onClickHandler(params){ // do something } } }
data屬性維護一個組件內部狀態,其他組件正常狀況下不可見。api
props
傳遞給子組件;$emit
的方式傳遞給父組件;能夠經過this.$refs.ref.$data
在mounted
生命週期內獲取子組件的內部狀態;ide
computed
和偵聽屬性watch
只能監聽 響應式依賴 的變化,而$refs
非響應式。一個組件的 data 選項必須是一個函數。函數
data選項有兩種定義方式: 1、對象形式: ``` data:{ //引用該組件的地方,共用一個狀態的引用,以致於,只要有一處修改了$data中的某一屬性值,其它引用該組件的地方也跟隨着改變該屬性值(其實,不是跟隨,原本就是同一個指向)。 } ``` 2、函數形式: ``` data(){ return { //引用該組件的地方,每個組件都會得到獨立的引用,互不干擾。 } } ```
區別 | method | computed | filter |
---|---|---|---|
類型 | 函數 | 數據變量 | 函數 |
用途 | 做事件處理函數 | 做數據 | 做管道符 |
做用範圍 | 組建內 | 組建內 | 組建內(局部註冊)、全局(全局註冊) |
參數 | 能夠帶參 | 不帶參(非函) | 帶參 |
返回值 | 不要求 | 必須有 | 必須有 |
觸發 | 交互時觸發 | 在它的相關依賴發生改變時纔會從新求值 | 傳入的數據變化時執行 |
注意:ui
Vue
中並非全部的屬性都是響應式的,如$refs
沒法監聽它的變更;組件構建的主要區別在於模板的生成方式。this
{ template: '<h1 v-if="level === 1">簡單示例</h1>', props: { level: { type: Number, required: true } } }
id
標識的一段script
標籤包裹的HTML片斷;<script type="text/x-template" id="anchored-heading-template"> <h1 v-if="level === 1"> 簡單示例 </h1> </script> { template: '#anchored-heading-template', props: { level: { type: Number, required: true } } }
createElement
方法做爲第一個參數用來建立VNode
;createElement
接收三個參數:組件根節點類型、組件配置對象、子節點(官方關於組件配置對象的說明);{ render: function (createElement) { return createElement( 'h' + this.level, // tag name 標籤名稱 this.$slots.default // 子組件中的陣列 ) }, props: { level: { type: Number, required: true } } }
單文件組件將模板、邏輯、樣式在結構上分離,保存在同一個文件中。spa
<template> <div> ... </div> </template> <script> ... export default{ ... } ... </script> <style> ... </style>
template | 單文件 | render |
---|---|---|
一行的簡單結構 | 常規的選擇 | 前邊兩種方案解決不了時候的選擇(靈活性高) |
注意:插件
template
標籤元素做根DOM,有且僅有一個。以上幾種方案定義的組件本質上都是一個對象,獲取該對象(假設變量名爲TabBar),要求只在另外一個組件(假設變量名爲App)內使用:
App
組件的配置對象:
{ components:{ 'tab-bar': TabBar, } }
這樣就是局部註冊,該組件TabBar
只能在App
模板中使用<tab-bar></tab-bar>
,其它組件對TabBar
不可見。
以上幾種方案定義的組件本質上都是一個對象,獲取該對象(假設變量名爲TabBar),要求項目內任何組件可以使用:
通常在項目的入口文件(如:腳手架搭建項目的main.js
)中:
Vue.component('tab-bar',TabBar);
這樣就是全局註冊,該組件TabBar
能在整個項目內使用<tab-bar></tab-bar>
,全部組件對TabBar
可見。
如下用本身的語言將生命週期鉤子表述一下,若是有不對的地方,請校訂:
在這個時候,生命週期函數已經準備好。
this
調用根實例上注入的$router
、$store
等對象。在這個時候,當前組件實例this
上的屬性($data
、props
、$methods
...)已經注入綁定,能夠調用本實例上的成員屬性;
在進入本生命週期以前,會進行如下判斷:
是否有el
選項(指定掛載目標):
el
選項的是根實例;el
選項的是非根實例(默認掛載元素爲組件調用的位置);是否有template
選項:
template
選項的是內聯模板;template
選項的是單文件組件;render
選項的判斷;最終這些模板都會轉換爲render
函數進行渲染!!!
在本生命週期以前,已經將模板渲染爲真實DOM,其中vm.$el
爲組件實例的根DOM元素;
this.$refs.ref
的場所;