<template>
<div class="app">
<h1>初中时你把书堆得高高,以为是挡住了老师,其实是挡住了自己的美好未来
{{msg}}
姓名是:{{studentName}}
</h1>
<!-- 通过父组件给子组件传递函数类型的props实现: 子给父传递数据 -->
<MySchool
:getSchoolName="getSchoolName"
/>
<!-- 共同点都需要配置回调 -->
<!-- 通过父组件给子组件绑定一个自定义事件实现: 子给父传递数据 第一种写法v-on @ v-on:qinling.once = 'getStudentName'-->
<Student
v-on:qinling = 'getStudentName'
/>
<!-- @click.native="show" v3已弃用 -->
<!-- v-on在谁身上就是在给谁绑定事件 -->
<!-- 细说:由于v-on在Student组件标签上,所以说是给Student的组件实例对象VC身上绑定了一个事件,
事件名叫qinling,如果以后有人触发了这个事件,那么getStudentName函数就会被调用。
触发原则: 给谁绑定的事件,就找谁触发事件。
-->
<!-- 通过父组件给子组件绑定一个自定义事件实现: 子给父传递数据 第二种写法 ref -->
<!-- <Student
ref="student"
/> -->
<!--通过APP组件VC this.$refs.student 可以获取到student组件的实例对象。 -->
组件的自定义事件:
1. 一种组件间通信的方式, 适用于: 子组件 ===> 父组件
2. 适用场景: A是父组件, B是子组件, B想给A传数据, 那么就要在A中给B绑定自定义事件(事件的回调在A中)
3. 绑定自定义事件:
1. 第一种方式, 在父组件中: <Demo @qinling="text" /> 或 <Demo v-on:qinling="test" />
2. 第二种方式, 在父组件中: <Demo ref="demo" /> mounted() {this.$refs.xxx.$on('atguigu',this,test)}
3. 若想让自定义事件子能触发一次, 可以使用once修饰符 或 $once方法
4. 触发自定义事件: this.$emit('qinling',数据)
5. 解绑自定义事件: this.$off('qinling')
6. 组件上也可以绑定原生DOM事件,需要使用native修饰符
7. 注意: 通过this$refs.xxx.$on('qinling',回调)绑定自定义事件时,回调要么配置在methods中,
要么用箭头函数,否则this指向会出现问题
</div>
</template>
<script>
// 引入school组件
import Student from './components/Student.vue'
import MySchool from './components/School.vue'
export default {
name: 'App',
components: {
Student,
MySchool
},
data() {
return {
msg: '你好啊!我不好。',
studentName:'',
}
},
mounted () {
// 只要APP 挂载完毕
// this.$refs.student.$on('qinling',this.getStudentName) vue3移除$on()方法 绑定自定义事件
// setTimeout(() => {
// this.$refs.student.$once('qinling',this.getStudentName) vue3移除$on()方法 绑定自定义事件 一次性 once
// }, 3000);
},
methods :{
getSchoolName (name) {
console.log('app收到了学校名:', name)
},
getStudentName (name,...params) {
console.log('app收到了学生名', name,params)
this.studentName = name
},
// show () {
// alert('v-on指令上的.native修饰符已弃用')
// }
},
}
</script>
<style >
.app{
background-color: gray;
padding: 5px;
}
</style>
-------------------------------------------------------------------------------------
<template>
<div class="demo">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{ address }}</h2>
<button @click="sendSchoolNameToApp">把组件学校名给父组件APP</button>
</div>
</template>
<script>
export default {
name:'MySchool',
props: ['getSchoolName'],
data() {
return {
name:'越焦虑越无从下手',
address:'大连',
}
},
methods:{
sendSchoolNameToApp () {
this.getSchoolName(this.name)
}
}
}
</script>
<style scoped>
.demo {
background-color: skyblue;
padding: 5px;
}
</style>
--------------------------------------------------------------------------------------
<template>
<div class="demo">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="sendStudentNameToApp">把组件中学生名给父组件APP</button>
<button v-on="unbind">解绑qinling自定义事件</button>
</div>
</template>
<script>
export default {
name:'MyStudent',
props: {
},
data() {
return {
name:'张三',
sex:'男',
}
},
methods:{
sendStudentNameToApp () {
// 触发Student组件实例身上的atguigu事件
this.$emit('qinling',this.name,12180,12177,12239,11708)
},
// 解绑
unbind () {
// vue3 api ' $on ', ' $off ' ' $once '已弃用。使用外部库
// this.$off('qinling') // 解绑一个自定义事件
// this.$off(['qinling','demo']) // 解绑多个自定事件
// this.$off() // 解绑所有自定事件
}
}
}
</script>
<style scoped>
.demo {
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>