VUE组件:组件通信

概述

所谓组件间的通信,实际上就是指在各个组件间,进行参数或者信息的相互传递。比如通过props给子组件传参,实际上这就是父组件向子组件进行单向的通信


组件通信的几种方式

(一)父到子的通信

父到子的通信使用props即可,在以前的博客中我有详细的讲解,不懂可以去看一下


(二)子到父的通信

①父子组件的概念

父组件:主动发起调用的哪一方,父组件一般可以给子组件传参

子组件:被调用的哪一方,子组件可以接受父组件传来的参数

例如:当我们在一个vue实例绑定的div中使用自定义组件component,那么这个vue实例就是父组件,被调用的component就是子组件


②子组件向父组件通信流程
  1. 在父组件中定义一个可以接受子组件信息的方法
    在这里插入图片描述
  2. 然后把这个方法类似于传参一样传入子组件,(v-on+自定义事件名绑定)
<h1>{{message}}</h1>
<son-component v-on:method='changeMes'></son-component>
  1. 在子组件就获取此方法,并进行传参调用来修改父组件内容,用this.$emit(事件名,参数)
    在这里插入图片描述
    $emit方法中附加参数都会传给监听器回调
    在这里插入图片描述
    点击子组件中定义的按钮
    在这里插入图片描述
    其实说白了,真正执行修改父组件的数据的代码还是定义在父组件的方法中的,只是由子组件触发并调用了而已

③扩展一:在组件标签上绑定原生事件

在组件标签标签上通过v-on绑定事件,如果未做声明那么绑定的就会是自定义事件,哪怕和原生事件名称一样,下面@click的代码就无法触发我们平常认知的onclick点击事件:

<son-component @click='fn' v-on:method='changeMes'></son-component>

上面的代码并不会执行点击事件, 如果要在在组件上监听原生DOM事件,可使用修饰符.native对事件进行修饰,这样就可绑定原生DOM事件,更改为:

<son-component @click.native='fn' v-on:method='changeMes'></son-component>

效果图
在这里插入图片描述


④扩展二:自定义事件@input的语法糖——v-model

当我们使用input事件作为事件名时,只要没有加上.native修饰符,那么就会作为自定义事件处理
在这里插入图片描述
因为v-mdel语法糖中实际包含了@input事件,这样我们就可以直接使用v-model来绑定
在这里插入图片描述
效果图
在这里插入图片描述
用v-model的简化点

  1. 可以去掉父组件中函数
  2. 在子组件标签上绑定时,可以使用v-model绑定,由于去掉了函数只需要绑定要改变的那个值就可以了
    不明白的可以直接参考我关于v-model语法糖的文章 点击这里

⑤直接用语法糖v-model绑定一个计算属性

在这里插入图片描述

⑥当子组件有一个完整的表单时,可以使用@input绑定计算属性实现
<body>
<div id="app">
    action:{{action}}<br>
    username:{{username}}<br>
    password:{{password}}<br>
    <login-component 
    :action = 'action' :username = 'username'
    :password = 'password' @input = "fromChange">
    </login-component>

</div>
<script>
    Vue.component('login-component',{
        props:['action','username','password'],
        data:function(){
            return{
                actionv:this.action,
                usernamev:this.username,
                passwordv:this.password,
            }
        },
        template:`
        <div>
        <form :action="actionv" @input="sendform">
        <input type="text" name="username" v-model="usernamev"/></br>
        <input type="password" name="password" v-model="passwordv"></br>
        <input type="submit" />
        <input type="reset" />
        </form>
        </div>`,
        methods:{
            sendform:function(){
                this.$emit('input',this.usernamev,this.passwordv)
            }
        }
    })
    var vueApp = new Vue({
        el:'#app',
        data:{
            username:'goudan',
            password:123456,
            action:'https://www.baidu.com'
        },
        methods: {
            fromChange:function(username,password){
                this.username = username;
                this.password = password;
            }
        },
    })
</script>
</body>

效果图
在这里插入图片描述


(三)任意组件之间的通信

在vue2中,推荐使用一个空的vue实例作为中央事件总线,来负责所有的信息转发。类似于中介。(其实也就是设计者模式的观察者模式)

通信流程
1. 创建一个作为中介的vue实例
var bus=new Vue();
2. 所有组件都把要发的信息发给中介实例——bus.$emit(事件名,参数)
3. 所有相关组件监听中介实例是否接收到了信息,好及时获取——bus.$on(事件名,回调函数)

在这里插入图片描述
在这里插入图片描述

由于中介实例能被任何组件访问,所以也就实现了任意组件间的通信

效果图
在这里插入图片描述
代码:

<body>
<div id="app">
    <div>
        <p>父组件键中接收到的消息:{{parentmes}}</p>
        <button @click=toSon>向子组件传值</button>{{message}}
    </div>
    <son-component></son-component>
</div>
<script>
    var bus = new Vue();    //中央事件总线
    //创建一个子组件
    Vue.component('son-component', {
        template: `<div>
                    <p>子组件键中接收到的消息:{{sonmes}}</p>
                    <button @click='toParent'>向父组件传值</button>{{message}}
                    </div>`,
        data: function () {
            return {
                sonmes: '',
                message: '子组件'
            }
        },
        methods: {
            toParent: function () {
                bus.$emit('son-news', '来自子组件son-component的内容');
            }
        },
        mounted: function () {
            var _this = this;
            bus.$on('parent-news', function (v) {
                _this.sonmes = v;
            })
        },

    })
    //创建一个vue实例,作为父组件
    var vueApp = new Vue({
        el: '#app',
        data: {
            parentmes: '',
            message: '父组件'
        },
        methods: {
            toSon: function () {
                bus.$emit('parent-news', '来自父组件的内容');
            }
        },
        mounted: function () {
            var _this = this;
            bus.$on('son-news', function (v) {
                _this.parentmes = v;
            })
        },
    })
</script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值