• 组件的自定义事件①


    文章目录

    案例引入

    我们前面在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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    然后我们使用组件的自定义事件来完成学生名称数据的传递
    ①首先我们使用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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    ③完成了这些我们很自然地就可以想到,我们如何去触发我们的自定义事件呢?因为我们的自定义事件绑定在了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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

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

    注意点:

    • 绑定的时候我们也可以使用简写形式
      在这里插入图片描述
    • 绑定的时候我们开可以使用$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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

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

    前两种方式进行事件绑定他都是瞬间绑定完成。但是如果现在有一个需求是等几秒钟再绑定(例如等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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

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

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

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

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

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

    小总结

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

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

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

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

  • 相关阅读:
    Educational Codeforces Round 155 (Rated for Div. 2)
    神经网络(六)循环神经网络
    【微信小程序】三分钟学会小程序的列表渲染
    【k8s】Kubernetes 原理剖析与实战应用(更新中)
    监控摄像头连接NAS,实现监控管理一体化
    EnumWindowsProc
    LVS集群
    uniapp 登录功能实现
    接口自动化之测试数据动态生成并替换
    贝叶斯网络详解
  • 原文地址:https://blog.csdn.net/zyb18507175502/article/details/125541629