Vue 组件(三)父组件与子组件传递数据 之自定义事件

上篇学习了如何把父组件的数据传递给子组件,尽管子组件内部不能改变prop的值,但子组件能把自己的数据传递给父组件。

我们通过自定义事件来实现。

#事件绑定

$on(eventName) 监听事件

$emit(eventName) 触发事件

父组件可以在使用子组件的地方直接用v-on来监听子组件触发的事件

[注意]不能用$on侦听子组件抛出的事件,直接在模板里用v-on绑定

HTML

<div id="example">

    <parent></parent>

</div>

 

Js

var childNode = {

    template: `<button @click="incrementCounter">{{ counter }}</button>`,

    data() {

        return {

            counter: 0

        }

    },

    methods: {

        incrementCounter() {

            this.counter++;

            this.$emit('increment');   // 子组件内用$emit触发事件

        }

    },

};

 

var parentNode = {

    // 父组件内通过v-on(简写@)监听事件

    template: `

  <div class="parent">

    <p>{{total}}</p>

    <child @increment="incrementTotal"></child>    

    <child @increment="incrementTotal"></child>

  </div>

  `,

    components: {

        'child': childNode   //声明子组件

    },

    data() {

        return {

            'total': 0

        }

    },

    methods: {

        incrementTotal() {

            this.total++;

        }

    }

};

// 创建根实例

new Vue({

    el: '#example',

    components: {

        'parent': parentNode  //声明父组件

    }

})

 

上面的代码中,子组件button一旦发生click事件,就会执行incrementCounter方法,而incrementCounter()会通过$emit触发increment事件,而在父组件内,通过v-on(简写@)监听increment事件,一旦increment被触发,则执行incrementTotal方法。

最终实现的效果如图

 

 

左边点击一次右边点击两次:

 

 

#数据传递

子组件通过$emit触发事件,$emit方法的第一个参数为要触发的事件,第二个参数为要传递的数据。

var childNode = {

    template: `

  <div class="child">

    <div>

      <span>子组件数据</span>

      <input v-model="childMsg" @input="data">

    </div>

    <p>{{childMsg}}</p>

  </div>

  `,

    data() {

        return {

            childMsg: ''

        }

    },

    methods: {

        data() {

            this.$emit('pass-data', this.childMsg)   // pass-data为被触发的事件,this.childMsg为要传递给父组件的数据

        }

    }

}

var parentNode = {

    // v-on监听pass-data是否被触发,如果触发了,就执行getData方法

    template: `

  <div class="parent">

    <div>

      <span>父组件数据</span>

      <input v-model="msg">

    </div>

    <p>{{msg}}</p>

    <child @pass-data="getData"></child>   

  </div>

  `,

    components: {

        'child': childNode

    },

    data() {

        return {

            'msg': 'match'

        }

    },

    methods: {

        getData(value) {    // getData方法接收的参数value的值就是从子组件接收的数据this.childMsg

            this.msg = value;

        }

    }

};

// 创建根实例

new Vue({

    el: '#example',

    components: {

        'parent': parentNode

    }

})

 

最终效果如下

 

 

修改子组件中input值,父组件则接收到相同的值并显示出来

 

 

posted @ 2018-01-30 16:03  zi_chil  阅读(3285)  评论(0编辑  收藏  举报