n1. 组件自定义事件

发布时间 2023-03-29 15:25:37作者: 月豕

组件自定义事件

组件自定义事件是一种组件间通信的方式,适用于:子组件 ===> 父组件

使用

使用场景

A是父组件,B是子组件,B想给A传数据。

1. 使用@或v-on

在这之前,我们是使用通过A给B传递函数类型的props实现B给A传数据。

//父组件
<School :getSchoolName="getSchoolName"></School>

...
 methods: {
    //定义函数接收数据
    getSchoolName(name) {
      this.school.name = name
    },
}

//子组件
<button @click="sendSchoolName">点我存学校名到App</button>

...

props: ['getSchoolName'],
    methods: {
        sendSchoolName() {
                //使用父组件传来的函数发送数据
		 this.getSchoolName(this.name)
        }

现在有了组件自定义事件,我们可以通过在A中给B绑定自定义事件(事件的回调在A中)。注意,是绑定在子组件的实例对象vc上。

//父组件
<Student v-on:getName="getStudentName"></Student>

...

 methods: {
    getStudentName(name) {
      this.student.name = name
    }
  }

//子组件
<button @click="sendStudentName">点我存学生名到App</button>

...

methods: {
        sendStudentName() {
            //触发Student组件实例身上的getName事件
            this.$emit('getName', this.name)
        }
    }

当你只想触发一次事件时用once

<Student @getName.once="getStudentName"></Student>

2. 使用ref

还有一种灵活性比较强的写法,使用ref,这样可以添加定时器等有时间差的条件。

//父组件
<Student ref="student"></Student>

···

methods: {
    getStudentName(name) {
      this.student.name = name
    }
  },
mounted() {
    //利用$on给student绑定一个getName事件
    //当getName事件被触发时,执行回调函数this.getSchoolName
    this.$refs.student.$on('getName', this.getSchoolName)
  }

//子组件
<button @click="sendStudentName">点我存学生名到App</button>

...

methods: {
        sendStudentName() {
            //触发Student组件实例身上的getName事件
            this.$emit('getName', this.name)
        }
    }

当你只想触发一次事件时,可以用$once

 this.$refs.student.$once('getName', this.getSchoolName)

解绑

当事件不再使用时,我们最好解绑。

  1. 解绑一个事件:this.off('事件名')
    • 解绑事件要定义在被绑定事件的组件里。
    //子组件
    <button @click="unbind">点我解绑事件</button>
    
    ...
    
    methods: {
        sendStudentName() {
            //触发Student组件实例身上的getName事件
            this.$emit('getName', this.name)
        }
        //解绑
        unbind() {
            this.$off('getName')
        }
    }
    
  2. 解绑多个事件:this.$off(['事件1', '事件2', ...])
  3. 解绑所有事件:this.$off()
  4. 当组件/父组件被destroy时,自定义事件也会被destory。

注意

  1. 当给组件添加原生DOM事件,例如@click时,会默认被当成是一个自定义事件,需要在子组件定义click事件才能触发。若想使用原生的DOM事件则需要添加修饰符native
    <Student @click.native="方法名"></Student>
    
  2. 通过this.$refs.xxx.$on('事件名',回调函数)绑定自定义事件时,回调函数要么配置在methods里,要么使用箭头函数,否则this的指向会出问题。
//1.
this.$refs.student.$on('getName', this.getStudentName)
//2.
this.$refs.student.$on('getName' (name) => {
this.student.name = name
})