笔记

自定义事件:区别于内置事件(E.g click keyup)而言。
例如:我们给组件自定义一个事件 peiqi
本节将的自定义事件 是服务于 组件的!

源码

App.vue

<template>
    <div class="app">
        <h1>{{ msg }}</h1>
        <!-- 通过父组件给子组件 传递函数类型的props 实现: 子给父传递数据 -->
        <School :getSchoolName="getSchoolName"/>

        <!-- 记住: v-on在谁身上,就是给谁在绑定事件。
        笼统说:给 Student组件,绑定了一个事件 atguigu。
        仔细说:由于 v-on 在 Student组件标签上,所以说是给student组件这个实例对象vc身上绑定了一个事件,事件名叫 atguigu 。
                如果以后有人触发atguigu事件,那么demo()函数就会被调用。
        -->
        <!-- 通过父组件给子组件 绑定一个自定义事件 实现: 子给父传递数据 
        <Student v-on:atguigu="getStudentName"/>
        -->
        <!-- 另外一种方法:  好处是比较灵活。 例如:想让App挂载之后,等5s再给Student组件实例,绑定自定义事件的话,上面一行的方法就无法实现,就需要下面一行的方法实现。
        通过 this.$refs.student 拿到 Student组件 的 实例对象 
        -->
        <Student ref="student"/>
    </div>
</template>

<script>
    import Student from './components/Student'
    import School from './components/School'

    export default {
        name:'App',
        components:{
            School,
            Student
        },

        data(){
            return {
                msg:'你好啊!'
            }
        },

        methods:{
            getSchoolName(name){
                console.log('App收到了学校名:', name)
            },

            getStudentName(name){
                console.log('App收到了学生名.', name)
            }
        },

        //配合 ref
        //App挂载完毕进入该函数
        mounted(){
            //.$on() 当 'atguigu' 事件被触发的时候,调用 getStudentName()函数
            //this.$refs.student.$on('atguigu', this.getStudentName)

            //实验:让 App 挂载之后,等5s再绑定。 效果:刚打开页面,点击 学生 按钮,一开始就没有反应,等5s之后才能看到效果。
            setTimeout(()=>{
                this.$refs.student.$on('atguigu', this.getStudentName)
            }, 5000)

            //如果只想 触发一次,那么就使用.once():
            //this.$refs.student.$once('atguigu', this.getStudentName)

        }
    }
</script>

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

components\School.vue

<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>


        <button @click="sndSchoolName">把学校名给App</button>
    </div>
</template>

<script>
    export default {
        name:'SchoolVue',

        props:['getSchoolName'],

        data() {
            return {
                name:'尚硅谷',
                address:'北京',
            }
        },

        methods:{
            sndSchoolName(){
                this.getSchoolName(this.name)
            }
        }
    }
</script>


<!-- 我们在 vue组件中写的样式,最终都被汇总在一起。此时容易出现一个问题:样式名冲突。 为了解决这个问题: 添加 scoped,表示其中的样式只负责本组件 -->
<style scoped>
    .school{
        background-color: skyblue;

        padding: 5px;
    }
</style>

components\Student.vue

<template>
    <div class="student">
        <h2 >学生姓名:{{name}}</h2>
        <h2 >学生性别:{{sex}}</h2>


        <button @click="sndStudentName">把学生名给App</button>
    </div>
</template>

<script>
    export default {
        name:'StudentVue',
        data() {
            return {
                name:'张三',
                sex:'男'
            }
        },

        methods:{
            sndStudentName(){
                //借助 $emit 触发 student组件身上的 atguigu事件
                this.$emit('atguigu', this.name)
            }
        }
    }
</script>

 <style scoped>
    .student{
        background-color: pink;

        padding: 15px;

        margin-top: 30px;
    }
</style>