vue学习【非父子组件传值问题(Bus/总线/观察者模式)】

如果两个组件是父子关系,就可以通过props的方式传值。
父组件通过props向子组件传值,子组件通过事件触发向父组件传值

那么如果两个组件之间不具备父子关系,该如何传值呢?任何一个网页都可以拆分成几个部分,或者是几个组件,like this:1和3,3和3组件传值应该怎么传呢?

一个网页可以拆分成这么多个组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>非父子组件传值问题(Bus/总线/观察者模式)</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<!--父组件通过props向子组件传值,子组件通过事件触发向父组件传值-->
<body>
<div id="app">
    <child content="Dell"></child>
    <child content="Lee"></child>
</div>
</body>
</html>
<script>
    // 每一个由Vue实例创建的组件都有bus
    Vue.prototype.bus = new Vue()
    // 子组件不能修改父组件的值,所以再定义一个变量承接父组件传来的content
    Vue.component('Child', {
        data: function () {
            return {
                selfContent: this.content
            }
        },
        props: {
            content: String
        },
        template: '<div @click="handleClick">{{selfContent}}</div>',
        methods: {
            handleClick: function () {
                alert('click:' + this.selfContent)
                this.bus.$emit('change', this.selfContent)
            }
        },
        // 监听bus的改变,组件被挂载时
        mounted: function () {
            var _this = this;
            this.bus.$on('change', function (msg) {
                alert('bus:' + msg)
                _this.selfContent = msg
            })
        }
    })
    var vm = new Vue({
        el: '#app'
    })
</script>

发布订阅模式【总线机制】
······这个例子是,点击Dell,将Dell传给下面的子组件,点击Lee,将Lee传给上面的子组件,实现非父子组件之间的传值。
······在子组件中定义一个点击事件,在点击事件的方法中用bus发出change事件,并将父组件传来的值传入。此时,通过vue的生命周期钩子mounted来监听change事件并且传值
······我在handle click方法和mounted方法中都写了alert,点击Dell之后,会弹出三个提示框,分别是click:Dell、bus:Dell、bus:Dell,在弹出第三个提示框之后,Lee变成了Dell。这是什么意思呢?首先,点击Dell会触发handle click方法,alert(click:Dell),然后由bus发出change事件,并且携带了content值(也就是Dell)。然后mounted中的bus.$on监听到change事件,会发出alert(bus Dell),因为页面的两个组件都有bus,所以,会发出两次alert,每一次alert之后都有一句_this.selfContent = msg,所以就会把msg携带的Dell覆盖掉原来的self_content。That’s all.

需要回顾的知识就是mounted,mounted只会执行一次,在html已经渲染到页面之后,也就是组件都挂载完成之后,会执行一次mounted中定义的事件,一半执行的是Ajax操作。

猜你喜欢

转载自blog.csdn.net/qq_33866063/article/details/89668341