如何你沒有下面幾個問題,那這篇文章真的是一無是處。
- 組件的創(chuàng)建與引用
- 父組件與子組件的交互
- 組件與組件間的交互
0.1 談?wù)劷M件
我一開始是對組件有著深深的誤解,我個人直接把web中的組件強(qiáng)行等于安卓中的button啊,listview啊,其實(shí)是錯的。組件的劃分,并沒有那么嚴(yán)格,一個按鈕可以是一個組件,頁面的導(dǎo)航欄可以是一個組件。最好是一個頁面中,只包含盡可能少的大組件,在大組件中,盡可以包含功能相近的小組件。
導(dǎo)航欄可以是一個大組件,內(nèi)容可以是一個大組件,導(dǎo)航欄里又可以包含logo,具體欄目的導(dǎo)航。
上面都是我個人的理解。
1 組件的創(chuàng)建與引用
這里只談單文件系統(tǒng),一個.vue就是一個組件。
在單文件系統(tǒng)中,一個*.vue文件包含script、style、template標(biāo)簽。那么,如何在a.vue中,用b.vue中的組件呢?
import view from 'xxx/xxx/xxx.vue'
import Vue from 'vue';
Vue.component('你喜歡的標(biāo)簽名',view)
這樣在a的template中,就可以這么使用b了
<template>
<你喜歡的標(biāo)簽名></你喜歡的標(biāo)簽名>
<template>
然后呢,由此,就會扯出一坨別的問題
- 那怎么才能向子組件里傳數(shù)據(jù)?。?/li>
- 那收到父組件的數(shù)據(jù),子組件里要怎么用呢?
- 那完成了一些操作,子組件要怎么報告給父組件呢?
答:我也不知道 見第二章。
2. 組件與組件間的交互
- 那怎么才能向子組件里傳數(shù)據(jù)啊? prop
- 那收到父組件的數(shù)據(jù),子組件里要怎么用呢? 插槽
- 那完成了一些操作,子組件要怎么報告給父組件呢? 如果只是簡單的,用自定義事情,復(fù)雜的,可以使用第三章提到的vuex。
其實(shí)官方文檔都有這些的使用,地址點(diǎn)我。
但是我這個更是讀完后的一個重點(diǎn)??!我覺得我理一下更方便自己的理解與使用~
2.1 prop
實(shí)在是覺得官網(wǎng)的中文教程寫的好,花10分鐘就可以看完了,真的不想單純的復(fù)制過來水,沒意思。就再補(bǔ)充下單文件下的定義吧:
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
// 聲明 props
props: ['message'],
// 就像 data 一樣,prop 也可以在模板中使用
}
<style >
</style>
2.2 插槽
補(bǔ)充一下:怎么理解插槽。
如果子組件要接收父組件的內(nèi)容顯示,要放在哪里顯示呢?
子組件要怎么使用呢?
于是就引出了<slot>這個標(biāo)簽,見b.vue,它用作接收父組件中的數(shù)據(jù)
如a.vue(發(fā)數(shù)據(jù),和slot無關(guān))
<template>
<div>
<h1>我是父組件的標(biāo)題</h1>
<my-component>
<p>這是一些初始內(nèi)容</p>
<p>這是更多的初始內(nèi)容</p>
</my-component>
</div>
</template>
b.vue(收數(shù)據(jù))
<div>
<h2>我是子組件的標(biāo)題</h2>
<slot>
只有在沒有要分發(fā)的內(nèi)容時才會顯示。
</slot>
</div>
最后就顯示成了:
<div>
<h1>我是父組件的標(biāo)題</h1>
<div>
<h2>我是子組件的標(biāo)題</h2>
<p>這是一些初始內(nèi)容</p>
<p>這是更多的初始內(nèi)容</p>
</div>
</div>
slot還可以指定名字來接收數(shù)據(jù)。具名插槽
更詳細(xì)內(nèi)容看官網(wǎng)
2.3 事件
使用自定義事件做一些子組件與父組件的交互
- on(eventName) 監(jiān)聽事件
- emit(eventName) 觸發(fā)事件
我把官網(wǎng)例子搞過來切割一下,并做點(diǎn)詳細(xì)的解釋吧~
父組件的template:
<div id="counter-event-example">
<p>{{ total }}</p>
<!--increment是事件的名字,而引號后面的incrementTotal是函數(shù)名-->
<!-- button-counter就是一個子組件-->
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
可以看出,父組件訂閱了increment這個事件,那么自然,字組件就一定觸發(fā)了increment這個事件。
下面還是父組件的js:
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
子組件的template:
<button v-on:click="incrementCounter">{{ counter }}</button>
子組件的js:
data: function () {
return {
counter: 0
}
},
methods: {
incrementCounter: function () {
this.counter += 1
this.$emit('increment')
}
}
從代碼中可以看出,子組件的click可以觸發(fā)incrementcounter函數(shù),在這個函數(shù)里,又發(fā)射了increment事件。
更多細(xì)節(jié)請參考官網(wǎng)
3 組件與組件之間的通迅
如果:
- a.vue中的子組件想與b.vue中的子組件的通迅
- a.vue想與b.vue中的子組件的通迅
- a.vue中的子組件想與b.vue通迅
- a.vue的子組件的子組件想與b.vue的子組件通迅
- ......
想想就煩啊,這個時候,就要全局的vuex,就是狀態(tài)管理~
這個坑值得另開一篇文章講,等一個二。