目录
因为今天正好看完Bzhan张天禹老师教的toDoList案例,然后里面就涉及到到了各种组件间的通讯方式,听的还是比较明白,因为在之前还没有系统的学习vue的时候就已经弄了一些简单的组件通讯案例,今天学习到了听到也懂的快,但是我还是觉得需要自己动手弄一下,果然,在今天我晚上弄的时候就是那种道理我都懂,但是实操起来是真的不知道怎么下手,。。。。然后果断的又返回去看了例子,最后弄了好一会才搞出来。
好了直接上例子把,里面都有解释的~~~
最基本的组件通信方法:
然后这个就是涉及到的组件,和老师讲的几乎差不多,就是所有的都由app来管理,grandfa中管理fathe,father管理grandson。父子通信就是通过props传递数据,在父组件引入子组件时在子组件上面绑定一个一个参数,使用 :参数名=‘变量/方法’。
然后子向父通信,就是要在父组件中先准备一个方法绑定在被映入到父组件的子组件身上,然后在子组件中使用props接收,并且返回给父组件一个参数,然后父组件就可以直接使用这个参数了
app组件:
<template>
<div id="app">
<grand-fa/>
<!-- 在这里使用grandfa组件 -->
</div>
</template>
<script>
import GrandFa from './components/grandFa.vue' //一定记得要引入哦
export default {
name: 'App',
components: {//当然了也得注册组件
GrandFa
}
}
</script>
<style>
/* 这下边的不用管,自带的 */
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
grandFa组件:
<template>
<div class="">
<div class="ye">
<h2>我是爷爷</h2>
<!-- 哈哈哈这个button几乎没啥用,为了好看摆在这里把,不然多孤单 -->
<button>点我获取孙子的名字和年龄</button>
</div>
<!-- 这行就是传参啦 -->
<father :getSon='getSon' :grandFaObj='grandFaObj' :getGrandSon='getGrandSon'/>
</div>
</template>
<script>
import father from './father.vue'
export default {
data () {
return {
grandFaObj:{
name:'王老头',
age:78
}
}
},
methods:{
getSon(obj){
console.log('此处是子向父传信息,大爷我是王老头,我儿子向我发送了信息他的信息为:',obj.name,obj.age)
},
getGrandSon(obj1){
console.log('此处是子向爷传信息,大爷我是王老头,我孙子向我发送了信息他的信息为:',obj1.name,obj1.age)
}
},
components: { father }
}
</script>
<style scoped>
.ye{
background-color: aqua;
}
</style>
father组件:
<template>
<div class="son">
<h3>我是儿子</h3>
<button @click="sendSon">点我向父亲发送我的名字和年龄</button>
<GrandSon :toSon='son' :grandFa='grandFaObj' :getMySon='getMySon'/>
</div>
</template>
<script>
import GrandSon from './grandSon.vue'
export default {
name: 'sonVue',
props:['getSon','grandFaObj','getGrandSon'],
data () {
return {
son:{
name:'王老子',
age:40
}
}
},
methods:{
sendSon(){//此处是为了子向爷传数据
this.getSon(this.son)
},
getMySon(obj){//此处是子向父传数据
console.log('此处是子父通信,我是老子,儿子向我传数据了,',obj.name,obj.age)
this.getGrandSon(obj)//这里偷个懒,因为本来就是子向爷传数据时就是要经过父亲的,
//所以我直接在这里向爷爷发送了数据,但是有一点不好,子向父和子向爷是同时发生的,偷懒~~~
},
},
components: { GrandSon }
}
</script>
<style>
.son{
background-color: beige;
}
</style>
grandSon组件:
<template>
<div class="sun">
<h3>我是孙子</h3>
<button @click="getFather">点我获取父亲的名字和年龄</button>
<button @click="getGrand">点我获取爷爷的名字</button>
<button @click="sendToFa">点我向父亲发送我的信息,这属于子向父跨通信</button><br>
<button @click="sendToFa">点我向爷爷发送我的信息,这属于子向父跨两级通信</button>
</div>
</template>
<script>
export default {
props:['toSon','grandFa','getMySon'],
data () {
return {
grand: {
name:'王小子',
age:18
}
}
},
methods:{
getFather(){
console.log('此处是父向子传信息,我是儿子,父亲的名字:'+this.toSon.name+' 父亲的年龄:'+this.toSon.age)
},
getGrand(){
console.log('此处是两层父子通信,我是孙子我拿到爷爷的信息啦,名字是:',this.grandFa.name,this.grandFa.age)
},
sendToFa(){
this.getMySon(this.grand)
}
},
components: {}
}
</script>
<style>
.sun{
background-color: pink;
}
</style>
使用$emit()实现子父通信
father组件
里面只有一点改了,我用红色圈出来,然后其他都是和上面一样的,在这里使用@绑定一个自定义事件
<template>
<div class="son">
<h3>我是儿子</h3>
<button @click="sendSon">点我向父亲发送我的名字和年龄</button>
<GrandSon :toSon='son' :grandFa='grandFaObj' @getMySon='getMySon'/>
</div>
</template>
下面是grandSon组件
<template>
<div class="sun">
<h3>我是孙子</h3>
<button @click="getFather">点我获取父亲的名字和年龄</button>
<button @click="getGrand">点我获取爷爷的名字</button>
<button @click="sendToFa">点我向父亲发送我的信息,这属于子向父跨通信</button><br>
<button @click="sendToFa">点我向爷爷发送我的信息,这属于子向父跨两级通信</button>
</div>
</template>
<script>
export default {
props:['toSon','grandFa'],//这里你可以看见props中没有了getMySon这个参数了
data () {
return {
grand: {
name:'王小子',
age:18
}
}
},
methods:{
getFather(){
console.log('此处是父向子传信息,我是儿子,父亲的名字:'+this.toSon.name+' 父亲的年龄:'+this.toSon.age)
},
getGrand(){
console.log('此处是两层父子通信,我是孙子我拿到爷爷的信息啦,名字是:',this.grandFa.name,this.grandFa.age)
},
sendToFa(){
this.$emit('getMySon',this.grand)//这里用emit事件,第一个是在父组件中使用@绑定的事件名,第二个是要传给父组件的参数
//this.getMySon(this.grand)
}
},
components: {}
}
</script>
<style>
.sun{
background-color: pink;
}
</style>
使用全局事件总线实现任意两个组件之间通信
在main.js文件中先定义一个总线$Bus,并且使用生命周期函数beforeCreate函数,使得这个this指向Vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
beforeCreate(){
Vue.prototype.$bus=this //安装全局组件,$bus就是当前的VUeComponent示例对象
},
render: h => h(App),
}).$mount('#app')
grandFa组件
然后这个mount钩子也是生命周期函数,表示的是在挂载时调用里面的一些方法啥的,这里的data是另外一个组件向grandFa组件传来的信息
mounted(){
this.$bus.$on('getByBus',data=>{
console.log('此处通过事件总线传递孙子的数据',data.name,data.age)
})
}
grandSon组件
这个组件里面就是多加了一个按钮的点击事件,然后通过定义好的$bus总线向绑定事件getByBus的组件发送数据
<button @click="sendByBus">通过bus事件总线向爷爷发送信息</button>
sendByBus(){
this.$bus.$emit('getByBus',this.grand)
}
使用ref实现父子通信
其实这个也不能说是通信,但是的确能够操作子组件的数据,原理是在父组件中直接拿到子组件的dom元素。使用方法是在组件实例中使用ref即可。
代码实现:
在父组件中引入upload实例
......
<upload ref='myref'/>在子组件中使用ref
........
script中
在方法中直接使用
this.$refs.myref.属性值
就可以直接拿到子组件upload的dom元素了
总结:
好啦,完整代码分享完毕啦,结合老师的例子多看几遍,最后在来试试我这个例子,你应该就能明白组件通信的原理啦。还是要多动手,不要以为你听懂了就会了,海得自己敲出来才OK。让我们一起卷起来好吗,然后这个案例这部分应该在72集左右