天天看点

在vue2.0中父组件如何触发子组件的自定义方法?

如果我在父组件的button上绑定了click事件,我想当点击button时可以触发子组件(单文件的子组件xx.vue)的某个方法(如fn1),要这样的效果该怎样实现?之前看了vue1的文档实例里面有methods和events这两者有什么区别,为什么在vue2去掉dispatch后我用emit(‘fn’),如果fn放在events会没有响应,而放在methods里面才会被触发到?

子组件:

[html]

view plain copy print ?

  1. <!DOCTYPE html>  
  2. <html lang=“en”>  
  3. <head>  
  4.     <meta charset=“UTF-8”>  
  5.     <title>Document</title>  
  6.     <script src=“vue.js”></script>  
  7. </head>  
  8. <body>  
  9. <div id=“parent”>   
  10.     <input type=“text” name=“” id=“” v-model=“msg” />  
  11.     <input type=“button” id=“” value=“dianji” @click=“clickDt” />  
  12.     <user-profile ref=“profile”></user-profile>    
  13. </div>    
  14. <script>    
  15.     Vue.component(‘user-profile’, {    
  16.         template: ’<span>{{ msg }}</span>‘,    
  17.         data: function () {    
  18.             return {  
  19.                 msg: 123  
  20.             };  
  21.         },    
  22.         methods: {    
  23.             greet: function (msg) {    
  24.                 console.log(msg);    
  25.             }    
  26.         }    
  27.     })    
  28. //      var parent = new Vue({el: ’#parent’});    
  29. //      var child = parent.refs.profile;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.greet();&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Vue({&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el:"#parent",&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data:{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg:""&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methods:&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clickDt(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.
  30. //      child.greet();    
  31.     new Vue({  
  32.         el:"#parent",  
  33.         data:{  
  34.             msg:""  
  35.         },  
  36.         methods: {  
  37.                 clickDt(){  
  38.                 this.refs.profile.greet(this.msg);  
  39.             }  
  40.         }  
  41.     })  
  42. </script>    
  43. </body>  
  44. </html>  
在vue2.0中父组件如何触发子组件的自定义方法?
<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="vue.js"></script>
</head>
<body>
<div id="parent"> 
    <input type="text" name="" id="" v-model="msg" />
    <input type="button" id="" value="dianji" @click="clickDt" />
    <user-profile ref="profile"></user-profile>  
</div>  

<script>  
    Vue.component('user-profile', {  
        template: '<span>{{ msg }}</span>',  
        data: function () {  
            return {
                msg: 123
            };
        },  
        methods: {  
            greet: function (msg) {  
                console.log(msg);  
            }  
        }  

    })  
//      var parent = new Vue({el: '#parent'});  
//      var child = parent.$refs.profile;  
//      child.greet();  
    new Vue({
        el:"#parent",
        data:{
            msg:""
        },
        methods: {
                clickDt(){
                this.$refs.profile.greet(this.msg);
            }
        }
    })
</script>  
</body>
</html>
           
[javascript]

view plain copy print ?

  1. <template>  
  2.     <div>  
  3.     <button v-on:click=”incrementCounter”>count +1</button>  
  4.     <button v-on:click=”showMask”>弹窗</button>  
  5.     <input type=”text” v-model=“msg”>  
  6.     <button v-on:click=’fdsf’>emit parent</button>  
  7.     <p>{{something}}</p>  
  8.     <button v-on:click=”some”>click</button>  
  9.     </div>  
  10. </template>  
  11. <script type=”text/javascript”>  
  12. import { mapGetters, mapActions } from ‘vuex’  
  13. var bus = new   
  14. export default {  
  15.    props:[’parentmsg’],  
  16.    data(){  
  17.     return {  
  18.       msg:’hello’,  
  19.       something:this.parentmsg  
  20.     }  
  21.    },  
  22.    ready(){  
  23.       console.log(window.location)  
  24.    },  
  25.    events:{  
  26.       emitchild(){  
  27.         console.log(’ds0’)  
  28.       }  
  29.    },  
  30.    methods:{  
  31.     …mapActions([  
  32.        ’incrementCounter’,  
  33.        ’showMask’  
  34.     ]),  
  35.     fdsf(){  
  36.       this.emit(</span><span class="string">'clickfn'</span><span>,</span><span class="keyword">this</span><span>.msg);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;some(){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.
  37.     },  
  38.     some(){  
  39.       this.emit(‘childjian’,this.msg)  
  40.     },  
  41.     childdomeing(){  
  42.       console.log(’child99’)  
  43.     },  
  44.     emitchild(){  
  45.         console.log(’ds0’)  
  46.       }  
  47. }  
  48. }  
  49. </script>  
在vue2.0中父组件如何触发子组件的自定义方法?
<template>
    <div>
    <button v-on:click="incrementCounter">count +1</button>
    <button v-on:click="showMask">弹窗</button>
    <input type="text" v-model="msg">
    <button v-on:click='fdsf'>emit parent</button>
    <p>{{something}}</p>
    <button v-on:click="some">click</button>
    </div>
</template>
<script type="text/javascript">
import { mapGetters, mapActions } from 'vuex'
var bus = new 
export default {
   props:['parentmsg'],
   data(){
    return {
      msg:'hello',
      something:this.parentmsg
    }
   },
   ready(){
      console.log(window.location)
   },
   events:{
      emitchild(){
        console.log('ds0')
      }
   },
   methods:{
    ...mapActions([
       'incrementCounter',
       'showMask'
    ]),
    fdsf(){
      this.$emit('clickfn',this.msg);
    },
    some(){
      this.$emit('childjian',this.msg)
    },
    childdomeing(){
      console.log('child99')
    },
    emitchild(){
        console.log('ds0')
      }
}
}
</script>
           

父组件

[javascript]

view plain copy print ?

  1. <template>  
  2.     <div>  
  3.         <Display></Display>  
  4.         <Increment v-bind:parentmsg = ”something” v-on:childjian=“parentjian” v-on:clickfn = “dosomething” v-on:emitchild =“emitchild”></Increment>  
  5.         <show-mask v-if=“showHide”>  
  6.             <show-info></show-info>  
  7.         </show-mask>  
  8.         <button v-on:click=’emitchild(something)’>emit child</button>  
  9.     </div>  
  10. </template>  
  11. <script type=”text/ecmascript-6”>  
  12.     import Display from ‘./Display.vue’;  
  13.     import Increment from ‘./Increment.vue’;  
  14.     import store from ‘../vuex/store’ ;  
  15.     import Mask from ‘./Mask.vue’;  
  16.     import Xinjian from ‘./xinjian.vue’  
  17.     export default{  
  18.         components:{  
  19.             Display:Display,  
  20.             Increment:Increment,  
  21.             showMask:Mask,  
  22.             showInfo:Xinjian  
  23.         },          
  24.         data(){  
  25.             return {  
  26.                something:’hello child’  
  27.             }  
  28.         },  
  29.         computed:{  
  30.             showHide(){  
  31.                 return store.state.showMask;  
  32.             }  
  33.         },  
  34.         store:store,  
  35.         events:{  
  36.         },  
  37.         methods:{  
  38.             parentjian(msg){  
  39.                 console.log(’child click:’+msg)  
  40.             },  
  41.             dosomething(msg){  
  42.                 console.log(10);  
  43.                 if(msg)  
  44.                     console.log(msg)  
  45.                 console.log(this.children)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;emitchild(msg){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(999)&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.
  46.             },  
  47.             emitchild(msg){  
  48.                 console.log(999)  
  49.                 this.emit(‘showMask’,msg);  
  50.             }  
  51.         }  
  52.     }  
  53. </script>  
在vue2.0中父组件如何触发子组件的自定义方法?
<template>
    <div>
        <Display></Display>
        <Increment v-bind:parentmsg = "something" v-on:childjian="parentjian" v-on:clickfn = "dosomething" v-on:emitchild ="emitchild"></Increment>
        <show-mask v-if="showHide">
            <show-info></show-info>
        </show-mask>
        <button v-on:click='emitchild(something)'>emit child</button>
    </div>
</template>
<script type="text/ecmascript-6">
    import Display from './Display.vue';
    import Increment from './Increment.vue';
    import store from '../vuex/store' ;
    import Mask from './Mask.vue';
    import Xinjian from './xinjian.vue'
    export default{
        components:{
            Display:Display,
            Increment:Increment,
            showMask:Mask,
            showInfo:Xinjian
        },        
        data(){
            return {
               something:'hello child'
            }
        },
        computed:{
            showHide(){
                return store.state.showMask;
            }
        },
        store:store,
        events:{

        },
        methods:{
            parentjian(msg){
                console.log('child click:'+msg)
            },
            dosomething(msg){
                console.log(10);
                if(msg)
                    console.log(msg)
                console.log(this.$children)
            },
            emitchild(msg){
                console.log(999)
                this.$emit('showMask',msg);
            }
        }
    }
</script>
           

Vue 2.0 废弃了 broadcast和 dispatch,不过可以用 children访问子组件,或者通过 refs 访问子组件,然后直接调用子组件的方法。

由于 events 实例选项属性已废弃,因此只能通过 created 钩子实现对自定义事件的监听,使用 this. on或者this. one。参见:

https://vuejs.org/v2/guide/mi…

组件中的v-on绑定自定义事件理解

每个 Vue 实例都实现了事件接口(Events interface),即:

使用 

$on(eventName)

 监听事件

使用 

$emit(eventName)

 触发事件

Vue的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是

$on</code>&nbsp;和&nbsp;<code style="font-family:&quot;Source Code Pro&quot;,monospace; padding:2px 4px; font-size:13.3333px; color:rgb(63,63,63); white-space:nowrap">$emit

 不是

addEventListener

 和 

dispatchEvent

 的别名。

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

下面是一个例子: 

在vue2.0中父组件如何触发子组件的自定义方法?

继续阅读