最近在刷面试题,看到vue时感觉自己像没学过一样,这下又重新学习了一遍vue。其实我之前跟着B站黑马学习过,但黑马那个视频过于基础,vue讲了一点就直接接上vue+elementUi的电商管理系统,让你成了一个cv。尽管我是靠黑马自学的,是pink粉。但我个人建议学vue还是要尚硅谷。以下文章是基于尚硅谷视频中组件间通信所提炼的文章,大佬请绕过!!!
废话不多说,进入正题。
组件间通信无非就几种,分别为父->子(A-B,B-C,B-D),子->父,兄弟组件间通信(C-D),以及跨组件通信。(A-C,A-D)
前提准备: 使用脚手架生成项目,创建四个组件根组件App.vue、根组件的子组件School.vue、根组件的子组件Student.vue、Student子组件 Zhangsan.vue
根组件代码:
<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>
Student代码
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
}
},
}
</script>
<style scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name:'School',
data() {
return {
name:'青花大学',
address:'北京',
}
},
}
</script>
<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
</style>
第一种通信:父->子 这是最简单的基本都知道就是用 props 。(从App.vue传个值给School.vue)
直接在App.vue中找到子组件,即 <School/>,直接在 <School/>身上写值即<School :message="message" /> message在data中定义,我这里写的 ' 明天全校放假' 子组件使用props接收。第一种完毕
第二种通信:子->父:
①在App.vue中定义个方法,通过传给子组件函数,子组件调用然后传值。
App.vue
这个方法需要props接收,下面是另一种方法。
②子组件传父组件:绑定自定义事件(v-on或者@)+$emit传
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
③子组件传父组件:通过ref+$emit传递
<Student ref="receview4"/>
......
mounted(){
this.$refs.demo.$on('receview4',事件回调)
}
其本质是改变了一下绑定自定义事件方法, 通过this.$refs.receview4
拿到Student组件的实例对象,写在mounted中,保证App挂载完毕。通过this.$refs.receview4.$on('receview4',事件回调)
绑定,Student与方法二一样,通过$emit传递。
这个方法看起来好像更麻烦了,但是他灵活性强,比如可以隔5秒后绑定事件、
第三种通信:爷->父->子,就是App.vue传给Zhangsan.vue。可类似于一整条链传播。这个与第一种类似,传递方式爷->父->子,逐层传递。使用props接收数据
App.vue
Student组件
Zhangsan组件
这样就从爷爷传到孙子,但是是一层一层的传递。
兄弟间传递
①借助父组件传值,先将要传的东西通过School组件传给App.vue 然后通过App.vue传给Student。
最最最最重要的来了!!!!!!
全局事件总线(GlobalEventBus)
一种组件间通信的方式,适用于任意组件间通信
安装全局事件总线:
在main.js中配
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})
接收数据:A组件想接收数据,则在A组件中给$bus
绑定自定义事件,事件的回调留在A组件自身。
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
提供数据:```this.$bus.$emit('xxxx',数据)```
获取数据
提供数据
还有一种可以组件间任意通信,那就是消息订阅与发布。
其实大家知道vue的双向绑定原理其中一部分是 消息订阅与发布设计模式,在这里我介绍一种消息订阅与发布实现组件间通信
准备工作:安装pubsub库:npm i pubsub-js
引入: import pubsub from 'pubsub-js'
A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){
demo(data){......}
}
......
mounted() {
this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}
B组件想发出数据,则在B组件中发布消息。
pubsub.publish('xxx',数据)
即:
School发布消息:
Student订阅消息:
注意:回调函数第二个参数才是数据
记住所有事件绑定后最好在beforeDestroy钩子中使用 this.$off('事件名')
解绑
对于发布订阅则在beforeDestroy钩子中,用PubSub.unsubscribe(pid)
去取消订阅。
以上是我对组件间传递的理解。还有vuex部分没有加上,以后会加。目前打了5600多个字,都是手打的,请各位支持下萌新,打字不容易。
此外,如有错误之处,请在评论指出,我会立即修改,以免误人子弟。
谢谢大家!!!