vue的非父子组件的传值详细解析

在这里插入图片描述
首先我们看一张图 图上
在这里插入图片描述
看上图 我们应该如何做
在这里插入图片描述
是不是感觉很麻烦?

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child></child>
        <child></child>
    </div>

    <script>
        Vue.component('child', {
            template: '<idv>child</div>'
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

我们可以通过一些特定的模式 来搞定.

步骤1

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child content="Dell"></child>
        <child content="Lee"></child>
    </div>

    <script>
        Vue.component('child', {
            props: {
                content: String
            },
            template: '<idv>{{content}}</div>'
        })

        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

步骤2

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child content="Dell"></child>
        <child content="Lee"></child>
    </div>

    <script>
        Vue.prototype.bus = new Vue()

        Vue.component('child', {
            props: {
                content: String
            },
            template: '<div @click="handleClick">{{content}}</div>',
            methods: {
                handleClick: function() {
                    alert(this.content)
                }
            }
        })


        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

运行效果图
在这里插入图片描述
接下来 我 要把我的值传给另一个组件应该怎么做
首先我们看

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child content="Dell"></child>
        <child content="Lee"></child>
    </div>

    <script>
        Vue.prototype.bus = new Vue()

        Vue.component('child', {
            props: {
                content: String
            },
            template: '<div @click="handleClick">{{content}}</div>',
            methods: {
                handleClick: function() {
                        this.bus.$emit('change', this.content)
                    }
                    // 这个组件触发其他的组件 要进行监听
            },
            mounted: function() {
                // 这样就可以监听事件
                this.bus.$on('change', function(msg) {
                    alert(msg)
                })

            }
        })


        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

但是为什么运行的时候 会触发两次呢
在这里插入图片描述
因为child组件 都进行了同一事件的监听
在这里插入图片描述
然后我们运行代码
在这里插入图片描述
原因是function里的作用域发生了变化
在这里插入图片描述

所以我们需要保存一下this作用域

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child content="Dell"></child>
        <child content="Lee"></child>
    </div>

    <script>
        Vue.prototype.bus = new Vue()

        Vue.component('child', {
            props: {
                content: String
            },
            template: '<div @click="handleClick">{{content}}</div>',
            methods: {
                handleClick: function() {
                        this.bus.$emit('change', this.content)
                    }
                    // 这个组件触发其他的组件 要进行监听
            },
            mounted: function() {
                // 所以我们需要对作用域this做一个保存
                var this_ = this
                    // 这样就可以监听事件
                this.bus.$on('change', function(msg) {
                    this_.content = msg
                })

            }
        })


        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

这样我们就可以实现组件间的传值了
但是依然会有问题
在这里插入图片描述
因为vue有单向数据流的概念 所以 子组件 不能向父组件 传值. 所以会报错.

解决方案:我们可以通过拷贝content 然后通过data函数进行返回
这样的话 我们就不会对父组件进行改变 自然不会报错了

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

<head>
    <meta charset="UTF-8">
    <title>非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)</title>
    <script src='./vue.js'></script>
</head>

<body>

    <div id="root">
        <child content="Dell"></child>
        <child content="Lee"></child>
    </div>

    <script>
        Vue.prototype.bus = new Vue()

        Vue.component('child', {
            data: function() {
                return {
                    selfContent: this.content
                }
            },
            props: {
                content: String
            },
            template: '<div @click="handleClick">{{selfContent}}</div>',
            methods: {
                handleClick: function() {
                        this.bus.$emit('change', this.selfContent)
                    }
                    // 这个组件触发其他的组件 要进行监听
            },
            mounted: function() {
                // 所以我们需要对作用域this做一个保存
                var this_ = this
                    // 这样就可以监听事件
                this.bus.$on('change', function(msg) {
                    this_.selfContent = msg
                })

            }
        })


        var vm = new Vue({
            el: '#root'
        })
    </script>

</body>

</html>

但是以后遇到非父子组件传值的问题 都可以通过bus进行解决

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值