一頁圖紙,顧名思義真的是一頁圖紙,讓我們來慢慢展開。
組件名:
Vue.component(‘my-component-name’,{}).這個形式的組件名應該是大家見過的最多的,也是最熟悉的。
組件名的兩種寫法:
使用 kebab-case短橫線分隔命名:
當使用這種命名方式,也必須用這種命名方式來引用
<my-component-name>
使用 PascalCase首字母大寫:
也叫做帕斯卡命名法,重在首字母大寫。
<my-component-name> 和 <MyComponentName>
都是可接受的。
註冊方式
全局註冊
Vue.component('my-component-name', {
// ... 選項 ...
})
局部註冊
- js對象中定義組件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
- 然後再component選項中定義你要使用的組件
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
局部註冊的組件在其子組件中不可用
模塊系統中局部註冊
在一個假設的 ComponentB.js 或 ComponentB.vue 文件中:
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
現在 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用了。
Prop
傳遞靜態或動態 Prop
props: {
title: String,//傳入字符串
likes: Number,//傳入數字
isPublished: Boolean,//傳入布爾值
commentIds: Array,//傳入數組
author: Object,//傳入一個對象
callback: Function,//傳入一個方法
contactsPromise: Promise // or any other constructor
}
傳入一個對象的所有property
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
等價於
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"></blog-post>
單向數據流的特點,儘可能使父組件和子組件的耦合性降低。
非父子組件通信的幾種方法:
中央事件bus總線法
var bus =new Vue();
Vue.component('component-a',{
template:'<button @click="handleEvent">傳遞事件</button>',
methods:{
handleEvent:function(){
bus.$emit('on-message','來自組件component-a的內容');
}
}
});
var app =new Vue(){
el:'#app',
data:{
message:'',
},
mounted:function(){
var _this=this;
bus.$on('on-message',function(msg){
_this.message=msg;
});
}
首先創建了一個名爲bus 的空Vue實例,全局語法定義了組件component-a,之後創建了Vue實例app,在app初始化時,即生命週期mounted鉤子函數監聽到了來自bus的事件on-message,在組件component-a,點擊按鈕會通過bus把事件on-message發出去,此時app就會接收到來自bus 的事件,進而在回調裏完成業務邏輯。
上面的說法沒什麼毛病就是太複雜了。
簡單分爲幾個模塊和步驟來講的話:
- 1.首先要有一個bus的中間件
- 2.在兩個需要通信的非父子組件的組件中引入這個中間件
- 3.想要發送數據的組件通過vue的實例方法
$emit
發送事件名稱和需要傳遞的數據,以上例子是掛載到mounted方法上。 - 4.被傳遞數據的組件,也就是本處的app實例,通過vue 實例方法
$on
監聽到事件和接收數據。
清除bus:
beforeDestory(){
bus.$off('on-message');
}
父鏈訪問
在子組件中,使用this.$parent可以直接訪問該組件的父實例或者組件,父組件也可以通過this.children訪問它的所有子組件,而且可以遞歸向上或者向下無限訪問。直到沒有父組件或子組件。
但通過這種方式將大大地增加父子組件的耦合性,所以不建議使用。
子組件索引
子組件較多的情況,通過以上父鏈子鏈的形式已經很難找出我們需要的組件實例。
則可以在子組件的標籤上用ref指定一個名稱,comA,在父組件內通過this.$refs.comA來找到組件
<div id="app">
<button @click="handleRef">通過ref獲取子組件實例</button>
<component-a ref="comA"></component-a>
Vue.component('component-a',{
template:'<div>子組件</div>',
data:function(){
return{
message:'子組件內容'
}
}
});
var app=new Vue({
el:'#app',
methods:{
handleRef:function(){
var msg=this.$refs.comA.message;
console.log(msg);
}
}
}
)
插槽slot
爲什麼需要插槽?vue的實用和流行的核心便是組件化,但是共用並不能代替很多需求的完善,可能需要對組件進行自定義,這就出現了插槽。
簡單來講:
假設有一個名爲comA的組件
<comA></comA>
此時組件經過渲染顯示的是今天的天氣是,此時你可能會想加入下雨,下雪等個性化定製的內容,但是直接在標籤中寫是沒有作用的。
如圖所示,slot就好像是那個異色的對話框出口,讓同色的語句也能在背景展示出來。
<comA><slot></slot></comA>
提供一個slot出口則可以正確的顯示。