Vue父子組件的通信

父子組件通信方式

一 父組件向子組件通過props傳遞數(shù)據(jù)

在組件中,使用選項(xiàng)props來聲明需要從父級接收到的數(shù)據(jù)。
props的值有兩種方式:
方式一:字符串?dāng)?shù)組,數(shù)組中的字符串就是傳遞時的名稱。
方式二:對象,對象可以設(shè)置傳遞時的類型,也可以設(shè)置默認(rèn)值等。

Prop 是你可以在組件上注冊的一些自定義 attribute
當(dāng)一個值傳遞給一個 prop attribute 的時候,它就變成了那個組件實(shí)例的一個 property。

1. props值為數(shù)組時候

為了給博文組件傳遞一個標(biāo)題,我們可以用一個 props 選項(xiàng)將其包含在該組件可接受的 prop列表中:

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

一個組件默認(rèn)可以擁有任意數(shù)量的 prop,任何值都可以傳遞給任何 prop。在上述模板中,你會發(fā)現(xiàn)我們能夠在組件實(shí)例中訪問這個值,就像訪問data中的值一樣。

一個 prop 被注冊之后,你就可以像這樣把數(shù)據(jù)作為一個自定義 attribute 傳遞進(jìn)來,在這里我們直接用k-v對顯示了值,而沒有進(jìn)行v-bind的動態(tài)綁定(下面有介紹):

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

然而在一個典型的應(yīng)用中,你可能在 data 里有一個博文的數(shù)組:

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

并想要為每篇博文渲染一個組件:

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
></blog-post>

如上所示,你會發(fā)現(xiàn)我們可以使用 v-bind 來動態(tài)傳遞 prop。這在我們一開始不清楚要渲染的具體內(nèi)容,比如從一個 API 獲取博文列表的時候,是非常有用的。


2. props值為對象時候

通常我們希望每個 prop 都有指定的值類型。這時,我們可以以對象形式列出 prop,這些 property 的名稱和值分別是 prop 各自的名稱和類型

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

3. 關(guān)于props值為對象時候,我們可以對傳入的數(shù)據(jù)做校驗(yàn)或者說驗(yàn)證

我們可以為組件的 prop 指定驗(yàn)證要求,例如你知道的這些類型。如果有一個需求沒有被滿足,則 Vue 會在瀏覽器控制臺中警告你。這在開發(fā)一個會被別人用到的組件時尤其有幫助。

3.1.在props中我們可以傳一個值做一個對象元素傳入,對其做三個限定.如下如代碼中的name
  • type 約定該元素類型
  • default 約定默認(rèn)值(如果父組件不傳入值的話將直接使用默認(rèn)值)
  • required 約定是否要求必須傳入(如果要求了父組件沒有傳入則會報(bào)錯)
props: {
    title:String,
       propB: [String, Number],
    name:{
            type:String,
            default:"zyh",
            required:true
            }
        }
3.2 我們可以對傳入的值約定多個可能類型

propB: [String, Number]

3.如果我們要求傳入的數(shù)據(jù)為對象或者數(shù)組,那么默認(rèn)值需要用工廠函數(shù)獲取

 // 帶有默認(rèn)值的對象
  propE: {
      type: Object,
      // 對象或數(shù)組默認(rèn)值必須從一個工廠函數(shù)獲取
      default: function () {
        return { message: 'hello' }
      }
    }

二 子傳父---通過監(jiān)聽子組件事件傳遞數(shù)據(jù)和信號給父組件

不同于組件和 prop,事件名不存在任何自動化的大小寫轉(zhuǎn)換。而是觸發(fā)的事件名需要完全匹配監(jiān)聽這個事件所用的名稱。
舉個例子,如果觸發(fā)一個 camelCase 名字為的事件:this.$emit('myEvent')
則監(jiān)聽這個名字的 kebab-case 版本是不會有任何效果的:
<my-component v-on:my-event="doSomething"></my-component>
不同于組件和 prop,事件名不會被用作一個 JavaScript 變量名或 property 名,所以就沒有理由使用 camelCase 或 PascalCase 了。

并且v-on 事件監(jiān)聽器在 DOM 模板中會被自動轉(zhuǎn)換為全小寫 (因?yàn)?HTML 是大小寫不敏感的),所以 v-on:myEvent將會變成 v-on:myevent——導(dǎo)致 myEvent不可能被監(jiān)聽到。

因此,Vue官方推薦始終使用 kebab-case 的\color{red}{事件名}。

自定義事件的流程:
  • 在子組件中,通過$emit來觸發(fā)事件。
  • 在父組件中,通過v-on來監(jiān)聽子組件事件。
    一個傳遞加減信號的demo

自定義組件的 v-model

一個組件上的 v-model 默認(rèn)會利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復(fù)選框等類型的輸入控件可能會將 value attribute 用于不同的目的。model 選項(xiàng)可以用來避免這樣的沖突:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

現(xiàn)在在這個組件上使用 v-model 的時候:

<base-checkbox v-model="lovingVue"></base-checkbox>
這里的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當(dāng) <base-checkbox>觸發(fā)一個 change事件并附帶一個新的值的時候,這個 lovingVue 的 property 將會被更新。

注意你仍然需要在組件的 props 選項(xiàng)里聲明 checked 這個 prop。


關(guān)于子組件向父組件傳參數(shù)量問題

$emit傳遞一個參數(shù)時

子組件:
this.$emit('closeChange',false);

父組件:
<posilCom @closeChange="closeCom($event)"></posilCom>
closeCom(msg) {
    this.msg = msg;
}

$emit傳遞多個參數(shù)時

子組件:
this.$emit('closeChange',false,true);
父組件:
<posilCom @closeChange="closeCom(arguments)"></posilCom>
closeCom(msg) {
    this.msg1 = msg[0];
    this.msg2 = msg[1];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容