组件的自定义事件①

导读:本篇文章讲解 组件的自定义事件①,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

也许你感觉自己的努力总是徒劳无功,但不必怀疑,你每天都离顶点更进一步。今天的你离顶点还遥遥无期。但你通过今天的努力,积蓄了明天勇攀高峰的力量。加油!

文章目录

案例引入

我们前面在TodoList经典案例中提到过,如果父组件要向子组件传递数据,我们可以使用props。而如果子组件要向父组件传递数据,我们可以先在父组件中定义好方法,使用props传递给子组件,然后让子组件去调用它。

现在我们多了一种子组件向父组件传递数据的方法,那就是自定义事件

现在我们完成一个小案例,分别使用两种不同的方式,将子组件中的数据传递给父组件
在这里插入图片描述
首先我们使用props的方法完成学校名称的传递,代码实现如下:

App组件:

<template>
    <div>
        <h2 ref="title" >欢迎来到{{n}}</h2>
        <hr>
        <SchoolName :getSchoolName="getSchoolName"></SchoolName>
        <StudentName ></StudentName>

    </div>
</template>

<script>

        import SchoolName from "@/components/School";
        import StudentName from "@/components/Student";
        export default {
            components:{
                SchoolName,
                StudentName
            },
            data(){
                return {
                    n:'CSDN'
                }
            },
            methods:{
                getSchoolName(name){
                    console.log('App组件已经收到了学校的名字:',name)
                }
            }
    }
</script>

<style>

</style>

School组件:

<template>
        <div class="demo">
            <h2>学校名称:{{name}}</h2>
            <h2>学校地址:{{address}}</h2>
            <button @click="getSchoolName(name)">点击将学校名称交给父组件App</button>
            <hr>            
        </div>
</template>

<script>

    export default {
        name:'DongBei',
        data(){
            return {
                name:'NEFU',
                address:'哈尔滨',
            }
        },
        props:['getSchoolName'],
    }
</script>

<style >
    .demo {
        background-color: yellow;
    }
</style>

然后我们使用组件的自定义事件来完成学生名称数据的传递
①首先我们使用v-on指令给student组件身上绑定事件(准确点说是给student组件的实例对象vc上绑定了事件)。事件的名字我们随便取,这里我使用stuName。

②然后我们完善一下回调函数:

<template>
    <div>
        <h2 ref="title" >欢迎来到{{n}}</h2>
        <hr>
        <SchoolName :getSchoolName="getSchoolName"></SchoolName>
        <StudentName v-on:stuName="getStudentName"></StudentName>

    </div>
</template>

<script>

        import SchoolName from "@/components/School";
        import StudentName from "@/components/Student";
        export default {
            components:{
                SchoolName,
                StudentName
            },
            data(){
                return {
                    n:'CSDN'
                }
            },
            methods:{
                getSchoolName(name){
                    console.log('App组件已经收到了学校的名字:',name)
                },
                getStudentName(name){
                    console.log('App组件已经收到了学生的名字:',name)
                }
            }


    }


</script>

③完成了这些我们很自然地就可以想到,我们如何去触发我们的自定义事件呢?因为我们的自定义事件绑定在了Student组件的实例对象上,那么我们就在Student的实例对象上去对他进行触发。

这里我们就要使用到事件触发语句$emit(eventName)来触发事件,括号中还可以紧跟一个参数用来给事件回调函数传参:

Student组件

<template>
    <div class="demo">
        <h2 class="stu" >学生名称:{{name}}</h2>
        <h2 >学生年纪:{{age}}</h2>
        <button @click="studentNameGetter(name)">点击将学生名称交给父组件App</button>
    </div>
</template>

<script>

    export default {
        name:'MyStudent',
        data(){
            return {
                name:'张三',
                age:18
            }
        },
        methods:{
            studentNameGetter(name){
                // 触发Student组件实例身上的stuName事件
                this.$emit('stuName',name)
            }
        }
    }

</script>

这里有一个易错点:触发事件的名字不要写成事件回调函数的名字!

注意点:

  • 绑定的时候我们也可以使用简写形式
    在这里插入图片描述
  • 绑定的时候我们开可以使用$on(eventName)。这个方法可以可以传入两个参数:第一个是绑定的事件名称,第二个是事件的回调函数。

例如:

我i们可以先试用ref获得Student组件的实例对象,再在这个实例对象上绑定事件。

<template>
    <div>
        <h2 ref="title" >欢迎来到{{n}}</h2>
        <hr>
        <SchoolName :getSchoolName="getSchoolName"></SchoolName>
        <StudentName ref="Student"></StudentName>
<!--        <StudentName v-on:stuName="getStudentName"></StudentName>-->
<!--        <StudentName @stuName="getStudentName"></StudentName>-->

    </div>
</template>

<script>

        import SchoolName from "@/components/School";
        import StudentName from "@/components/Student";
        export default {
            components:{
                SchoolName,
                StudentName
            },
            data(){
                return {
                    n:'CSDN'
                }
            },
            methods:{
                getSchoolName(name){
                    console.log('App组件已经收到了学校的名字:',name)
                },
                getStudentName(name){
                    console.log('App组件已经收到了学生的名字:',name)
                }
            },
            mounted() {
                this.$refs.Student.$on('stuName',this.getStudentName)
            }


        }

</script>

这种绑定方式的存在意义就是他的灵活型很强,我们可以举个例子来体会。

前两种方式进行事件绑定他都是瞬间绑定完成。但是如果现在有一个需求是等几秒钟再绑定(例如等Ajax请求发送完毕回来我们再绑定自定义事件),我们使用前两种方式是完成不了的,此时只能使用上述的方式。

例如现在我们向让它等3秒钟再绑定事件:

<template>
    <div>
        <h2 ref="title" >欢迎来到{{n}}</h2>
        <hr>
        <SchoolName :getSchoolName="getSchoolName"></SchoolName>
        <StudentName ref="Student"></StudentName>
<!--        <StudentName v-on:stuName="getStudentName"></StudentName>-->
<!--        <StudentName @stuName="getStudentName"></StudentName>-->

    </div>
</template>

<script>

        import SchoolName from "@/components/School";
        import StudentName from "@/components/Student";
        export default {
            components:{
                SchoolName,
                StudentName
            },
            data(){
                return {
                    n:'CSDN'
                }
            },
            methods:{
                getSchoolName(name){
                    console.log('App组件已经收到了学校的名字:',name)
                },
                getStudentName(name){
                    console.log('App组件已经收到了学生的名字:',name)
                }
            },
            mounted() {
                setTimeout(() => {
                    this.$refs.Student.$on('stuName',this.getStudentName)
                },3000)
            }
        }
</script>

如果我们想要这个事件只能触发一次:

  • 若使用的是第一种绑定方式,直接使用事件修饰符即可
    在这里插入图片描述

  • 若使用的是第二种绑定方式,则调用另外的Api
    在这里插入图片描述

如果要传递多个数据,有两种方法:

  • 直接传一个对象过去
  • 使用ES6的…params语法

小总结

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122113.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!