一頁圖紙看懂Vue組件之間的交互

一頁圖紙,顧名思義真的是一頁圖紙,讓我們來慢慢展開。
在這裏插入圖片描述

組件名:

Vue.component(‘my-component-name’,{}).這個形式的組件名應該是大家見過的最多的,也是最熟悉的。
在這裏插入圖片描述

組件名的兩種寫法:

使用 kebab-case短橫線分隔命名:

當使用這種命名方式,也必須用這種命名方式來引用

<my-component-name>

使用 PascalCase首字母大寫:

也叫做帕斯卡命名法,重在首字母大寫。
<my-component-name> 和 <MyComponentName> 都是可接受的。

註冊方式

全局註冊

Vue.component('my-component-name', {
  // ... 選項 ...
})

局部註冊

  1. js對象中定義組件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
  1. 然後再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出口則可以正確的顯示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章