389 vue非父子之间通讯 ,事件总线 (event bus),$on注册,开关灯案例

十二、非父子之间通讯 ( 组件 ⇒ 组件 ) (重点)

需求 : 组件 jack ===> 恁弄啥哩 ===> 组件 rose

事件总线bus用于管理事件,
vuex用于管理数据状态。
  • 是通过 事件总线 (event bus 公交车) 的机制 来实现的
  • 事件总线 : 实际上就是一个 空Vue实例
  • 可以实现任意两个组件之间的通讯,而不管两个组件到底有什么样的层级关系
  • 看图
  • 示例 :
// 第一步 : 事件总线
var bus = new Vue()

// 第二步 : 发送数据   可在点击事件里 触发事件
// 参数1 : 唯一标识  参数2:参数
bus.$emit('todo', '恁弄啥哩?')

// 第三步 : 监听事件  接收数据  可在 created 里 注册事件 【也可以在methods里注册事件。】
bus.$on('todo', arg => {
  console.log('接收过来的', arg)
})


01-非父子之间的通信.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- 
       需求 : jack 给 rose 发一条消息 : i jump u jump

       非父子之间的通信通过 事件总线 (event bus ) 来实现
       1. 创建事件总线 (bus) : 一个空的vue实例   const bus = new Vue()
       2. 发送数据 触发事件  bus.$emit('jump',XXXX)
       3. 接收数据 注册事件  bus.$on('jump,res => { })
     -->

    <div id="app">
        <div>
            <div>
                <div>
                    <div>
                        <jack></jack>
                    </div>
                </div>
            </div>
        </div>

        <div>
            <div>
                <div>
                    <rose></rose>
                </div>
            </div>
        </div>
    </div>

    <script src="./vue.js"></script>
    <script>
        //1. 事件总线
        const bus = new Vue()

        // jack
        Vue.component('jack', {
            template: `<div @click='send'>jack 组件</div>`,
            methods: {
                send() {
                    console.log('send');
                    //2. 发送数据, 触发事件, 发送 一起 jump 的话
                    // 【代码的执行顺序:先注册,后触发,和传统的DOM操作一样。这个jump事件,只有点击上面的div时,才触发。下面注册的jump,是created阶段就触发。】
                    bus.$emit('jump', 'i jump u jump')
                }
            }
        })

        // rose
        Vue.component('rose', {
            template: `<div>rose 组件</div>`,
            created() {
                //3. 接收数据 注册事件 【代码的执行顺序:先注册,后触发,和传统的DOM操作一样。回调函数只有触发jump事件时才会执行。】
                console.log('on')
                bus.$on('jump', res => {
                    console.log('rose接收到的:', res)
                })
            }
        })

        const vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>

十三、开关灯案例

02-案例:开关灯(模板).html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
        /* 容器 */
        
        .container {
             150px;
        }
        /* 灯 */
        
        .light {
             100px;
            height: 100px;
            border-radius: 50%;
            text-align: center;
            line-height: 100px;
            margin: 0 auto;
            color: #fff;
            background-color: #000;
        }
        /* 开灯 */
        
        .turn-on {
            background-color: #ff0;
            color: #000;
        }
        /* 灯座 */
        
        .bottom {
             150px;
            height: 50px;
            margin-top: 10px;
            line-height: 50px;
            text-align: center;
            color: #fff;
            background-color: #000;
        }
    </style>
</head>

<body>
    <div id="app" class="container">
        <light-head></light-head>
        <light-bottom></light-bottom>
    </div>
    <script src="./vue.js"></script>
    <script>
        //1. 事件总线
        const bus = new Vue()

        // 创建灯泡组件
        Vue.component('light-head', {
            // 通过控制台查看,当isLight为true时, div的class同时有 light、turn-on
            template: `<div class="light" :class="{ 'turn-on' : isLight }">我是一盏灯</div>`,
            data() {
                return {
                    isLight: false
                }
            },
            created() {
                //3. 接收数据 注册事件 【也可以在methods里注册事件。】
                bus.$on('light', res => {
                    console.log(res)
                    this.isLight = res
                })
            }
        })

        // 创建灯座组件
        Vue.component('light-bottom', {
            template: `
                <div class="bottom">
                    <button @click='turnOn'>开</button>
                    <button @click='turnOff'>关</button>
                </div>
            `,
            methods: {
                // 开灯
                turnOn() {
                    // 2. 发送数据  触发事件
                    bus.$emit('light', true)
                },
                // 关灯
                turnOff() {
                    //3. 发送数据 触发事件
                    bus.$emit('light', false)
                }
            }
        })

        var vm = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>
原文地址:https://www.cnblogs.com/jianjie/p/12529472.html