Vue组件间通信

目录

1.父传子

2.子传父

3.父子间通信扩展

4.兄弟间通信


前言: 我们把页面拆分成不同的组件,提高了复用性,但是拆分完组件后,有的数据,在多个组件中都需要使用,但是我们只能在其中一个组件中获取到数据,此时.我们就需要根据组件间的关系来传递数据

1.父传子

核心 子组件中 props 接收 + 父组件中 v-bind 传递数据

1. 父组件中在使用子组件时,利用v-bind把数据传递给子组件

2.子组件中,利用props,接收数据

3.在子组件中使用接收到的数据

props 接收形式 :

1.数组 [  'params ' ]      直接接收数据

2.对象 { params : type }  对接收到的数据类型进行制定

3.多层对象{ params : type , required : true , default : 1} 对接收到的数据类型,是否必传,默认值进行制定

注意 : props接收到的数据一般不建议更改,如果确实需要更改,在子组件中,声明一个中转属性,把接收到的值作为初始值

代码如下

<div id="app">
    <far-component></far-component>
</div>
<template id="far">
    <div style="background-color: orange;width: 400px;height: 400px;">
        <h1>{{value}}</h1>
        <son-component :val="value"></son-component>
    </div>
</template>
<template id="son">
    <div style="background-color: antiquewhite;width: 200px;height: 200px;">
    <h1>子组件收到的数据:{{val}}</h1>
    </div>
</template>
<script>
    let sonComponent = {
        template: '#son',
        // props: ['val'],
        // props:{
        //     val:String
        // },
        props:{
            val:{
                type:String
                required:true,
                default:'默认值'
            }
        }
    }
    let farComponent = {
        template: '#far',
        data(){
            return {
               value:'父组件数据'
            }
        },
        components: {sonComponent}
    }
    new Vue({
        el: '#app',
        components: {farComponent}
    })
</script>

2.子传父

1. 通过自定义事件实现

通过$emitv-on 实现

1.在父组件中给子组件上通过v-on绑定自定义事件,回调函数在父组件中执行并接收数据

2.在子组件的事件函数通过$emit()触发自定义事件,并传递参数

代码如下:

<div id="app">
<far-component></far-component>
</div>
<template id="far">
    <div>
        <h1>父组件:{{message}}</h1>
        <hr>
        <son-component  @demo="getData"></son-component>
    </div>
</template>
<template id="son">
    <div>
        <h1>子组件: {{value}}</h1>
        <button @click="sendData">传递数据给父组件</button>
    </div>
</template>
<script>
    let SonComponent = {                                                         
        template: '#son',                
        data() {
            return {
                value: '子组件中的数据',
            }
        },                 
        methods:{
            sendData(){
               this.$emit('demo',this.value)
            }
        }
    }
    let FarComponent = {
        template: '#far',
        components: {SonComponent},
        methods:{
            getData(params){
                this.message = params
            }
        }
    }
    new Vue({
        el: '#app',
        components: {FarComponent}
    })
</script>

2.通过ref实现

1. 在父组件中给子组件添加ref属性

2.父组件中一挂载(mounted函数中),利用$refs获取到子组件,利用$on给他绑定自定义事件,事件的回调是methods中的方法

3. 在子组件的事件函数中,触发自定义事件,并传递参

 注意: 自定义事件的回调函数中的this不是Vue的实例对象,所以不能在回调函数中直接使用this.传递数据;解决办法: 1. 事件回调写在methods中,然后调用methods中的方法 2. 回调函数使用箭头函数,没有自己的this指向,在当前上下文中的this是Vue的实例对象

代码如下

<div id="app">
    <far-component></far-component>
</div>
<template id="far">
    <div>
        <h1>父组件:{{val}}</h1>
        <hr>
        <son-component ref="sonCom"></son-component>
    </div>
</template>
<template id="son">
    <div>
        <h1>子组件:</h1>
        <button @click="sendData">点击传递数据</button>
    </div>
</template>
<script>
    let SonComponent = {
        template: '#son',
        data() {
            return {
                a: 100,
                b: 200
            }
        },
        methods: {
            sendData() {
                this.$emit('demo', 123)
            },
        }
    }
    let FarComponent = {
        template: '#far',
        components: {SonComponent},
        data(){
           return {
               val:''
           }                           
        },                               
        methods: {                       
            getData(a) {                
               this.val = a             
            }
        },
        mounted() {
            this.$refs.sonCom.$on('demo', this.getData)
        }
    }
    new Vue({
        el: '#app',
        components: {FarComponent}
    })
</script>

3.父子间通信扩展

$parent         获取父组件

$children      获取所有子组件

$refs             根据ref获取标签对象

$root            获取根组件

代码如下,了解即可

<div id="app">
<far-component></far-component>
</div>
<template id="far">
    <div>
        <h1>父组件:</h1>
        <hr>
        <son-component ref="sonCom"></son-component>
        <button @click="getCom">点击获取子组件</button>
    </div>
</template>
<template id="son">
    <div  ref="sonCom">
        <h1>子组件:</h1>
        <button @click="getHtml">点击获取标签</button>
    </div>
</template>
<script>
    let SonComponent = {
        template: '#son',
        data(){
            return {
                a:100,
                b:200
            }
        },
        methods:{
            sendData(){
                console.log('.............')
            },
            getHtml(){
                console.log(this.$refs.sonCom)  // 根据ref名称获取标签
                console.log(this.$parent)       // 获取父组件
                console.log(this.$root)         // 获取根组件 VM
            }
        }
    }
    let FarComponent = {
        template: '#far',
        components: {SonComponent},
        methods:{
            getCom(){
                console.log(this.$children)           // 获取所有子组件
                console.log(this.$children[0].a)       // 获取某个子组件中的数据
                console.log(this.$children[0].b)
                console.log(this.$children[0].$refs.sonCom)
            }
        }
    }
    new Vue({
        el: '#app',
        components: {FarComponent}
    })
</script>

 4.兄弟间通信

实现兄弟间通信的方式常用的有以下两种: 

1. 在父子通信的基础上,子组件传递数据给父组件,通过父组件传递给另一个子组件

2. 全局事件总线 globalEventBus

3. 消息订阅与发布(下载第三方库,如pubsub等)

4.1全局事件总线使用

1.安装全局事件总线

new Vue({
        el: '#app',
        components: {FarComponent,SonComponent},
        beforeCreate(){
            Vue.prototype.$bus = this
        }
    })

2. 使用事件总线

1.接收数据

      methods: {
            getData(a) {
                this.val = a
            }
        },
        mounted(){
            this.$bus.$on('demo',this.getData)
        },

2. 提供数据

       methods: {
            sendData() {
                this.$bus.$emit('demo', this.a)
            },
        }

全局事件总线实现兄弟通信案例

<div id="app">
    <son-component></son-component>
    <far-component></far-component>
</div>
<template id="com1">
    <div>
        <h1>组件1:a: {{a}}; b: {{b}}</h1>
        <button @click="sendData">点击发送数据</button>
        <hr>
    </div>
</template>
<template id="com2">
    <div>
        <h1>组件2:{{val}}</h1>
    </div>
</template>
<script>                          // 全局事件总线 :
    let SonComponent = {          //1. 安装全局事件总线 :
        template: '#com1',             // new Vue({ beforeCreate(){Vue.prototype.$bus = this}})
        data() {                  // 2. 提供数据 : this.$bus.$emit('事件',数据)
            return {              // 3. 接收数据 : mounted(){this.$bus.$on('事件',回调)}
                a: 100,
                b: 200
            }
        },
        methods: {
            sendData() {
                this.$bus.$emit('demo', this.a)
            },
        }
    }
    let FarComponent = {
        template: '#com2',
        data(){
           return {
               val:''
           }
        },
        methods: {
            getData(a) {
                console.log(a)
                this.val = a
            }
        },
        mounted(){
            this.$bus.$on('demo',this.getData)
        },

    }
    new Vue({
        el: '#app',
        components: {FarComponent,SonComponent},
        beforeCreate(){
            Vue.prototype.$bus = this
        }
    })
</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值