Vue2 框架整理:兄弟组件 及 跨级组件通信

这里写图片描述

除了父子之间通信还有兄弟组件通信或跨级通信等

在Vue2 中,一般都使用一个空的vue实例作为中央事件总栈来处理,
这里的“中央事件总栈”就类似于我们生活中“中介”一样的存在;

比如:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #v1{
            /*display: none;*/
            width:200px;
            margin: 100px;
            border: 2px solid #faf;
        }
    </style>
</head>
<body>

<div id="v1">

    <v-component></v-component>

    <p>{{ val }}</p>

</div>

<script src="vue.min.js"></script>

<script>

    //先在这里创建一个空的vue实例
    var bus=new Vue({});

    //定义全局组件
    Vue.component("v-component",{
        template:'<button @click="postData">传输数据</button>',
        methods:{
            postData:function () {
                bus.$emit('message','通过组件传递的数据');
            }
        }
    });

    //最后创建实例app
    var app=new Vue({
        el:"#v1",
        data:{
            val:''
        },
//这里使用生命周期的钩子mounted,在这里可以监听到来自中央事件总栈的信息,通过组件中的按钮发布事件,
//app收到后在回调里完成对应的业务逻辑
        mounted:function () {  
            var that=this;
            //监听来自bus实例的事件
            bus.$on('message',function (msg) {
                that.val=msg;
            })
        }

    })
</script>

</body>
</html>

实现效果:

这里写图片描述


除了中央事件总栈外,还可以通过 父链子组件索引 来完成通信:

父链:

在子组件中,用this.$parent可以直接访问该组件的父实例及组件
在父组件中,用this.$children访问其所有的子组件,并且是可以无限向上或向下递归访问,直到“根实例”或“最内层组件”


<body>

<div id="v1">

    <v-component></v-component>

    <p>{{ val }}</p>

</div>

<script src="vue.min.js"></script>

<script>
    Vue.component("v-component",{
        template:'<button @click="postData">通过父链修改数据</button>',
        methods:{
            postData:function () {
                this.$parent.val='通过组件传递的数据';
            }
        }
    });

    //最后创建实例app
    var app=new Vue({
        el:"#v1",
        data:{
            val:''
        }
    })
</script>

</body>

其实在项目中,一般尽量不要用子组件主动修改父组件的数据,理想情况下,只有组件自己能修改自己的状态,父子还是推荐 $emit 和 props来通信最好;


子组件索引

当子组件较多时,建议使用vue提供的子组件索引,用特殊的属性ref 为子组件指定一个索引名称。
在父组件模板中,子组件标签上使用ref指定一个名称,并在父组件内通过this.$refs访问指定名称的子组件。
例如:


<body>

<div id="v1">

    <button @click="setRef">获取子组件内容</button>

    <v-component ref="comA"></v-component>

    <p>{{ val }}</p>

</div>

<script src="vue.min.js"></script>

<script>

    Vue.component("v-component",{
        template:'<p>我是子组件</p>',
        data:function () {
            return {
                msg:"我的内容"
            }
        }
    });

    var app=new Vue({
        el:"#v1",
        data:{
            val:""
        },
        methods:{
            setRef:function () {
                var i=this.$refs.comA.msg;

                this.val=i;
            }
        }
    })
</script>

</body>

显示效果:
这里写图片描述

需要注意的是: $refs只在组件渲染完成后才填充,不是响应式,尽量不要在计算属性中使用

猜你喜欢

转载自blog.csdn.net/freedomVenly/article/details/80876531