Vue子组件给父组件传递数据之自定义事件

在vue中我们可以通过给父组件绑定自定义事件,然后子组件通过$emit方法去触发该自定义事件来给父组件传递数据,写法:this.$emit('自定义事件名',要传递的数据(可以是多个,中间用逗号隔开)),绑定自定义事件有两种写法,一种是通过<父组件 v-on:自定义事件名="callBack" />的方式来绑定(v-on在组件的实例标签上,所以是给组件的实例对象VueComponent上绑定了自定义事件),还有一种是通过ref属性来获取到组件的实例对象Vuecomponent,写法:<父组件 ref="refName />",refName就是组件的实例对象,然后在methods或mounted等函数中通过this.$refs.refName.on("自定义事件名",callBack)来给父组件绑定自定义事件,ref这种绑定自定义事件的方式比较灵活,可以自由控制绑定自定义事件的时间

具体代码实现如下:

<!-- 父组件 -->    
<template>
 <div class="app">
   <h1>{{ msg }},学生姓名是:{{ studentName }}</h1>

   <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
   <School :getSchoolName="getSchoolName" />

   <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
   <!-- <Student @atguigu="getStudentName" @demo="m1"/> -->

   <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
   <Student ref="student" @click.native="show" />
 </div>
</template>

<script>
import Student from "./components/Student";
import School from "./components/School";

export default {
 name: "App",
 components: { School, Student },
 data() {
   return {
     msg: "你好啊!",
     studentName: "",
  };
},
 methods: {
// 获取学校名称
   getSchoolName(name) {
     console.log("App收到了学校名:", name);
  },
   
   // 获取学生姓名 ---ES6 剩余参数
   getStudentName(name, ...params) {
     console.log("App收到了学生名:", name, params);
     this.studentName = name;
  },
   m1() {
     console.log("demo事件被触发了!");
  },
   show() {
     alert(123);
  },
},
 mounted() {
   this.$refs.student.$on("atguigu", this.getStudentName); //绑定自定义事件
   // this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
},
};
</script>

<style scoped>
.app {
 background-color: gray;
 padding: 5px;
}
</style>

 

<!-- 学校子组件 -->  
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="sendSchoolName">把学校名给App</button>
</div>
</template>

<script>
export default {
name:'School',
props:['getSchoolName'],
data() {
return {
name:'尚硅谷',
address:'北京',
}
},
methods: {
sendSchoolName(){
this.getSchoolName(this.name)
}
},
}
</script>

<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
</style>

 

<!-- 学生子组件 -->
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>当前求和为:{{number}}</h2>
<button @click="add">点我number++</button>
<button @click="sendStudentlName">把学生名给App</button>
<button @click="unbind">解绑atguigu事件</button>
<button @click="death">销毁当前Student组件的实例(vc)</button>
</div>
</template>

<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
number:0
}
},
methods: {
add(){
console.log('add回调被调用了')
this.number++
},
sendStudentlName(){
//触发Student组件实例身上的atguigu事件
this.$emit('atguigu',this.name,666,888,900)
// this.$emit('demo')
// this.$emit('click')
},
unbind(){
this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
},
death(){
this.$destroy() //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
}
},
}
</script>

<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>

当我们使用完自定义事件之后不需要自定义事件的时候可以在合适的时机去解绑自定义事件,具体的写法如下

this.$off('自定义事件名')         //解绑一个自定义事件
this.$off(['自定义事件名','自定义事件名']) //解绑多个自定义事件   ---注:解绑多个自定义事件必须放在数组里面
this.$off() //解绑所有的自定义事件

注意:要是给组件标签上绑定原生事件的话,必须给原生事件后面加上native,不然Vue会解析成自定义事件

列如:@click.native="callBack"

posted @ 2021-12-14 09:56  问某完红  阅读(84)  评论(0编辑  收藏  举报