vue.js组件——组件通信

组件关系有:父子组件通信、兄弟组件通信、跨级组件通信。

一、自定义事件

子组件用$emit()来触发事件,父组件用$on()来监听子组件的事件。

父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件出发的自定义事件。

<div id="app">
        <p>总数:{{ total }}</p>
        <my-component
            @increase="handleGetTotal"
            @reduce="handleGetTotal"></my-component>
    </div>
    <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);
                }
            }
        });

        var app = new Vue({
            el:'#app',
            data:{
                total:0
            },
            methods:{
                handleGetTotal:function (total) {
                    this.total = total;
                }
            }
        })
    </script>

子组件有两个按钮实现效果,改变组件的data"counter"后,通过$emit()再把它传递给父组件,父组件用绑定的两个方法。

除了用v-on在组件监听自定义事件外,也可以监听DOM事件,这时可以用.native修饰符表示监听的是一个原声的事件,监听的是该组件的根元素。

使用v-model

<div id="app">
    <p>总数为:{{ total }}</p>
    <my-component v-model="total"></my-component>
</div>
<script>
    Vue.component('my-component',{
        template:'<button @click="handleClick">+1</button>',
        data:function () {
            return {
                counter:0
            }
        },
        methods:{
            handleClick:function () {
                this.counter++;
                this.$emit('input',this.counter);
            }
        }
    });
    var app = new Vue({
        el:'#app',
        data:{
            total:0
        }
    })
</script>

$emit的事件名为特殊的inpuut,在使用组件的父级,并没有在<my-component>上使用@input=“handle”,而是直接用v-model绑定的一个数据total。v-model还可以用来创建自定义的表单输入组件。

<div id="app">
    <p>总数为:{{ total }}</p>
    <my-component v-model="total"></my-component>
    <button @click="handleReduce">-1</button>
</div>
<script>
    Vue.component('my-component',{
        props:['value'],
        template:'<input type="text" :value="value" @input="updateValue"/>',
        methods:{
            updateValue:function (event) {
                this.$emit('input',this.target.value);
            }
        }
    });
    var app = new Vue({
        el:'#app',
        data:{
            total:'',
        },
        methods:{
            handleReduce:function () {
                this.total--;
            }
        }
    })
</script>

非父子组件通信

在vue.js 2.x中,推荐使用一个空的Vue实例作为中央事件总线。

<div id="app">
        {{ message }}
        <component-a></component-a>
    </div>
    <script>
        var bus = new Vue();
        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:''
            },
            mounted:function () {
                var _this = this;
                bus.$on('on-message',function (msg) {
                    _this.message = msg;
                })
            }
        })
    </script>

首先创建了一个名为bus的空的vue实例,全局定义了组件component-a,在app初始化时,在生命周期mounted钩子函数里监听来自bus的事件on-message,在组件component-a中,点击按钮会通过bus把事件发出去,此时app就会就接收到来自bus的事件,进而在回掉里完成自己的业务。还有两种方式实现组件间的通信:父链和子组件。不建议用父链操作。

猜你喜欢

转载自blog.csdn.net/qq_38311097/article/details/82693507