学习笔记Vue(十)—— 组件通信

一、在子组件中获取父组件的数据

1.通过$attr

$attrs包含的是组件没有被注册到prop上的属性,
可以将父组件没有用过的值通过v-bind直接传递给子组件
代码:

<body>
    <div id="app">
        <my-content :title="title" :content="content" class="aaa"></my-content>
    </div>
    <script>
 		//通过$attrs
        const vm = new Vue({
            el: '#app',
            data: {
                content: '我是内容内容内容内容内容内容内容',
                title: '我是标题'
            },
            components: {
                myContent: {
                    props: ['title'],
                    created (){
                        console.log(this.$attrs); //包含的这个组件没有被注册的属性,打印出来content
                    },
                    inheritAttrs: false,//如果某个属性没有被用,会直接显示在行间,设置inheritAttrs:false可以防止这种情况
                    //通过v-bind将$attrs传递给子组件
                    template: `<div>
                                <h3>{{title}}</h3>
                                <my-p v-bind="$attrs"></my-p>
                            </div>`,
                    components:{
                        myP: {
                            props:['content'],
                            template: `<p>{{content}}</p>`
                        }
                    }
                }
            }
        });
    </script>
</body>

如果某个属性没有被用,会直接显示在行间,
在这里插入图片描述
设置inheritAttrs:false可以防止这种情况。

2.通过$parent

可以在子组件里通过$parent来获取父组件的实例,
同时也可以在父组件里通过 $children来获取子组件的实例,
子组件在挂载完毕才有,所以应在生命周期的mounted里获取
但这种方法并不推荐,写起来也麻烦。

<body>
    <div id="app">
        <my-content :title="title" :content="content" class="aaa"></my-content>
    </div>
    <script>
 		//通过$parent 
        const vm = new Vue({
            el: '#app',
            data: {
                content: '我是内容内容内容内容内容内容内容',
                title: '我是标题'
            },
            components: {
                myContent: {
                    // props: ['title'],
                    created (){
                        console.log(this.$parent); //打印出根实例
                        this.title = this.$parent.title;
                    },
                    mounted() {
                        console.log(this.$children);
                    },
                    inheritAttrs: false,
                    template: `<div>
                                <h3>{{title}}</h3>
                                <my-p></my-p>
                            </div>`,
                    components:{
                        myP: {
                            // props:['content'],
                            created(){
                                this.content = this.$parent.$parent.content;
                            },
                            template: `<p>{{content}}</p>`
                        }
                    }
                }
            }
        });
    </script>
</body>

3.通过provide和inject

在父组件上有一个属性,provide,可以写入想提供给子组件的值,并且不只是直接子组件,孙子组件也可以拿到,相当于传家宝,子组件或孙子组件可以使用inject来获取provide里的数据。
举例:

<body>
    <div id="app">
        <my-content :title="title" :content="content" class="aaa"></my-content>
    </div>
    <script>
        //provide inject
        const vm = new Vue({
            el: '#app',
            provide: {
                content: '我是内容内容内容内容内容内容内容',
                title: '我是标题'
            },
            components: {
                myContent: {
                    inject: ['title'],
                    template: `<div>
                                <h3>{{title}}</h3>
                                <my-p></my-p>
                            </div>`,
                    components:{
                        myP: {
                            inject:['content'],
                            template: `<p>{{content}}</p>`
                        }
                    }
                }
            }
        });
    </script>
</body>

二、在父组件中获取子组件的数据

1.通过$children

$children是一个数组,因为可能有很多子组件,但 p a r e n t 是 一 个 对 象 。 这 个 在 上 面 parent是一个对象。 这个在上面 parentparent的地方有提,不多写了。

2.引用 (ref)

ref引用可以放在dom上,也可以放在组件上,在实例中使用this.$refs可以获取到全部的引用。

<body>
    <div id="app">
        <div ref="dom">i am a dom</div>
    </div>
    <script>
        //引用 ref   可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
        const vm = new Vue({
            el: "#app",
            mounted (){
                console.log(this.$refs);
                console.log(this.$refs.dom);
            }
        });
    </script>
</body>

打印结果:
在这里插入图片描述
如果有两个ref名一样的标签,则只会获取到后一个。
但是使用v-for循环产生的标签,则会以数组的形式获取到全部的标签
举例:

<body>
    <div id="app">
        <!-- 两个具有相同的ref名的dom只能获取到后一个 -->
        <div ref="dom">i am a dom</div>
        <div ref="dom">i am a dommmmm</div>
        <!-- 通过for循环的方式 获取到的ref是一个数组, -->
        <div ref="dom2" v-for="item in 5">i am a dom</div>
    </div>
    <script>
        //引用 ref   可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
        const vm = new Vue({
            el: "#app",
            mounted (){
                console.log(this.$refs);
                console.log(this.$refs.dom);
                console.log(this.$refs.dom2);
            }
    </script>
</body>

输出结果:
在这里插入图片描述
通过组件上的ref拿到的是组件实例。

<body>
    <div id="app">
        <my-cmp ref="cmp"></my-cmp>
    </div>
    <script>
        // 引用 ref   可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
        const vm = new Vue({
            el: "#app",
            mounted (){
                console.log(this.$refs.cmp.msg); // hello world
                this.$refs.cmp.cmpFunc();  //执行了myCmp组件的method
            },
            components: {
                myCmp: {
                    data (){
                        return {
                            msg : 'hello world'
                        }
                    },
                    methods: {
                        cmpFunc (){
                            console.log('cmp');
                        }
                    },
                    template: '<div>i am a compontent</div>'
                }
            }
        });
    </script>
</body>

3.监听组件事件

组件是不能感知事件的,可以通过两种方法来获取组件的事件。
(1)通过.native让组件可以感知原生的事件

        <my-cmp @click.native="func"></my-cmp>

(3)$emit

<my-cmp @click="func"></my-cmp>   
     
const vm = new Vue({
            el: "#app",
            methods: {
                func (data){
                    console.log('func');
                }
            },
            components: {
                myCmp: {
                    props: ['func'],
                    data (){
                        return {
                            msg : 'hello world'
                        }
                    },
                    methods: {
                        cmpFunc (){
                            console.log('cmp');
                        },
                        handleClick (){
                            this.$emit('click', this.msg); //要触发的事件, 参数   
                        }
                    },
                    template: `<div>i am a compontent
                                <button @click="handleClick">点击</button>
                                </div>`
                }
            }
        });

(2)$listener
$listener可以获取到所有组件上的事件,也可以通过v-on绑定

<my-cmp @click="func" @like="like"></my-cmp>   
 
const vm = new Vue({
            el: "#app",
            methods: {
                func (data){
                    console.log('func');
                },
                like (){
                    console.log('like');
                }
            },
            components: {
                myCmp: {
                    props: ['func'],
                    data (){
                        return {
                            msg : 'hello world'
                        }
                    },
                    methods: {
                        cmpFunc (){
                            console.log('cmp');
                        },
                        handleClick (){
                            // console.log(this.$listeners);
                            // this.$listeners.click(this.msg);
                            this.$emit('click', this.msg); //要触发的事件  参数
                            this.$listeners.like();  // 也可以执行自定义事件 
                        }
                    },
                    template: `<div>i am a compontent
                                <button @click="handleClick">点击</button>
                                <button v-on="$listeners">click</button>
                                </div>`
                }
            }
        });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值