先来看一个父子之间的组件通信;

body>
        <div id="app">
           <my-component msg="来自父组件的数据"></my-component>   
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        Vue.component('my-component',{
            props:['msg'],
             template: '<div>{{msg}}</div>'
        });
        new Vue({
            el: '#app'
        });

    </script>

在父组件中,定义了这样一个变量:msg="来自父组件的数据";而我们可以在子组件中,通过选项props来接收来自父组件的数据,注意要跟父组件中传过来的一致,随后,我们就可以在模板中,用插值的方式,把来自父组件的数据显示出来了。

注意:props中声明的数据与data函数return的数据,最大的区别就是,props的数据来自其父级,而data函数return的数据来自自身的这个作用域。

而我们可能会遇到动态的数据,也就是说,数据本身是不确定的,这个时候,我们应该怎么做呢?

<body>
        <div id="app">
            <input type="text" v-model="parentmsg"> //输入的数据与parentmsg绑定在一起
           <my-component :msg="parentmsg"></my-component>   //用v-bind:  绑定来自父组件的parentmsg
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        Vue.component('my-component',{
            props:['msg'],  //通过props属性,声明来自父组件的值
             template: '<div>{{msg}}</div>'   //用插值的方式显示父组件的值
        });
        new Vue({
            el: '#app',
            data:{
                parentmsg:''   //初始化父组件中的值,默认为空。
            }
        });

    </script>

也就是说,我们要用v-model和v-bind绑定对应值,以此来达到动态数据,双向绑定的目的。

再看子父之间的通信:

子组件用$emit()来触发事件,父组件用$on(),来监听子组件触发的事件.看一个详细的例子。

<!DOCTYPE html>
<html>
    <body>
        <div id="app">
            <p>总数{{total}}</p>           
<my-component @increase="handleGetTotal" @reduce="handleGetTotal"></my-component>   
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        Vue.component('my-component',{
                 template: `
                 <div>\
                 <button @click="handleIncrease">+1</button>
                 <button @click="handleReduce">-1</button>
                 </div>`,
                 data:function(){
                 return {
                    counter:0
                }
                 },
                 methods:{
                    handleIncrease:function(){
                        this.counter++;
                        this.$emit('increase',this.counter);
                    },
                    handleReduce:function(){
                         this.counter--;
                        this.$emit('reduce',this.counter);
                    }
                         }
                });
        new Vue({
            el: '#app',
            data:{
                total:0
            },
            methods:{
                handleGetTotal:function(total){
                    this.total=total;
                }
            }
        });
    </script>

</html>

在这里面,我们分别为父组件和子组件用v-on:绑定了事件,其中,子组件的.$emit()有两个参数,第一个是父组件中的,自定义事件名称,第二个是参数。而在父组件中用,v-on:绑定自定义事件,以此来监听子组件的事件。以此来达到,子组件改变值,触发父组件也改变值。

来给一个v-model创建自定义的表单输入组件,进行双向数据绑定。

<!DOCTYPE html>
<html>
    <body>
        <div id="app">
            <p>总数{{total}}</p>           
<my-component v-model="total"></my-component>   
<button @click="handleReduce">-1</button>
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        Vue.component('my-component',{
            props:['value'],       
                 template: `
                 <input :value="value" @input="updateValue">`,
                 methods:{
                    updateValue:function(event){
                        this.$emit('input',event.target.value);
                    }
                }
                });
        new Vue({
            el: '#app',
            data:{
                total:0
            },
            methods:{
                handleReduce:function(){
                    this.total--;
                }
            }
        });
    </script>

</html>

再来看看父子,同级,跨级的组件之间是怎么通信的吧。在vue2.0中,用一个空的VUE实例作为中央事件总线,所有的通信都是通过bus作为中间件来达到目的的。

<!DOCTYPE html>
<html>
    <body>
        <div id="app">
            {{message}}
            <component-a></component-a>
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        var bus = new Vue();   //创建一个空的Vue实例,bus作为‘中间件’
        Vue.component('component-a',{
                 template: `
                <button @click="handleEvent">传递事件</button>`,
                 methods:{
                    handleEvent:function(){
                        bus.$emit('on-message','来自组件component-a的内容')   //触发事件,第一个为事件名,第二个为传递的参数
                    }
                }
                });
        var app = new Vue({
            el: '#app',
            data:{
                message:''
            },
         created:function(){
            var _this=this;  //在调用bus的函数之前,把当前this保存起来,因为在钩子函数中,调用函数之后,this 的指向会被改变,
            bus.$on('on-message',function(msg){  //在钩子函数中,监听到了来自bus的事件,第二个参数为回调函数,传递消息的步骤在回调函数中完成。
                _this.message=msg;
            });
         }
        })
    </script>
</html>

Logo

前往低代码交流专区

更多推荐