海南省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站首頁(yè)排名前50名免費(fèi)的網(wǎng)站
目錄
- 1、組件的自定義事件
- 1.1 綁定自定義事件:
- 1.1.1 第一種方式
- 1.1.2 第二種方式
- 1.1.3 自定義事件只觸發(fā)一次
- 1.2 解綁自定義事件
- 1.3綁定原生DOM事件
- 1.4 總結(jié)
- 2、全局事件總線(GlobalEventBus)
- 2.1 應(yīng)用全局事件總線
- 3、 消息訂閱與發(fā)布(pubsub)
- 3.1 應(yīng)用消息訂閱與發(fā)布
前言:
組件之間通信的方式有很多種,比如props
、自定義事件
、全局事件總線
、消息訂閱與發(fā)布
、父鏈與子組件索引
、插槽
、Vuex
等都可以實(shí)現(xiàn)組件之間的通信。在這里我將介紹以下三種通信方式。
1、組件的自定義事件
- 它是一種組件間通信的方式,適用于:子組件 ===> 父組件
- 使用場(chǎng)景:A是父組件,B是子組件,B想給A傳數(shù)據(jù),那么就要在A中給B綁定自定義事件(事件的回調(diào)在A中)。
1.1 綁定自定義事件:
1.1.1 第一種方式
- 在父組件中:
<Demo @dome="test"/>
或<Demo v-on:dome="test"/>
- 觸發(fā)自定義事件:
this.$emit('dome',數(shù)據(jù))
代碼示例:
app組件
<template><div><h1 class="title">你好啊</h1><Student @dome="test" /></div>
</template><script>
import Student from "./components/Student";
export default {name: "App",components: { Student },methods: {test() {console.log("我被觸發(fā)了");},},
};
</script><style scoped>
</style>
子組件student
<template><div class="demo"><button @click="domes">點(diǎn)我觸發(fā)</button></div>
</template><script>
export default {name: "Student",methods: {domes() {this.$emit("dome");},},
};
</script><style scoped>
</style>
1.1.2 第二種方式
在父組件中:
<Demo ref="xxx"/>......mounted(){this.$refs.xxx.$on('demo',this.test)}
代碼示例:
app組件
<template><div><h1 class="title">你好啊</h1><!-- <Student @dome.once="test" /> --><Student ref="student" /></div>
</template><script>
import Student from "./components/Student";
export default {name: "App",components: { Student },methods: {test() {console.log("我被調(diào)用了");},},mounted() {this.$refs.student.$on("dome", this.test);},
};
</script><style scoped>
</style>
子組件student
<template><div class="demo"><button @click="domes">點(diǎn)我觸發(fā)</button></div>
</template><script>
export default {name: "Student",methods: {domes() {this.$emit("dome");},},
};
</script><style scoped>
</style>
注意:通過(guò)
this.$refs.xxx.$on('dome',回調(diào))
綁定自定義事件時(shí),回調(diào)要么配置在methods中,要么用箭頭函數(shù),否則this指向會(huì)出問(wèn)題!
代碼示例:
mounted() {this.$refs.student.$on("dome", function() {console.log(this);this指向子組件student將普通函數(shù)換成箭頭函數(shù),this指向就還是原來(lái)的app組件});},
1.1.3 自定義事件只觸發(fā)一次
若想讓自定義事件只能觸發(fā)一次,可以使用once
修飾符,或$once
方法。
代碼示例:
- once修飾符使用方法
代碼示例:
app組件
<template><div><h1 class="title">你好啊</h1><Student @dome.once="test" /><!--綁定自定義事件,一次性 --><!-- <Student ref="student" /> --></div>
</template><script>
import Student from "./components/Student";
export default {name: "App",components: { Student },methods: {test() {console.log("我被調(diào)用了");},},/* mounted() {this.$refs.student.$on("dome", this.test);}, */
};
</script><style scoped>
</style>
- $once使用方法
代碼示例:
app組件
<template><div><h1 class="title">你好啊</h1><!-- <Student @dome.once="test" /> --><Student ref="student" /></div>
</template><script>
import Student from "./components/Student";
export default {name: "App",components: { Student },methods: {test() {console.log("我被調(diào)用了");},},mounted() {this.$refs.student.$once("dome", this.test);//綁定自定義事件(一次性)},
};
</script><style scoped>
</style>
1.2 解綁自定義事件
- 解綁自定義事件通過(guò)
this.$off('atguigu')
代碼示例:
app
組件
<template><div><h1 class="title">你好啊</h1><Student @dome="test" @dome2="test2"/><!-- <Student ref="student" /> --></div>
</template><script>
import Student from "./components/Student";
export default {name: "App",components: { Student },methods: {test() {console.log("我被調(diào)用了");},test2() {console.log("我是第二個(gè)事件");},},/* mounted() {this.$refs.student.$on("dome", this.test);}, */
};
</script><style scoped>
</style>
子student
組件
<template><div class="demo"><button @click="domes">點(diǎn)我觸發(fā)</button><button @click="unbind">點(diǎn)我解綁事件</button></div>
</template><script>
export default {name: "Student",methods: {domes() {this.$emit("dome");this.$emit("dome2");//綁定多個(gè)自定義事件},unbind() {// this.$off("dome")//解綁一個(gè)自定義事件// this.$off(['dome','dome2'])//解綁多個(gè)自定義事件this.$off()//解綁所有的自定義事}},
};
</script><style scoped>
</style>
1.3綁定原生DOM事件
- 組件上也可以綁定原生DOM事件,需要使用
native
修飾符。如果不加上native
修飾符,Vue會(huì)默認(rèn)將此事件當(dāng)作自定義事件。
代碼示例:
<Student @click.native="xxx"/>
1.4 總結(jié)
-
一種組件間通信的方式,適用于:子組件 ===> 父組件
-
使用場(chǎng)景:A是父組件,B是子組件,B想給A傳數(shù)據(jù),那么就要在A中給B綁定自定義事件(事件的回調(diào)在A中)。
-
綁定自定義事件:
-
第一種方式,在父組件中:
<Demo @atguigu="test"/>
或<Demo v-on:atguigu="test"/>
-
第二種方式,在父組件中:
<Demo ref="demo"/> ...... mounted(){this.$refs.xxx.$on('atguigu',this.test) }
-
若想讓自定義事件只能觸發(fā)一次,可以使用
once
修飾符,或$once
方法。
-
-
觸發(fā)自定義事件:
this.$emit('atguigu',數(shù)據(jù))
-
解綁自定義事件
this.$off('atguigu')
-
組件上也可以綁定原生DOM事件,需要使用
native
修飾符。 -
注意:通過(guò)
this.$refs.xxx.$on('atguigu',回調(diào))
綁定自定義事件時(shí),回調(diào)要么配置在methods中,要么用箭頭函數(shù),否則this指向會(huì)出問(wèn)題!
2、全局事件總線(GlobalEventBus)
-
一種組件間通信的方式,適用于任意組件間通信。
-
安裝全局事件總線:
new Vue({......beforeCreate() {Vue.prototype.$bus = this //安裝全局事件總線,$bus就是當(dāng)前應(yīng)用的vm},...... })
-
使用事件總線:
-
接收數(shù)據(jù):A組件想接收數(shù)據(jù),則在A組件中給$bus綁定自定義事件,事件的回調(diào)留在A組件自身。
methods(){demo(data){......} } ...... mounted() {this.$bus.$on('xxxx',this.demo) }
-
提供數(shù)據(jù):
this.$bus.$emit('xxxx',數(shù)據(jù))
-
最好在beforeDestroy鉤子中,用$off去解綁當(dāng)前組件所用到的事件。
2.1 應(yīng)用全局事件總線
- 我們利用全局事件總線來(lái)完成一個(gè)兄弟間的通信
目錄結(jié)構(gòu)圖:
代碼示例:
在main文件
里面安裝全局事件總線
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//關(guān)閉Vue的生產(chǎn)提示
Vue.config.productionTip = false//創(chuàng)建vm
new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this //安裝全局事件總線},
})
沒(méi)有涉及到和app組件通信,所以app組件正常編寫(xiě)即可
<template><div class="app"><h1>{{msg}}</h1><School/><Student/></div>
</template><script>import Student from './components/Student'import School from './components/School'export default {name:'App',components:{School,Student},data() {return {msg:'你好啊!',}}}
</script><style scoped>.app{background-color: gray;padding: 5px;}
</style>
由于我們將school組件
作為接受數(shù)據(jù)方,所以我們要給school組件
種的$bus綁定自定義事件,事件的回調(diào)留在school組件自身。
<template><div class="school"><h2>學(xué)校名稱:{{name}}</h2><h2>學(xué)校地址:{{address}}</h2></div>
</template><script>export default {name:'School',data() {return {name:'東方',address:'北京',}},mounted() {// console.log('School',this)this.$bus.$on('hello',(data)=>{console.log('我是School組件,收到了數(shù)據(jù)',data)})},beforeDestroy() {this.$bus.$off('hello')},}
</script><style scoped>.school{background-color: skyblue;padding: 5px;}
</style>
由于我們將student組件
作為提供數(shù)據(jù)方,所以我們要在student組件
中調(diào)用自定義事件
<template><div class="student"><h2>學(xué)生姓名:{{name}}</h2><h2>學(xué)生性別:{{sex}}</h2><button @click="sendStudentName">把學(xué)生名給School組件</button></div>
</template><script>export default {name:'Student',data() {return {name:'張三',sex:'男',}},mounted() {// console.log('Student',this.x)},methods: {sendStudentName(){this.$bus.$emit('hello',this.name)}},}
</script><style lang="less" scoped>.student{background-color: pink;padding: 5px;margin-top: 30px;}
</style>
3、 消息訂閱與發(fā)布(pubsub)
-
一種組件間通信的方式,適用于任意組件間通信。
-
使用步驟:
-
安裝pubsub:
npm i pubsub-js
-
引入:
import pubsub from 'pubsub-js'
-
接收數(shù)據(jù):A組件想接收數(shù)據(jù),則在A組件中訂閱消息,訂閱的回調(diào)留在A組件自身。
methods(){demo(data){......} } ...... mounted() {this.pid = pubsub.subscribe('xxx',this.demo) //訂閱消息 }
-
提供數(shù)據(jù):
pubsub.publish('xxx',數(shù)據(jù))
-
最好在beforeDestroy鉤子中,用
PubSub.unsubscribe(pid)
去取消訂閱。
-
3.1 應(yīng)用消息訂閱與發(fā)布
- 將上面的
全局事件總線案例
應(yīng)用消息訂閱與發(fā)布
的方法實(shí)現(xiàn)一下,整體思路是一樣的。
目錄結(jié)構(gòu)圖:
首先我們先要安裝pubsub:npm i pubsub-js
,然后在需要通信的組件中引入import pubsub from 'pubsub-js'
這個(gè)包。
代碼示例:
main文件
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//關(guān)閉Vue的生產(chǎn)提示
Vue.config.productionTip = false//創(chuàng)建vm
new Vue({el:'#app',render: h => h(App),
})
app組件
<template><div class="app"><h1>{{msg}}</h1><School/><Student/></div>
</template><script>import Student from './components/Student'import School from './components/School'export default {name:'App',components:{School,Student},data() {return {msg:'你好啊!',}}}
</script><style scoped>.app{background-color: gray;padding: 5px;}
</style>
school組件
作為接受信息訂閱方
<template><div class="school"><h2>學(xué)校名稱:{{name}}</h2><h2>學(xué)校地址:{{address}}</h2></div>
</template><script>import pubsub from 'pubsub-js'export default {name:'School',data() {return {name:'東方',address:'北京',}},mounted() {this.pubId = pubsub.subscribe('hello',(msgName,data)=>{console.log(this)// console.log('有人發(fā)布了hello消息,hello消息的回調(diào)執(zhí)行了',msgName,data)})},beforeDestroy() {pubsub.unsubscribe(this.pubId)},}
</script><style scoped>.school{background-color: skyblue;padding: 5px;}
</style>
student組件
作為發(fā)布信息方
<template><div class="student"><h2>學(xué)生姓名:{{name}}</h2><h2>學(xué)生性別:{{sex}}</h2><button @click="sendStudentName">把學(xué)生名給School組件</button></div>
</template><script>import pubsub from 'pubsub-js'export default {name:'Student',data() {return {name:'張三',sex:'男',}},mounted() {},methods: {sendStudentName(){pubsub.publish('hello',666)}},}
</script><style lang="less" scoped>.student{background-color: pink;padding: 5px;margin-top: 30px;}
</style>