vue中$on与$emit的实际应用
$on常用于监听自定义事件,触发后可传入参数
//监听event1事件 vm.$on('event1',function(msg){ console.log(msg) })
//触发event1自定义事件 vm.$emit('event1','参数')
需要注意的时,自定义事件必须绑定在实例上,否则无效。
应用一:传值可用于组件间的数据通信,如下例:(将A组件的数据a和B组件的数据b传入C组件中)
//A组件 var A={ template:"<div><h2>组件A</h2><input type='button' value='btnA' @click='send'></div>", data(){ return { a:"data A" } }, methods:{ send(){ Event.$emit("a-msg",this.a); } } };
//B组件 var B={ template:"<div><h2>组件B</h2><input type='button' value='btnB' @click='send'></div>", data(){ return { b:"data B" } }, methods:{ send(){ Event.$emit("b-msg",this.b); } } };
//C组件 var C={ template:"<div><h2>组件C</h2><h3>{{a}}</h3><h3>{{b}}</h3></div>", data(){ return { a:"", b:"" } }, mounted(){ var _this=this; Event.$on("a-msg",function(str){ _this.a=str; }) Event.$on("b-msg",function(str){ _this.b=str; }) } }
注册组件
new Vue({ el:"#box", components:{ "com-a":A, "com-b":B, "com-c":C } })
应用一示例的全部代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="box"> <com-a></com-a> <com-b></com-b> <com-c></com-c> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var Event=new Vue(); var A={ template:"<div><h2>组件A</h2><input type='button' value='btnA' @click='send'></div>", data(){ return { a:"data A" } }, methods:{ send(){ Event.$emit("a-msg",this.a); } } }; var B={ template:"<div><h2>组件B</h2><input type='button' value='btnB' @click='send'></div>", data(){ return { b:"data B" } }, methods:{ send(){ Event.$emit("b-msg",this.b); } } }; var C={ template:"<div><h2>组件C</h2><h3>{{a}}</h3><h3>{{b}}</h3></div>", data(){ return { a:"", b:"" } }, mounted(){ var _this=this; Event.$on("a-msg",function(str){ _this.a=str; }) Event.$on("b-msg",function(str){ _this.b=str; }) } } new Vue({ el:"#box", components:{ "com-a":A, "com-b":B, "com-c":C } }) </script> </body> </html>
应用二:子组件与父组件的通信
父组件代码:(父组件自定义changeTitle函数)
<template> <section class="sear-box">
//将isShow数据传递给searchInput组件,并进行双向绑定,子组件数据更新后,父组件的数据也相应改变,从而改变相应数据驱动的视图,2.3.x版本中恢复sync的使用。 <searchInput :isShow.sync='listShow' :title='title'></searchInput> <searchList v-show='listShow' @changeTitle='titleHandle'></searchList> </section> </template> <script> //搜索框 import searInput from './searInput' //搜索推荐列表 import searList from './searList' export default { components: { searchInput: searInput, searchList: searList }, data () { return { listShow: false, title: '' } }, methods: { //自定义事件的事件处理函数 titleHandle (title) { this.title = title } } } </script>
子组件:
<template> <section> <ul class="sear-list"> <li v-for='item in data' :key='item.id' @click='listClickHandle(item.title)'>{{ item.title }}</li> </ul> </section> </template> <script> let data = [ {title: 'html', id: 1}, {title: 'html+css', id: 2}, {title: 'html+css3', id: 3} ] export default { data () { return { data: data } }, methods: { listClickHandle (title) { //点击搜索推荐列表项时触发listClickHandle函数并触发自定义事件changeTitle this.$emit('changeTitle', title) } } } </script>
应用三:更新数据
父组件同应用二;
子组件代码:
<template> <section class="sear-con"> <input type="text" name="" class="sear-input" @click='clickHandle' v-model='title'><a href="#" class="sear-btn">search</a> </section> </template> <script> export default { props: ['isShow', 'title'], computed: { initShow () { return this.isShow } }, methods: { clickHandle () { console.log('click') //点击搜索框时触发clickHandle函数并将isShow数据修改为!this.initShow this.$emit('update:isShow', !this.initShow) } } } </script>
Demo的github地址https://github.com/pomelott/VueDemo