vue實(shí)現(xiàn)組件通信的八種方法實(shí)例
對(duì)于vue來(lái)說(shuō),組件之間的消息傳遞是非常重要的,下面是我對(duì)組件之間消息傳遞的常用方式的總結(jié)
1、props 父組件--->子組件通信
父組件---屬性的方式傳值給子組件
子組件---props方式接收數(shù)據(jù)
<Son :datas="fData"></Son> <script> import Son from '@/components/son' export default{ name:'Father', components:{Son}, data(){ return{ fData:'我是父組件向子組件傳遞的值-props方式' } } } </script>
子組件props接受的參數(shù)名稱,要與父組件傳遞時(shí)定義的屬性名一致
<template> <div>我是父組件的數(shù)據(jù):{{fData}}</div> <div @click=changeData>我是父組件傳遞修改后的數(shù)據(jù):{{mydata}}</div> </template> <script> export default{ name:'Son', props:{ fData:{ type:String, default:'' } } data(){ mydata:this.fatherData }, methods:{ changeData(){ this.mydata += '改變數(shù)據(jù)' } }, } </script>
注意:
- 子組件不能夠直接去修改父組件傳遞的值修改的:因?yàn)閂ue的單向數(shù)據(jù)流機(jī)制,如果直接修改那父組件的值就被“污染”了。(props是單向綁定的(只讀屬性):當(dāng)父組件的屬性變化時(shí),將傳導(dǎo)給子組件,但是反過(guò)來(lái)不會(huì))
報(bào)錯(cuò)信息大概是:vue使用prop通信出錯(cuò):Avoid mutating a prop directly since the value will be overwritten whenever the parent - 解決方案:可以在子組件內(nèi)定義一個(gè)變量mydata去接收f(shuō)Data數(shù)據(jù)
- 參數(shù)傳遞類型不確定是可以這么寫:
props:{ fData:{ type:[String,Number], default:'' } }
2、$emit 子組件--->父組件傳遞
- 子組件綁定自定義事件
- $emit()第一個(gè)參數(shù)為:自定義的事件名稱,第二個(gè)參數(shù)為:需要傳遞的數(shù)據(jù)
- 使用 $emit() 觸發(fā)更改數(shù)據(jù)
子組件
<el-button @click="handleEmit">改變父組件</el-button> <script> export default{ name:'Son', methods:{ handleEmit(){ this.$emit('triggerEmit','子組件的數(shù)據(jù)') } } } </script>
父組件(子組件發(fā)送的事件名稱,要和父組件接受的事件名稱一致)
<Son @triggerEmit="changeData"></Son> <script> import Son from '@/components/son' export default{ name:'Father', components:{Son}, methods:{ changeData(name){ console.log(name) // => 我是來(lái)自子組件的數(shù)據(jù) } } } </script>
$emit與props結(jié)合 兄弟組件傳值
- 父組件引入兩個(gè)子組件
- 父組件充當(dāng)一個(gè)橋梁作用
父組件
<childA :myName="name"></ChildA> <ChildB :myName="name" @changeName="editName"></ChildB> export default{ data() { return { name: '數(shù)據(jù)你好' } }, methods: { editName(name){ this.name = name } } }
子組件B改變,接收數(shù)據(jù)
<p>姓名:{{ myName }}</p>
<button @click="changeName">修改姓名</button> <script> export default{ props: { myName:String }, methods: { changeName() { this.$emit('changeName', '新數(shù)據(jù)名稱') } } } </script>
子組件A接收數(shù)據(jù)
<p>姓名:{{ newName }}</p> <script> export default{ props: { myName:String } } </script>
3、bus(事件總線) 兄弟組件通信
非父子組件或更多層級(jí)間組件間傳值,在Vue中通過(guò)單獨(dú)的事件中心來(lái)管理組件間的傳值
- 創(chuàng)建一個(gè)公共的bus.js文件
- 暴露出Vue實(shí)例
- 傳遞數(shù)據(jù)方,通過(guò)一個(gè)事件觸發(fā)bus.$emit(方法名,傳遞的數(shù)據(jù))
- 接收數(shù)據(jù)方,在生命周期函數(shù)中,通過(guò)bus.$on(方法名,[params])來(lái)監(jiān)聽
- 銷毀事件,在接受數(shù)據(jù)方,通過(guò)bus.$off(方法名)銷毀之后無(wú)法監(jiān)聽數(shù)據(jù)
import Vue from "vue" const bus=new Vue() export default bus
需要改變數(shù)據(jù)的組件中定義調(diào)用
<template> <div> <div>我是通信組件A</div> <button @click="changeName">修改姓名</button> </div> </template> <script> import bus from "@/utils/Bus.js"; export default { components: {}, data() { return {}; }, mounted() { console.log(bus); }, methods: { changeName() { bus.$emit("editName", "數(shù)據(jù)集!"); }, }, }; </script> <style lang='scss' scoped> </style>
另外一個(gè)組件中同樣引入bus.js文件,通過(guò)$on監(jiān)聽事件回調(diào)
<template> <div> <span>名稱:{{name}}</span> <div>我是通信組件B</div> </div> </template> <script> import bus from "@/utils/Bus.js"; export default { components: {}, data() { return {name}; }, mounted() { bus.$on("editName", (name) => { this.name=name console.log(name); // }); }, methods: {}, }; </script> <style lang='scss' scoped> </style>
4、$parent、$children 直接訪問(wèn)組件實(shí)例
- 子組件通過(guò)---> $parent 獲得父組件實(shí)例
- 父組件通過(guò)---> $children 獲得子組件實(shí)例數(shù)組
子組件---this.$parent可以獲取到父組件的方法、data的數(shù)據(jù)等,并可以直接使用和執(zhí)行
<template> <div>我是子組件</div> </template> <script> export default{ name:"Son", data(){ return{ sonTitle: '我是子組件的數(shù)據(jù)' } }, methods:{ sonHandle(){ console.log('我是子組件的方法') } }, created(){ console.log(this.$parent) console.log(this.$parent.fatherTitle) // => 我是父組件的數(shù)據(jù) this.$parent.fantherHandle() // => 我是父組件的方法 } } </script>
父組件 --- 獲取子組件實(shí)例的,并且獲取的實(shí)例是一個(gè)數(shù)組形式,this.$children[0]才可以獲取某個(gè)組件實(shí)例,并調(diào)用組件方法和數(shù)據(jù)
<template> <div> <Son>我是父組件</Son> </div> </template> <script> import Son from './son.vue' export default{ name: 'father', components:{ Son }, data(){ return{ fatherTitle: '我是父組件的數(shù)據(jù)' } }, methods:{ fantherHandle(){ console.log('我是父組件的方法') } }, mounted(){ console.log(this.$children) console.log(this.$children[0].sonTitle) // => 我是子組件的數(shù)據(jù) this.$children[0].sonHandle() // => 我是子組件的方法 } } </script>
5、$refs
ref被用來(lái)給元素或子組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)在父組件的 $refs 對(duì)象上。
父組件使用 $refs 獲得組件實(shí)例
<template> <div> <Son ref="son"></Son> </div> </template> <script> import Son from './son.vue' export default{ name: 'father', components:{ Son }, mounted(){ console.log(this.$refs.son) /*組件實(shí)例*/ } } </script>
6、provide/inject(提供/注入) 多組件或深層次組件通信
- 父組件使用 provide 注入數(shù)據(jù)
- 子組件使用 inject 使用數(shù)據(jù)
/*父組件*/ export default{ provide: { return{ provideName: '販賣前端仔' } } }
至此provideName這個(gè)變量可以提供給它其下的所有子組件,包括曾孫、孫子組件等,只需要使用 inject 就能獲取數(shù)據(jù)
/*子組件*/ export default{ inject: ['provideName'], created () { console.log(this.provideName) // => "販賣前端仔" } }
- 父組件不需要知道哪個(gè)組件使用它提供出去的數(shù)據(jù)
- 子附件不需要知道這個(gè)數(shù)據(jù)從哪里來(lái)
7、slot(slot-scope作用域插槽) 子元素-->父元素(類似于通信)
- 用作一個(gè) (能被傳遞數(shù)據(jù)的)可重用模板,來(lái)代替已經(jīng)渲染好的元素
- 在子組件中,只需將數(shù)據(jù)傳遞到插槽,就像你將 prop 傳遞給組件一樣
- 注意:父級(jí)插槽接收內(nèi)容是最外側(cè)元素 ,必須要有屬性slot-scope
子元素
<template> <div> <div class="isSon"> <slot :info='arrList'></slot> </div> </div> </template> <script> export default { components: {}, data() { return {arrList:[1,'aa','張三']}; }, mounted() { }, methods: { }, }; </script>
父元素
<template> <div> <SonG> <span slot-scope="props"> <ul> aa <li v-for="item in props.info" :key="item"> {{item}} </li> </ul> </span> </SonG> </div> </template> <script> import SonG from '../components/SonG.vue' export default { components:{ SonG }, data () { return { } } } </script>
8、vuex狀態(tài)管理
相當(dāng)于一個(gè)公共數(shù)據(jù)的倉(cāng)庫(kù)
提供一些方法管理倉(cāng)庫(kù)數(shù)據(jù)
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { } })
總結(jié)
到此這篇關(guān)于vue實(shí)現(xiàn)組件通信的八種方法的文章就介紹到這了,更多相關(guān)vue實(shí)現(xiàn)組件通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue跳轉(zhuǎn)同一個(gè)路由參數(shù)不同的問(wèn)題
這篇文章主要介紹了vue跳轉(zhuǎn)同一個(gè)路由參數(shù)不同的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Vue2+Elementui?Dialog實(shí)現(xiàn)封裝自定義彈窗組件
在日常的管理系統(tǒng)界面中,我們寫的最多的除了列表表格之外,就是各種彈窗組件,本文就來(lái)為大家詳細(xì)介紹一下Vue2如何結(jié)合Elementui?Dialog實(shí)現(xiàn)封裝自定義彈窗組件,希望對(duì)大家有所幫助2023-12-12Vue3中使用styled-components的實(shí)現(xiàn)
本文主要介紹了Vue3中使用styled-components的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05vue 內(nèi)置過(guò)濾器的使用總結(jié)(附加自定義過(guò)濾器)
這篇文章主要介紹了vue 內(nèi)置過(guò)濾器的使用總結(jié)(附加自定義過(guò)濾器),詳細(xì)的介紹了各種過(guò)濾器的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12vue3父子組件通信、兄弟組件實(shí)時(shí)通信方式
這篇文章主要介紹了vue3父子組件通信、兄弟組件實(shí)時(shí)通信方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06vue項(xiàng)目是如何運(yùn)行起來(lái)的
這篇文章主要介紹了vue項(xiàng)目是如何運(yùn)行起來(lái)的,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09