vue中各种关系组件通信方式(非常齐全)

一、父子通信:

1、props(组件传参)

从父到子,用props属性绑定(通过props向子组件传递数据)。

注意:props静态传入的都是字符,不管里面写的是Number、Boolean、Array还是Object类型,如果想传入除字符之外的类型,就需要动态传入。

实例一:

<div id="app">
    <alert msg="hhhhhhh"></alert>
</div>
Vue.component('alert', {
    template: '<button @click="on_click">点击</button>',
    props: ['msg'],
    methods: {
        on_click: function(){
            alert(this.msg);
        }
    }
})

new Vue({
    el: '#app'
})

实例二:

<div id="app">
    <user username="samve"></user>
</div>
Vue.component('user', {
    template: `
        <a :href="'user/' + username">{{username}}</a>
    `,
    props: ['username']
})

new Vue({
    el: '#app'
})

Prop 验证:

<div id="app">
    <my-component
        :num="100"
        :msg="'sdf'"
        :cust="8"
    ></my-component>
</div>
Vue.component('my-component', {
    props: {
        num: Number,
        propB: [String, Number],
        msg: {
            type: String,
            require: true
        },
        num1: {
            type: Number,
            default: 1000
        },
        object: {
            type: Object,
            default: function(){//对象必须以这种方式返回
                return {
                    message: 'hello'
                }
            }
        },
        list: function(){//对象必须以这种方式返回
            return ['第1项', '第2项', '第3项'];
        },
        cust: {
            validator: function(value){
                return value>10
            }
        }
    },
    template: `<div>
        <p>{{num}}</p>
        <p>{{msg}}</p>
        <p>{{num1}}</p>
        <p>{{object}}</p>
        <p>{{cust}}</p>
    </div>`
});

new Vue({
    el: '#app'
})

这里都是通过验证了的,能够全部输出来,而且控制台没有报错。
如果有不符合的,控制台会报错。

2、特性$attrs

只读

详细:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

// parent
<Helloworld foo="foo"/>

// child,并未在props中申明foo
<p>{{$attrs.foo}}</p>

3、引用refs

// parent
<Helloworld ref="foo"/>

mounted(){
    this.$ref.foo.xx="xxx";
}

4、子元素$children

只读

详细:当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。

this.$children[0].xx="xxx"

二、子父组件通信:从子组件向上传递数据

<div id="app">
    <parent-comp1></parent-comp1>
    <parent-comp1></parent-comp1>
</div>
Vue.component('child-comp1', {
    template: `
        <button @click="send">发送</button>
    `,
    data(){
        return {
            child_comp1: 'hello world!'
        }
    },
    methods: {
        send(){
            this.$emit('child_comp1_send', this.child_comp1);
        }
    }
});
 
Vue.component('parent-comp1', {
    template: `
        <div>
            <child-comp1 @child_comp1_send="get"></child-comp1>
            <p>{{parent_comp1}}</p>
        </div>
    `,
    data(){
        return {
            parent_comp1: ''
        }
    },
    methods: {
        get(data){
            this.parent_comp1 = data;
        }
    }
});
 
new Vue({
    el: '#app'
})

另一种方式:

有的时候用一个事件来抛出一个特定的值是非常有用的。这时可以使用 $emit 的第二个参数来提供这个值,然后当在父级组件监听这个事件的时候,我们可以通过 $event 访问到被抛出的这个值:

<div id="app">
    <div id="blog-posts-events-demo">
        <div :style="{fontSize: postFontSize+'em'}">
            <my-component @enlarge-text="postFontSize+=$event"></my-component>
            <p>Sometimes this is desirable for readability.</p>
        </div>
    </div>
</div>
Vue.component('my-component', {
    template: `<button @click="$emit('enlarge-text', 0.2)">Enlarge text</button>`
});
 
let vm = new Vue({
    el: '#app',
    data: {
        postFontSize: 1
    }
});

三、兄弟组件之间通信

通过共同的祖辈组件搭桥:$parent或$root

<div id="app">
    <comp1></comp1>
    <comp2></comp2>
</div>
let event = new Vue();
 
Vue.component('comp1', {
    template: `
        <div>
            <p>我是第一个组件</p>
            <input type="text" @keyup="send" v-model="comp1_msg"/>
        </div>
    `,
    data(){
        return {
            comp1_msg: ''
        }
    },
    methods: {
        send(){
            event.$emit('comp1_send', this.comp1_msg);
        }
    }
});
 
Vue.component('comp2', {
    template: `
        <div>
            <P>我是第二个组件</P>
            <p>{{comp2_msg}}</p>
        </div>
    `,
    data(){
        return {
            comp2_msg: ''
        }
    },
    mounted(){
        let me = this;
        event.$on('comp1_send', function(data){
            me.comp2_msg = data;
        });
    }
});
 
new Vue({
    el: "#app"
})

四、祖先和后代之间通信

由于嵌套层数过多,传递props不切实际,vue提供provide和inject API完成该任务。

provide和inject能够实现祖先给后代元素传值。

// 祖先
provide(){
    return {
        foo: 'foo'
    }
}

// 后代
inject: ["foo"]

五、任意组件之间通信:事件总线或vuex

事件总线:创建一个Bus类负责事件派发、监听和回调管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值