vue——组件间通信方式

组件间通信:(父子、兄弟组件数据的传递方式)

一、父组件向子组件传递:

1、常见方式:利用属性传递数据
$attrs表示组件中未被注册的属性;可以利用其进行传值;配合v-bind可以将所有属性传递给另一个组件;
在这里插入图片描述

  //根数据传给组件,通过父组件传给子组件:

   var vm = new Vue({ 
        el: "#app",
        data: {
            content: '我是内容',
            title: '我是标题'
        },
        components: {
            myContent: {
                // props: ['title', 'content'], //这种方法注册的'content'只是用来传值,没用实际作用
                props: ['title'],
                created () {//$attrs表示组件中未被注册的属性;可以利用其进行传值;
                    console.log(this.$attrs)
                },
                inheritAttrs: false,     //设为false,没有被注册的属性不会显示在行间;(本身有的不会消除)
          
  // template: `<div>
            //                 <h3>{{ title }}</h3>
            //                 <my-p :content="content"></my-p>
            //             </div>`,
             template: `<div>
                            <h3>{{ title }}</h3>
                            <my-p v-bind="$attrs"></my-p>
                        </div>`,
            components: {
                myP: {
                    props: ['content'],
                    template: `<p>{{ content }}</p>`
                }
            }
        }
    }
})

2、$attrs、
$children:

一般情况下能不用不用,应急时使用(传递较麻烦)
在这里插入图片描述

  //根数据直接父组件用一部分、子组件用一部分:
        var vm1 = new Vue({
            el: "#app1",
            data: {
                content: '我是内容',
                title: '我是标题'
            },
            components: {
                myContent: {
                    created () {                    //$parent表示父组件的实例;
                        console.log(this.$parent);
                        this.title = this.$parent.title
                    },
                    mounted () {                  //$childre表示子组件的实例;
                        console.log(this.$children)
                    },
                     template: `<div>
                                    <h3>{{ title }}</h3>
                                    <my-p> {{ title }}</my-p>
                                </div>`,
                    components: {
                        myP: {
                            created () {
                                this.content = this.$parent.$parent.content;
                            },
                            template: `<p>{{ content }}</p>`
                        }
                    }
                }
            }
        })

3、provide:{}提供值,inject:[]接收值;(一般不用)

在这里插入图片描述

  //父组件提供值,子组件可以取到;
        var vm2 = new Vue({
            el: "#app2",
            provide: {
                content: '我是内容',
                title: '我是标题'
            },
            components: {
                myContent: {
                    inject: ['title'],
                     template: `<div>
                                    <h3>{{ title }}</h3>
                                    <my-p> {{ title }}</my-p>
                                </div>`,
                    components: {
                        myP: {
                            inject: ['content'],
                            template: `<p>{{ content }}</p>`
                        }
                    }
                }
            }
        })

二、子向父传递:
1、$children 方式获取到子组件的实例,进行操作(不推荐)

2、$refs:拿到子组件的引用;可以dom上,也可以放到组件上;
在这里插入图片描述

 const vm3 = new Vue({
        el: "#app3",
        mounted  () {
            console.log(this.$refs.dom); //放到dom上;
            //这里的dom元素如果初始时有多个且一样,只会打印最后一个;v-for生成的dom会全不打印在[]中;
            console.log(this.$refs.cmp); //放到组件上;this.$refs.cmp拿到子组件里的实例;再拿到里面的数据;
            console.log(this.$refs.cmp.msg);
            this.$refs.cmp.cmpFunc()
        },
        components: {
            myCmp: {
                data () {
                    return {
                        msg: 'hello'
                    }
                },
                methods: {
                    cmpFunc () {
                        console.log('cmp')
                    }
                },
                template: `<div> i am a cmp </div>`
            }
        }
    })

3、传递函数方式:通过在子组件中执行父组件的函数,向父组件传递数据
方法一:将父组件中的函数当做属性传给子组件执行;
方法二:利用 l i s t e n e r s : 能 够 把 通 过 v − o n 绑 定 的 事 件 放 到 listeners:能够把通过v-on绑定的事件放到 listenersvonlisteners里面来;
方法三:利用$emit(’’, );主动触发组件v-on绑定的事件;第二个值可传参用;

//注意:
//当事件绑定很多时,利用v-on给组件内某个dom绑定事件监听(注意通过v-on方法不能传参)
//$listeners与$attrs相似有一个v-on属性,可以将该组件通过v-on绑定的事件传递给另一个组件;
//$listeners和$emit()不仅能触发系统自带的事件,也可以触发自定义事件; 

在这里插入图片描述


    const vm4 = new Vue({
        el: "#app4",
        methods: {
            func (data) {
                console.log(data);
            },
            down (){
                console.log('down')
            }
        },
        components: {
            myCmp: {
                // props: ['func'],  //方法一
                data () {
                    return {
                        msg: 'hello'
                    }
                },
                methods: {
                    cmpFunc () {
                        console.log('cmp');
                    },
                    handleClick () {
                        // this.func(this.msg);  //方法一;
                        // this.$listeners.click(this.msg);  //方法二;
                        this.$emit('click', this.msg);    //方法三;
                    },
                    handleMouse () {
                        this.$emit('mousedown', 4545);
                    }
                },
                template: `<div> i am a cmp
                            <button @click="handleClick" @mousedown="handleMouse">点击</button>
                            <button v-on="$listeners"> click </button>
                            </div>`
            }
        }
    })

三、兄弟传递:

enent bus 事件总线: 一个兄弟组触发新的vue实例事件并将数据传参,另一个兄弟组件监听该vue实例事件并取值;

this.bus. $emit(’’, )触发事件;
this.bus. $on(’’, data => {})监听事件;

在这里插入图片描述

 Vue.prototype.bus = new Vue();  //vue原型上增加属性为一个新的vue实例;
    const vm5 = new Vue({
        el: "#app5",
        components: {
             myContent1: {      //一个兄弟组触发新的vue实例事件并将数据传参,
                data () {
                    return {
                        content: '我有值'
                    }
                },
                methods: {
                    handleClick () {
                        console.log(this)
                        this.bus.$emit('myClick', this.content); //触发新vue实例的事件
                    }
                },
                template: `<div> {{ content }}
                            <button @click="handleClick">提交</button>
                          </div>`
            },
            myContent: {        //另一个兄弟组件监听该vue实例事件并取值;
                data () {
                    return {
                        msg: 123
                    }
                },
                created () {
                    this.bus.$on('myClick', data => {    //监听vue实例的事件
                         this.msg = data;
                    })
                },
                template: `<div> {{ msg }}</div>`
            },
        }})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值