vue組件之間數(shù)據(jù)傳遞和通信方式總結(jié)

方式主要包括
  1. ==父組件=>子組件 | 單向數(shù)據(jù)流涧尿,props==
  2. ==子組件=>父組件 | 觀(guān)察者模式翁涤,即vue的自定義事件 emit 和on==
  3. ==非父子組件通信 | 中介者模式,即 中央事件總線(xiàn) bus==
  4. ==父子組件通信 | 父鏈和子鏈==
  5. vuex 等狀態(tài)管理庫(kù)(略)

1 父組件=>子組件扔涧,props的兩個(gè)主要用法

  • 子組件把 props 的值枯夜,作為初始值(data中)保存起來(lái)湖雹,從而和父級(jí)解綁
  • 子組件需要二次處理 props 值,這時(shí),應(yīng)將其作為【計(jì)算屬性】保存起來(lái)

將prop用于子組件的data

  • 定義一個(gè)本地的 data 屬性并將這個(gè) prop 用作其初始值
props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}
  • 用 prop 的值來(lái)定義一個(gè)計(jì)算屬性
props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

prop 是單向數(shù)據(jù)流

  • 所有的 prop 都使得其父子 prop 之間形成了一個(gè)==單向下行綁定==
    父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中,但是反過(guò)來(lái)則不行
  • ==不要在子組件中改變 prop==

props傳值:父組件=>子組件

//靜態(tài)傳值
<blog-post name="zhangkai"></blog-post>
//動(dòng)態(tài)傳值
<blog-post :name="zhangkai"></blog-post>
<blog-post :num="42"></blog-post>
<blog-post :ifSale="false"></blog-post>
<blog-post :list="[1,2,3]"></blog-post>
<blog-post :person="{name:'zhangkai',age:19}"></blog-post>
<blog-post :person="person.name"></blog-post>
//不帶參數(shù)的 v-bind,post={id:1,title:"title"}
<blog-post v-bind="post"></blog-post>
//等價(jià)于
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

prop檢驗(yàn)

詳細(xì)章節(jié)見(jiàn)

  • <a >vue prop傳值default屬性如何使用</a>
  • <a >vue prop傳值類(lèi)型檢驗(yàn)</a>

2 子組件=>父組件

  • 原理:【觀(guān)察者模式】 + 【vue自定義事件】
  • 子組件用 $emit 方法觸發(fā)事件楞遏,第一個(gè)參數(shù)是自定義事件名勒奇,后續(xù)參數(shù)都是要傳遞的數(shù)據(jù)
  • 父組件用 v-on 定義的方法監(jiān)聽(tīng)子組件的事件
  • 注意劈彪,add 和 reduce 是兩個(gè)自定義事件痘括,用來(lái)監(jiān)聽(tīng)子組件的 $emit 事件
//vue模板
<template>
  <div class="wrap">
    <!--注意屠凶,add 和 reduce 是兩個(gè)自定義事件,用來(lái)監(jiān)聽(tīng)子組件的 $emit 事件-->
    <MyComponent v-on:add="handleTotal" v-on:reduce="handleTotal"/>
    {{total}}
  </div>
</template>
//vue script
var MyComponent = {
  template:
    "<div>\
    <button @click='handleAdd'>+1</button>\
    <button @click='handleReduce'>-1</button>\
    </div>",
  data() {
    return {
      sum: 0
    };
  },
  methods: {
    handleAdd() {
      this.sum++;
      this.$emit("add", this.sum);
    },
    handleReduce() {
      this.sum--;
      this.$emit("reduce", this.sum);
    }
  }
};
export default {
  components: {
    MyComponent
  },
  data() {
    return {
      total: 0
    };
  },
  methods: {
    handleTotal(total) {
      this.total = total;
    }
  }
};

3 非父子組件通信 bus

  • 使用【中央事件總線(xiàn) bus】
  • bus 其實(shí)就是一個(gè)空的Vue實(shí)例,充當(dāng)中介者的作用
  • bus 通過(guò) emit 發(fā)出信息,通過(guò)on 來(lái)監(jiān)聽(tīng)獲取,這兩個(gè)方法的第一個(gè)參數(shù)必需是同一個(gè)消息名稱(chēng)
  • bus 對(duì)象中,可以添加 data、methods呵晚、computed 等信息
  • 協(xié)同開(kāi)發(fā)中劣纲,向 bus 對(duì)象添加一些共享的信息,是非常有用的
  • 比如劫瞳,token、用戶(hù)昵稱(chēng)伺绽、郵箱信息等,只需初始化時(shí)讓 bus獲取一次,所有組件就都可以使用了
 //vue模板
<template>
  <div class="wrap">
    <componentA/>
    <br>
    {{msg}}
  </div>
</template>
<script>
//vue script
import Vue from "vue";
const bus = new Vue({
  data: {
    name: "",
    passport: ""
  }
}); //一個(gè)空的Vue實(shí)例歌殃,做為【中央事件總線(xiàn)】
const componentA = {
  template: "<button @click='handleEvent'>傳遞事件</button>",
  methods: {
    handleEvent() {
      bus.name = "gs";
      bus.$emit("on-msg", "componentA content");
    }
  }
};
export default {
  components: {
    componentA
  },
  data() {
    return {
      msg: ""
    };
  },
  mounted() {
    const that = this;
    bus.$on("on-msg", msg => {
      console.log(bus.name);
      that.msg = msg;
    });
  }
};

4 父子組件通信 父鏈和子鏈

  • 在子組件中,this.$parent 可以訪(fǎng)問(wèn)父組件實(shí)例
  • 在父組件中朵你,this.children 可以訪(fǎng)問(wèn)子組件實(shí)例
  • 該方法可以向上向上無(wú)限遞歸抡医,直到遇見(jiàn)根組件和葉子組件
  • 給子組件添加一個(gè) ref 屬性,可以幫助父組件快速找到子組件(調(diào)用方法 this.$refs.comA.msg,實(shí)際上 react 也有這樣的方法)宙刘,但不建議使用 ref
  • 注意衙猪,在 mounted階段時(shí) this.$refs 才會(huì)綁定茫船,在 created 階段尚未綁定
  • 另外,$refs 不是一個(gè)響性式的屬性
//注意高每,this.$children 一般為數(shù)組
this.$children[0].age
//使用 ref 屬性,可以更容易找到子組件
//<componentA ref="ageCom"/>
this.$refs.ageCom.age;
注意事項(xiàng):

不要在子組件中修改 props 的值

  • props 是對(duì)象或數(shù)組時(shí)带欢,由于是引用類(lèi)型逗宜,在子組件中修改,會(huì)影響到父組件

重要空骚!Prop 的大小寫(xiě) (camelCase vs kebab-case)

  • 聲明一個(gè)vue組件纺讲,如果使用駝峰命名法,在使用時(shí)府怯,需要轉(zhuǎn)換成短橫線(xiàn)分隔命名
  • 因?yàn)槿绻晦D(zhuǎn)刻诊,html解析時(shí),會(huì)將大寫(xiě)字母小寫(xiě)化牺丙,這樣變量即為undefined
  • 如下则涯,props 一般是一個(gè)數(shù)組,也可以是一個(gè)對(duì)象(對(duì)象類(lèi)型檢測(cè))
//聲明一個(gè)組件
Vue.component('blog-post', {
  // 在 JavaScript 中是 camelCase 的
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
//使用組件
<blog-post post-title="hello!"></blog-post>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冲簿,一起剝皮案震驚了整個(gè)濱河市粟判,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峦剔,老刑警劉巖档礁,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異吝沫,居然都是意外死亡呻澜,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)惨险,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)羹幸,“玉大人,你說(shuō)我怎么就攤上這事辫愉≌な埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵恭朗,是天一觀(guān)的道長(zhǎng)屏镊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)痰腮,這世上最難降的妖魔是什么而芥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮膀值,結(jié)果婚禮上棍丐,老公的妹妹穿的比我還像新娘弟翘。我一直安慰自己,他們只是感情好骄酗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著悦冀,像睡著了一般趋翻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盒蟆,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天踏烙,我揣著相機(jī)與錄音,去河邊找鬼历等。 笑死讨惩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寒屯。 我是一名探鬼主播荐捻,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寡夹!你這毒婦竟也來(lái)了处面?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤菩掏,失蹤者是張志新(化名)和其女友劉穎魂角,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體智绸,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡野揪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年瞧栗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沼溜。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖系草,靈堂內(nèi)的尸體忽然破棺而出通熄,到底是詐尸還是另有隱情,我是刑警寧澤找都,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站能耻,受9級(jí)特大地震影響亡驰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饿幅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一凡辱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栗恩,春花似錦透乾、人聲如沸磕秤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蒙兰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間癞己,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工仰担, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摔蓝。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓愉耙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親朴沿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351