新玩家Vue笔记18

提示:该文章为笔者的个人笔记并不是权威,如有错误,谢谢指出。

 组件间通信

1. 组件间的通信可以通过props属性

父组件传递消息给子组件,父组件通过标签传递数据,如:<Student name = '小爱同学' :age = 18 sex = '男'></Student>,子组件在props配置项中接收数据,如:props: ['name', 'age', 'sex']。

子组件传递消息给父组件,首先父组件先定义一个方法,将该方法通过props配置项传递给子组件,子组件调用该方法,并随之将数据传递回去。

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

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

    export default {
        data() {
            return {
                msg: 'hello',
            }
        },
        name: 'App',
        components: {School},
        methods: {
            // 创建getSchoolName方法,接收数据name
            getSchoolName(name) {
                console.log('@学校名字',name)
            }
        }   
    }
</script>

<style>

</style>
<template>
    <div class="school">
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <button @click="sendSchoolName">点击</button>
    </div>
</template>

<script>
    export default {
        name: 'Student',
        // 接收父组件的getSchoolName方法
        props:['getSchoolName'],
        data() {
            return {
                name: 'lyun',
                address: '福建'
            }
        },
        methods: {
            sendSchoolName(name) {
                // 调用getSchoolName方法,并将this.name传递过去
                this.getSchoolName(this.name)
            }
        }
    }
</script>

<style>

</style>

 2. 组件间的通信通过自定义事件实现

自定义事件主要用于子组件传递数据给父组件。使用场景为A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)

第一种方式:

<template>
    <div class="app">
        <h1>{{msg}} {{studentName}}</h1>
        <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 -->
        <Student @lyun="getStudentName"></Student>
    </div>
</template>

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

    export default {
        data() {
            return {
                msg: 'hello',
                studentName: ''
            }
        },
        name: 'App',
        components: {Student},
        methods: {
            // 该自定义方法的回调
            getStudentName(name) {
                console.log('@学生名字',name)
                this.studentName = name
            }
        } 
    }
</script>

<style>

</style>
<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生性别:{{sex}}</h2>
        <button @click="sendstudentName">点击</button>
        <button @click="unbind">解绑</button>
    </div>
</template>

<script>
    export default {
        name: 'Student',
        data() {
            return {
                name: '小爱同学',
                sex: '女'
            } 
        },
        methods: {
            sendstudentName() {
                // 通过$emit触发Student组件上的lyun事件, 并传递this.name
                this.$emit('lyun',this.name)
            },
            unbind() {
                // 解绑一个自定义事件
                this.$off('lyun')
            }
        }
    }
</script>

<style>

</style>

 第二种方式

<template>
    <div class="app">
        <h1>{{msg}} {{studentName}}</h1

        <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 -->
        <Student ref="student"></Student>
    </div>
</template>

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

    export default {
        data() {
            return {
                msg: 'hello',
                studentName: ''
            }
        },
        name: 'App',
        components: {School,Student},
        methods: {
           /*  getStudentName(name) {
                console.log('@学生名字',name)
                this.studentName = name
            } */
        },
        mounted() {
            // $on绑定自定义事件
            // this.$refs.student.$on('lyun', this.getStudentName)
            this.$refs.student.$on('lyun', (name) => {
                console.log('@学生名字',name)
                this.studentName = name
            })
        },
        
    }
</script>

<style>

</style>

 3. 全局事件总线

一种组件间通信的方式,适用于任意组件间通信。

首先在main.js中安装全局事件总线:

// 引入vue
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false


new Vue({
    el: '#app',
    render: h => h(App),
    // 安装全局事件总线
    beforeCreate() {
        Vue.prototype.$bus = this
    }
})

 使用事件总线:

        (1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

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

<script>
    export default {
        name: 'Student',
        data() {
            return {
                name: 'lyun',
                address: '福建'
            }
        },
        // 该组件想要接收外部组件的数据,绑定hello事件,data为接收外部发送的数据
        mounted() {
            this.$bus.$on('hello', (data) => {
                console.log('我是school组件,收到了name',data)
            })
        }
    }
</script>

<style>

</style>

       (2)发送数据,通过 $bus.$emit触发该事件,并将数据作为参数传递。

<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生姓别:{{sex}}</h2>
        <button @click="sendStudentName">点击传输</button>
    </div>
</template>

<script>
    export default {
        name: 'Student',
        data() {
            return {
                name: '小爱同学',
                sex: '女'
            } 
        },
        methods: {
            sendStudentName() {
                // 触发hello事件,并将this.name数据传送出去
                this.$bus.$emit('hello',this.name)
            }
        }
    }
</script>

<style>

</style>

 4. 消息发布与订阅

借助第三方库pubsub-js实现组件间通信的方式,适用于任意组件间通信。

首先安装pubsub-js库:npm i pubsub-js

        (1)接收数据:

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

<script>
    // 引入第三方库
    import pubsub from 'pubsub-js'
    export default {
        name: 'Student',
        data() {
            return {
                name: 'lyun',
                address: '福建'
            }
        },
        // 订阅消息,该事件名称为hello,接收到msgName,data数据
        // msgName为该事件名称,data为接收到的数据
        mounted() {
            this.pubId = pubsub.subscribe('hello',(msgName, data) => {
                console.log('有人发布了hello消息',msgName, data)
            })
        },
        // 解绑事件
        beforeDestroy() {
            pubsub.unsubscribe(this.pubId)
        }
    }
</script>

<style scoped>

</style>

         (2)发送数据

<template>
    <div class="student">
        <h2>学生姓名:{{name}}</h2>
        <h2>学生姓别:{{sex}}</h2>
        <button @click="sendStudentName">点击传输</button>
    </div>
</template>

<script>
    import pubsub from 'pubsub-js'
    export default {
        name: 'Student',
        data() {
            return {
                name: '小爱同学',
                sex: '女'
            } 
        },
        // 触发hello事件,发送this.name数据
        methods: {
            sendStudentName() {
                pubsub.publish('hello', this.name)
            }
        }
    }
</script>

<style>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值