组件的自定义事件②

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

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

事件的解绑

首先声明事件的解绑他不是必须的,但他一定是推荐的。这就跟定时器的关闭一样,我们只要开启就应该选择一个合适的时机关掉,但是你不关,就等着用户关网页,也是可以的。

我们在上一篇的基础上对事件进行解绑。

解绑使用的语法:$off(事件名)

注意:在哪里绑定的,就在哪里解绑

代码实现如下:

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

<script>

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

</script>

但是如上的方法只能解绑一个自定义事件,如果我们有多个自定义事件需要解绑,则在上面的方法中传入一个数组即可:

$off(['事件1',‘事件2’,......])

Tips:
$off()
如果什么都不传,则会把这个组件实例身上所有的自定义事件全部解绑

要点回顾:
在这里插入图片描述
在销毁vm执行了$destroy()之后,会关闭所有的监听器,子组件,以及事件监听器。这时原生的DOM事件可以使用,因为他拆掉的是自定义事件的事件监听器。

两个注意点

$on()方法中this的指向问题

App组件

<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>

在$on()方法中第二个参数我们既然传入的是一个函数,那么我们能不能直接将函数定义在on方法中,而不是在methods中定义呢?

App组件:

<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',function (name) {
                        console.log(this)
                        console.log('App组件已经收到了学生的名字:',name)
                    })
            }
        }
</script>

在这里插入图片描述

在这里插入图片描述

我们发现this的指向并不是App

注意:谁触发了这个事件,此时$on()方法中this指向就是谁

这种情况造成的影响就是如果我们想要把从子组件传递过来的数据挂载到当前父组件的身上的时候,会发现挂载不上,因为此时this的指向已经不是这个父组件了

那么我们怎么解决这个问题呢?两种方法:

  • 像以前一样,中规中矩的把回调方法写在methods中
  • 将$on()方法中传入的回调方法写成箭头函数。因为箭头函数没有自己的this,于是就向外寻找,而mounted()函数中的this已经被维护成了当前组件,也就是App,所以是可行的。

代码如下:

<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',(name) => {
                        console.log(this)
                        console.log('App组件已经收到了学生的名字:',name)
                    })
            }
        }
</script>

此时的this就是App组件了:
在这里插入图片描述

绑定误解

我们在给组件绑定一些原生的DOM事件的时候,会发现不能被触发,这是因为Vue会把一切在组件上绑定的事件当作自定义事件。

在这里插入图片描述
那么我们怎么解决这个问题呢?使用.native事件修饰符即可:
在这里插入图片描述
如此这个事件才会被当作原生的DOM事件去解析。

他的底层是把click事件交给了Student组件的最外层元素。

Student组件:
在这里插入图片描述

也就是这个大的div。

此处也从侧面印证了一个事实:组件的template里面只能有一个根元素!
如果有多个的话,此时你的click事件应该给谁呢?(当然这只是其中一个印证方向)

组件的自定义事件总结

组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:<Demo @eventName="test"/><Demo v-on:eventName="test"/>

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('eventName',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('eventName',数据)

  5. 解绑自定义事件this.$off('eventName')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('eventName',回调)绑定自定义事件时,回调要么配置在methods中要么用箭头函数,否则this指向会出问题!

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

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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

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