Vue組件化常用方法之組件傳值與通信
相關(guān)知識點(diǎn)
- 父組件傳值到子組件
- 子組件傳值到父組件
- 兄弟組件之間傳值
- 祖代和后代之間傳值
- 任意兩個(gè)組件之間傳值
父組件傳值到子組件
父組件傳值到子組件基本方法有三個(gè),分別為:
- 屬性 props
- 引用 $refs
- 子元素 $children
日常開發(fā)中,我們用到 props 和 $refs 頻率比較多,$children 相對較少些(我就沒怎么使用過~)。
屬性 props
在父組件中添加屬性,在子組件中接收使用,例如:
父組件:
<HelloWorld msg="Welcome to Your Vue.js App" />
子組件:
<h1>{{ msg }}</h1> props: { msg: String }
引用 $refs
在父組件中可以使用 this.$refs.xxx 獲取子組件中定義的數(shù)據(jù)或者方法,并使用。
父組件:
<HelloWorld ref="hw" /> mounted() { this.$refs.hw.foo = "bar"; }
子組件:
<p>{{ foo }}</p> data() { return { foo: "foo" }; }
注意事項(xiàng):
this.$refs.xxx 不能在 created 生命周期中使用,因?yàn)檎鎸?shí)的 DOM 還沒有掛載完畢,如果非要想,可以使用 vm.$nextTick 來訪問 DOM?;蛘咭部梢赃@樣理解,父組件先于子組件創(chuàng)建,在父組件的 created 生命周期中子組件還沒有創(chuàng)建,所以獲取不到子組件。
在 Vue 中組件生命周期調(diào)用順序如下:
組建的調(diào)用順序都是 先父后子,渲染完成的順序是 先子后父
組件的銷毀操作是 先父后子,銷毀完成的順序是 先子后父
加載渲染過程
- 父 beforeCreate
- 父 created
- 父 beforeMount
- 子 beforeCreate
- 子 created
- 子 beforeMount
- 子 mounted
- 父 mounted
子組件更新過程
- 父 beforeUpdate
- 子 beforeUpdate
- 子 updated
- 父 updated
父組件更新過程
- 父 beforeUpdate
- 父 updated
銷毀過程
- 父 beforeDestroy
- 子 beforeDestroy
- 子 destroyed
- 父 destroyed
created() { console.log("第一個(gè)執(zhí)行"); console.log(this.$refs.hw); // undefined this.$nextTick(() => { console.log("第三個(gè)執(zhí)行"); console.log(this.$refs.hw); // 此時(shí)可以獲取到 }); } mounted() { console.log("第二個(gè)執(zhí)行"); this.$refs.hw.foo = "bar"; }
子元素 $children
父組件:
this.$children[0].xx = "xxx";
注意事項(xiàng):
$children 獲取當(dāng)前實(shí)例的直接子組件。如果父組件中存在多個(gè)子組件,需要注意 $children 并不保證順序,也不是響應(yīng)式的。
子組件傳值到父組件
子組件傳值到父組件使用的方法是自定義事件。在子組件中派發(fā),在父組件中監(jiān)聽。
注意事項(xiàng): 事件的派發(fā)者是誰,事件的監(jiān)聽者就是誰,只不過聲明的時(shí)候聲明在父組件中了。
分為三種情況:不傳遞參數(shù)、傳遞一個(gè)參數(shù)、傳遞多個(gè)參數(shù)。
不傳遞參數(shù)
子組件:
this.$emit('childFoo');
父組件:
<HelloWorld2 @childFoo="onChildFoo"></HelloWorld2> methods: { onChildFoo() { console.log("====== onChildFoo ========"); } }
傳遞一個(gè)參數(shù)
在父組件中使用 $event 接收參數(shù)。
子組件:
this.$emit('childFooSingle', 'foo');
父組件:
<HelloWorld2 @childFooSingle="onChildFooSingle($event)"></HelloWorld2> methods: { onChildFooSingle(e) { console.log(e); // foo } }
傳遞多個(gè)參數(shù)
在父組件中使用 arguments 接收參數(shù),會以數(shù)組的形式傳遞。
子組件:
this.$emit('childFooMultiple', 'foo', 'bar', 'dong');
父組件:
<HelloWorld2 @childFooSingle="onChildFooMultiple(arguments)"></HelloWorld2> methods: { onChildFooMultiple(msg) { console.log(msg[0]); // foo console.log(msg[1]); // bar console.log(msg[2]); // dong } }
兄弟組件之間傳值
兄弟組件之間傳值可以通過共同的父輩組件搭橋進(jìn)行傳遞,例如:$parent、$root。
兄弟組件1:
this.$parent.$on('foo', handle);
兄弟組件2:
this.$parent.$emit('foo');
祖代和后代之間傳值
由于組件嵌套層數(shù)過多,使用 props 進(jìn)行傳遞不切實(shí)際,vue 提供了 provide/inject API 完成該任務(wù)。
provide/inject 能夠?qū)崿F(xiàn)祖先給后代傳值。
祖代:
provide() { return {foo: 'foo'} }
后代:
inject: ['foo']
注意:provide 和 inject 主要為高階組件/組件庫提供用例,并不推薦直接用于應(yīng)用程序代碼中,我們更多會在開源組件庫中見到。但是,反過來想要后代給祖代傳值,這種方案就不行了?。?!
官方提示:provide 和 inject 綁定并不是響應(yīng)式的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽的對象,那么其對象的 property 還是可響應(yīng)式的。
祖代:
provide() { return { dong: this.home }; }, data() { return { home: ["App home"] }; }
后代:
inject: ["dong"] this.dong = ["App data"]; // 會報(bào)錯(cuò),Avoid mutating an injected value directly since the changes will be overwritten whenever the provided component re-renders this.dong.push("App data"); // 可以修改成功
任意兩個(gè)組件之間傳值
任意兩個(gè)組件之間傳值有兩種方案:事件總線、Vuex。
事件總線
創(chuàng)建一個(gè) Bus 類負(fù)責(zé)事件派發(fā)、監(jiān)聽和回調(diào)管理。
首先創(chuàng)建一個(gè) bus.js,并在 main.js 中引入,然后在組件中使用:
第一步:新建 plugins/bus.js
class Bus{ constructor(){ this.callbacks = {} } $on(name, fn){ this.callbacks[name] = this.callbacks[name] || [] this.callbacks[name].push(fn) } $emit(name, args){ if(this.callbacks[name]){ this.callbacks[name].forEach(cb => cb(args)) } } } export default Bus;
第二步:main.js 中引入
import Bus from "./plugins/bus"; Vue.prototype.$bus = new Bus()
第三步:在組件中使用
組件1:
this.$bus.$on('foo', handle)
組件2:
this.$bus.$emit('foo')
Vuex
創(chuàng)建唯一的全局?jǐn)?shù)據(jù)管理者 store,通過它管理數(shù)據(jù)并通知組件狀態(tài)變更??梢宰孕邢攘私庖幌鹿俜轿臋nVuex,具體詳細(xì)使用后續(xù)會寫一個(gè)專題~
總結(jié)
到此這篇關(guān)于Vue組件化常用方法之組件傳值與通信的文章就介紹到這了,更多相關(guān)Vue組件傳值與通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解從新建vue項(xiàng)目到引入組件Element的方法
本篇文章主要介紹了詳解從新建vue項(xiàng)目到引入組件Element的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08Vue導(dǎo)出el-table表格為Excel文件的兩種方式
在開發(fā)過程中,我們經(jīng)常需要將表格數(shù)據(jù)導(dǎo)出為 Excel 文件,大多數(shù)情況下,由后端處理即可,但是當(dāng)數(shù)據(jù)量不大、需要快速響應(yīng)用戶操作、或者數(shù)據(jù)已經(jīng)在前端進(jìn)行處理和展示時(shí),前端該如何實(shí)現(xiàn)呢,本文將介紹兩種方法,需要的朋友可以參考下2024-09-09vue3中el-table實(shí)現(xiàn)表格合計(jì)行的示例代碼
這篇文章主要介紹了vue3中el-table實(shí)現(xiàn)表格合計(jì)行,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01vue3實(shí)現(xiàn)圖片縮放拖拽功能的示例代碼
v3-drag-zoom 是基于 vue3 開發(fā)的一個(gè)縮放拖拽組件,方便開發(fā)者快速實(shí)現(xiàn)縮放拖拽功能,效果類似地圖的縮放與拖拽,本文給大家介紹了vue3如何快速實(shí)現(xiàn)圖片縮放拖拽功能,感興趣的朋友可以參考下2024-04-04