
VUE組件之間通信的方式有哪些(SSS)

常見使用場景可以分為三類:
-
父子通信:
- null
父向子傳遞資料是通過props,子向父是通過$emit / $on $emit / $busVuex- 通過父鏈 / 子鏈也可以通信(
$parent/$children) ref也可以訪問組件實體
- null
-
兄弟通信:
$emit / $busVuex
-
跨級通信:
$emit / $bus;Vuex;provide / inject API$attrs/$listeners
$emit / $bus
// main.js
Vue.prototype.$bus = new Vue() // event Bus 用于無關系組件間的通信,
A觸發B
// A
this.$bus.$emit('new-messsage-at-me', {
data: { conversationID: message.conversationID }
})
// B
mounted() {
this.$bus.$on('new-messsage-at-me', event => {
if (
event.data.conversationID === this.conversation.conversationID &&
this.conversation.conversationID !==
this.currentConversation.conversationID
) {
this.hasMessageAtMe = true
}
})
},
父子組件通信
- 父組件向子組件傳值( props ):
//App.vue父組件
<template>
<div id="app">
<users v-bind:users="users"></users>//前者自定義名稱便于子組件呼叫,后者要傳遞資料名
</div>
</template>
<script>
import Users from "./components/Users"
export default {
name: 'App',
data(){
return{
users:["Henry","Bucky","Emily"]
}
},
components:{
"users":Users
}
}
//users子組件
// 注:組件中的資料共有三種形式:data、props、computed
<template>
<div >
<ul>
<li v-for="user in users">{{user}}</li>//遍歷傳遞過來的值,然后呈現到頁面
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props:{
users:{ //這個就是父組件中子標簽自定義名字
type:Array,
required:true
}
}
}
</script>
- 子組件向父組件傳值(B 組件中 $emit, A 組件中 v-on ):
// 子組件
<template>
<header>
<h1 @click="changeTitle">{{title}}</h1>//系結一個點擊事件
</header>
</template>
<script>
export default {
name: 'app-header',
data() {
return {
title:"Vue.js Demo"
}
},
methods:{
changeTitle() {
this.$emit("titleChanged","子向父組件傳值");//自定義事件 傳遞值“子向父組件傳值”
}
}
}
</script>
// 父組件
<template>
<div id="app">
<app-header v-on:titleChanged="updateTitle" ></app-header>//與子組件titleChanged自定義事件保持一致
// updateTitle($event)接受傳遞過來的文字
<h2>{{title}}</h2>
</div>
</template>
<script>
import Header from "./components/Header"
export default {
name: 'App',
data(){
return{
title:"傳遞的是一個值"
}
},
methods:{
updateTitle(e){ //宣告這個函式
this.title = e;
}
},
components:{
"app-header":Header,
}
}
</script>
$ref 與 $parent $children
- 使用 this.$parent查找當前組件的父組件,
- 使用 this.$children查找當前組件的直接子組件,可以遍歷全部子組件, 需要注意 $children 并不保證順序,也不是回應式的,
- 使用 this.$root查找根組件,并可以配合$children遍歷全部組件,
- 使用 this.$refs查找命名子組件( )( this.$refs.one )
$attrs / $listeners
- 兩者的出現使得組件之間跨組件的通信在不依賴 vuex 和事件總線的情況下變得簡潔,業務清晰,
- A->B->C 多級組件嵌套需要傳遞資料時,通常使用的方法是通過vuex,如果僅僅是傳遞資料,而不做中間處理,使用 vuex 處理,未免有點殺雞用牛刀,Vue 2.4 版本提供了另一種方法,使用 v-bind=”$attrs”, 將父組件中不被認為 props特性系結的屬性傳入子組件中,通常配合 interitAttrs 選項一起使用,
- 簡單來說:$attrs 與 $listeners 是兩個「物件」,$attrs 里存放的是父組件中系結的非 Props 屬性, 唯一缺點 沒在props定義的屬性 會顯示在生成的html標簽上, 解決辦法:通過inheritAttrs:false,避免頂層容器繼承屬性; $listeners里存放的是父組件中系結的非原生事件,
A父組件
<template>
<div>
<child-dom
:foo="foo"
:coo="coo"
v-on:upRocket="reciveRocket"
>
</child-dom>
</div>
</template>
<script>
import childDom from "@/components/ChildDom.vue";
export default {
name:'demoNo',
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
components:{childDom},
methods:{
reciveRocket(){
console.log("reciveRocket success")
}
}
}
</script>
B子組件
<template>
<div>
<p>foo:{{foo}}</p>
<p>attrs:{{$attrs}}</p>
<childDomChild v-bind="$attrs" v-on="$listeners"></childDomChild>
</div>
</template>
<script>
import childDomChild from './childDomChild';
export default {
name:'child-dom'
props:["foo"],
inheritAttrs:false,
}
</script>
C子組件的子組件
<template>
<div>
<p>coo:{{coo}}</p>
<button @click="startUpRocket">我要發射火箭</button>
</div>
</template>
<script>
export default {
name:'childDomChild',
props:['coo'],
methods:{
startUpRocket(){
this.$emit("upRocket");
console.log("startUpRocket")
}
}
}
</script>
provide / inject
- 適用于 隔代組件通信 祖先組件中通過 provider 來提供變數,然后在子孫組件中通過 inject 來注入變數, provide / inject API 主要解決了跨級組件間的通信問題,不過它的使用場景,主要是子組件獲取上級組件的狀態,跨級組件間建立了一種主動提供與依賴注入的關系,
- 如果是單一的只是拿資料使用,在父組件定義,則在所有子組件都能為之所用
- 官網不建議在應用中直接使用該辦法,理由很直接:他怕你"管不好"
1.一般情況使用都是在app.vue配置為:
provide () {
return {
isTest: this
}
},
2.所有子組件都可以參考 拿到app.vue里面的所有資料
inject: ['isTest'],
歡迎留言~~~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/14860.html
標籤:JavaScript
