组件的自定义事件-区别于js事件的内置事件
总结
-
一种组件间通信的方式,适用于:子组件 ==> 父组件
-
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
-
绑定自定义事件:
-
第一种方式,在父组件中:
<Demo @sztu="test"/>
或<Demo v-on:sztu="test"/>
-
第二种方式,在父组件中:
-
若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法
-
<Demo ref="demo"/>
...
mounted(){
this.$refs.demo.$on('sztu',this.getName)//回调函数在父组件上
}
-
触发自定义事件:在子组件中
this.$emit('sztu',数据)
-
解绑自定义事件:
this.$off('sztu')
-
组件上也可以绑定原生DOM事件,需要使用
native
修饰符 -
注意:通过
this.$refs.xxx.$on('atguigu',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!
绑定
功能:School/Student组件
中有一个按钮,点击按钮就会把学校名/学生名交给App组件
本质:子组件给父组件传递数据
- 运用
props
,父组件提前给子组件一个函数,子组件调用该函数。
App
组件
<!-- 通过 父组件 给 子组件 传递函数类型的props 实现:子给父传递数据 -->
<School :getSchoolName="getSchoolName"/>
传递给子组件的函数
getSchoolName(name){
console.log("已收到学校的名称:"+name)
},
Student
组件
声明接收
props:['getSchoolName'],
添加一个点击事件
<button @click="sendSchoolName">把学校名给App</button>
点击事件函数-调用父组件传递过来的函数
sendSchoolName(){
this.getSchoolName(this.name)
}
- v-on 给 Student组件 的实例对象vc上绑定事件,事件名称是sztu ,事件被触发则调用getStudentName函数。
由于v-on
在Student组件
标签上,所以说是给Student组件
的实例对象vc
身上绑定了一个事件,事件名字是sztu
,如果有人触发了这个事件,那么getStudentName
函数就会被调用,
App
组件
<!-- 通过 父组件 给 子组件 绑定一个自定义事件实现子给父传递数据(第一种写法:使用@或v-on) -->
<Student v-on:sztu="getStudentName"/>
<Student @sztu.once="getStudentName"/><!-- 仅一次 -->
配置一个getStudentName
函数
getStudentName(name){
console.log("已收到学生的姓名:"+name)
},
如何触发事件?给谁绑的找谁触发。
Student
组件
添加一个点击事件
<button @click="sendStudentName">点我传递学生姓名</button>
触发sztu事件——绑定在Student
组件的实例对象vc
身上
sendStudentName(){
// 触发 Student 组件 实例上的 sztu事件,将学生的名字
this.$emit('sztu',this.name)
}
3.元素绑定ref之后,直接通过this.$refs即可调用.(灵活性强)
App
组件
<!-- 通过 父组件 给 子组件 绑定一个自定义事件 实现子给父传递数据(第二种写法:使用ref) -->
<Student ref="student"/>
this.$refs.student
选中Student
组件的实例对象,$on
当sztu
事件执行回调sendStudentName
//App组件挂载完毕
mounted(){
setTimeout(()=>{
this.$refs.student.$on('sztu',this.getStudentName)//绑定自定义事件
},3000)//需要3s
this.$refs.student.$once('sztu',this.getStudentName)//绑定自定义事件(一次)
}
传不止一个数据
Student
组件
sendStudentName(){
// this.$emit('jojo',this.name)
// 触发 Student 组件 实例上的atguigu事件
this.$emit('sztu',this.name,666,888,999)
}
App
组件
getStudentName(name,x,y,z){
console.log("已收到学生的姓名:",name,x,y,z)
},//一般不那么做,通常 1.将数据打包成对象 2.ES6知识
getStudentName(name,...params){
console.log('已收到学生的姓名',params)
},
效果
将除name
后的其他数据打包成数组params
解绑
Student
组件
<button @click="unbind">解绑sztu事件</button>
<button @click="death">销毁当前Student组件的实例</button>
unbind(){
this.$off('sztu'),
this.$off(['sztu','demo'])//解绑多个自定义事件
this.$off()//解绑所有的自定义事件
}
death(){
this.$destroy()//销毁了当前Student组件的实例
//销毁后, 所有Student组件实例的自定义事件全都不奏效了 及 Student组件的子组件都被销毁了
}
将接收到学生名字展示到页面上
App
组件
<h1>{{ msg }},{{studentname}}</h1>
data(){
return {
msg:'你好啊',
studentname:''
}
},
methods:{
getStudentName(name,...params){
console.log('已收到学生的姓名',params)
this.studentname=name
},
},
效果: