從結構上看,組件之於實例,就比如輪子之於汽車。從屬性和方法來看,組件有實例的大部分方法,若是Vue實例是孫悟空,組件就比如實例的一個毫毛,變化無窮卻爲Vue實例所用。javascript
目錄:html
組件的註冊vue
is的做用java
event,props,soltsnode
動態組件git
有兩種方式註冊Vue組件:全局註冊和局部註冊,就好像歐元和英鎊的區別,前者能夠在各Vue實例中使用,後者只能在註冊他的Vue實例或者父組件中使用。若是在組件中使用組件,就造成了組件的嵌套,若是組件裏嵌套的組件是本身,就造成組件的遞歸。es6
總之:組件由兩部分構成,github
一部分是須要自定義的tag-name,如下面爲例,tagname是<my-component>,數組
另外一部分是options對象,裏面包含了該組件的模板,方法,props,data等細節瀏覽器
全局註冊:
Vue.component('my-component', { // 選項 })
局部註冊:
var options={template:....}//組件的選項對象 new Vue({ el:'#man', components:{ 'my-component',options } });
將組件掛載到已存在元素上時,遇到某些元素,會發生尷尬的事情:如<ul> , <ol>
, <table>
,<select>這些標籤,他們只認識<li>,<tr>,<option>這些標籤,想把<my-component>插進去,人家不認識,這時就要is發揮做用了:
<ul> <my-component></my-component> </ul>
上面這樣瀏覽器不給面子,須要變成這樣:
<ul> <li is='my-component'></li> </ul>
當使用單文件組件時,就當上面是廢話,也就是說<ul>中能夠有組件了。(見這裏)動態組件也有一個is屬性,用來切換不一樣的組件,咱們下面再說
下面說說我以爲組件中的三個重點:prop,events和slots。當我看到組件這部分時,以前沒有接觸過mvvm類型的框架,因此到這裏感受是極限了,這時,找到熟悉的事物做類比是一個好辦法。若是把組件比成一間房子,上面的三隻就是房子用來和外界通訊的門窗。
在開始以前:應該記住一張圖和一句話:
這張圖對應的意思是:父組件經過 props 向下傳遞數據給子組件,子組件經過 events 給父組件發送消息。
想象一個場景。2048遊戲裏面,兩個子組件中的數據合併了,產生一個addscore事件,須要通知父組件容器,這時,就能夠用自定義事件了:
//父組件中 <father v-on:addscore="addscore"></father> function addscore(){ this.score++; } //子組件中 this.$emit('addscore');
注意 ,在子組件中,子組件只負責觸發這個自定義事件,經過$emit方法來觸發,而在父組件中則定義事件觸發以後的回調函數。好吧,其實vue官方教程的兩個button觸發add事件看起來是個更好的例子。。。。
再想象一個場景,2048中,父組件中的data中有一個定義了全部card的值的數組,如今要把這些值傳到每個card中,這時就用到props:
//爹組件 //在模板中,爲子組件寫一個自定義屬性card,用來把cardNum傳給子組件 <children :card="card_num"></children> data:{card_num:8} //****子組件中****** <div>{{card}}</div> 在組件的props字段中加入子組件的自定義屬性 { data:.... computed:.... props:{card:null} }
其實理解起來很簡單,vue的子組件對父組件來講被包裝成爲一個相似於<children></children>的標籤,正如你在父組件中看到的那樣。可是vue爲咱們留了一個props屬性,就像上帝給人類五官用來感覺世界同樣,組件用props和自定義事件用來和父組件傳遞消息。
這也是一種封裝,對父組件隱藏了內部的實現,只留下了props做爲接口。接口在現實世界也很常見,好比顯示器對主機的接口,你沒必要管顯示器的內部實現,只要知道接上主機就能顯示信息了就行。
若是你瞭解過es6的模板字符串,那麼理解起這個來將絕不費勁。我當時但是被這個slots搞得稀裏糊塗的。。。固然當時不知道模板引擎,也不知道模板字符串。slots就是在組件中插入內容的機制。
在<p>等原生的標籤裏插入內容很簡單,就直接寫就好了(說了一句廢話),而在組件中寫入內容就有講究了,好比<children>我仍是個寶寶</children>,因爲組件的模板通常是一堆原生標籤一塊兒構成的,那麼上面這麼寫,究竟應該把內容插到那個元素中就成了問題。因而就有了<slot></slot>元素。
solt元素就是用來接受父組件放到子組件的內容的。不知爲何,到了這裏我會想起學習機上插遊戲卡的例子。。。舉個例子:
//學習機組件 <div> <h2>小霸王學習機</h2> <slot> 內置魂鬥羅 </slot> </div>
//小朋友父組件 <div> <h1>我要玩遊戲</h1> <xue-xi-ji> <p>插入雙截龍遊戲卡</p>//插入的內容 </xue-xi-ji> </div>
最後獲得的就是小學生愉快的玩雙截龍了
<div> <h1>我要玩遊戲</h1> -------------------------------組件區域—————————————— <h2>小霸王學習機</h2> ————————slot區域—————————————— <p>插入雙截龍遊戲卡</p>//插入的內容 </div>
當父組件不往子組件標籤中添加任何字符時,子組件會顯示默認內容,若是有的話,也就是說魂鬥羅。。
具名slot是說組件中有大於一個地方須要插值時,須要給slot取個名字。就像電腦的接口,有usb的,也有接投影的HDMI接口,爲的是將多條內容放到正確的地方。
咱們知道,在組件內部,this指向組件本身,那麼組件的slot內容能夠經過this.$slots得到被插入的vnode節點。
動態組件就是爲了適應頁面的局部刷新而生的,舉個我用過的例子:todolist在線小demo
當我點擊寫日記button時,頁面會變成一個markdown編輯器界面。這就是動態組件。實現的代碼以下
<keep-alive> <compoment v-bind:is='currentview'></compoment> </keep-alive>
methods: { toggleview: function() { this.currentview = (this.currentview == 'todolist') ? 'write' : 'todolist'; } },
當我點擊上面的button時,觸發toggleview方法,致使is綁定的組件名發生變化,若是當前是write組件,那麼變成todolist組件。
那麼<keep-alive>標籤又有什麼用呢?標籤字面意思是活着。。就是當todolist組件由顯示變成隱藏時,組件的數據狀態會被保存下來而不是被徹底destory,當組件由隱藏再次變爲顯示時,當前的狀態得以保留。比方你在write組件中寫一段md文檔,而後切換回todolist組件,若是沒有keep-alive組件,再切換回write組件時,以前編輯的東西就會丟失。