Vue组件通信的方式有哪些?

1.组件 父传子

使用 `Props`属性,父组件将信息传给子组件,从而子组件获得父组件的信息,父组件和子组件之间靠子组件标签
取得关联,在子组件标签上所有的属性构成的集合在子组件的props属性可以接受到。

2.组件 子改父

基于自定义事件 : 把父组件的某些方法 注册到任务队列中,再通过实例的`$emit`方法获取自定义事件
中的方法

3.组件 兄弟之间元素的通信

实例:

<div id="app">
        <!-- 实例中写的数据只能该区域使用 -->
        <h2>{{name}}</h2>
        <my-vote v-for="item in list" :title="item"></my-vote>
    </div>
    <template id="myVote">
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">{{title}}----{{num}} <button @click="changeNum">增加</button></h3>
                </div>
                <content-vote :event="eventBus"></content-vote>

                <!-- 基于自定义事件 : 把父组件的某些方法 注册到任务队列中 -->
                <!-- <footer-vote v-on:changeParent="changeNum"></footer-vote> -->
                <footer-vote :event="eventBus" @changeParent="changeNum"></footer-vote>
                
            </div>
        </div>
    </template>
    <template id="contentVote">
        <div class="panel-body">
            <ul class="list-group">
                <li class="list-group-item">支持人数:{{subNum}}</li>
                <li class="list-group-item">反对人数:{{oppNum}}</li>
                <li class="list-group-item">支持率:{{radio}}</li>
            </ul>
        </div>
    </template>
    <template id="footerVote">
        <div class="panel-footer">
            <button class="btn btn-success" @click="handle('support')">支持</button>
            <button class="btn btn-danger" @click="handle('oppose')">反对</button>
        </div>
    </template>

Vue.component("myVote",{
        template:"#myVote",
        data(){
            return {
                num:0,
                eventBus:new Vue
            }
        },
        methods:{
            changeNum(){
                console.log(123)
                this.num++;
            }
        },
        props:['title','index'],
        created(){
            console.log(this); // 此时this就是当前的组件
            console.log(this.$props);
            console.log(this.title)
        }
    })   
    Vue.component("contentVote",{
        template:"#contentVote",
        data(){
            return {
                subNum:0,
                oppNum:0
            }
        },
        props:['event'],
        computed: {
            // 求支持率
            radio(){
                let total=this.subNum+this.oppNum;// 求和
                // 0/0得到NaN 
                if(total===0){
                    return "0%";
                }
                return (this.subNum/total*100).toFixed(2)+"%"
            }
        },
        methods:{
            change(type){
                type=="support"?this.subNum++:this.oppNum++;
            }
        },
        created(){
            // eventBus.$on('changeEvent',this.change)
            this.event.$on('changeEvent',this.change)
            // @changeEvent="change"
        }

    })
    Vue.component("footerVote",{
        template:"#footerVote",
        props:['event'],
        methods:{
            handle(type){
                // console.log(456);
                // console.log(this.$emit(''));
                this.$emit('changeparent'); // 获取自定义事件中的方法
                // 该处的事件的名字是小写 
                // eventBus.$emit('changeEvent',type)
                this.event.$emit('changeEvent',type)

            }
        }
    })
    
    let vm=new Vue({
        el:"#app",
        data:{
            // name:"胡歌",
            list:['胡歌','靳东']

        }
    })

效果展示:在这里插入图片描述

4.通过provideinject实现祖先和后代组件之间的通信

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作。

<div id="app">
    <vote></vote>
    <vote></vote>
    <vote></vote>
</div>

inject 选项应该是:
1)一个字符串数组,或
2)一个对象,对象的 key 是本地的绑定名,value 是:
在可用的注入内容中搜索用的 key (字符串或 Symbol),或一个对象,该对象的:
from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)
default property 是降级情况下使用的 value。
注意:provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

利用 ES2015 Symbols、函数 provide 和对象 inject:

     const s = Symbol();
    const Provider = {
        provide () {
            return {
                [s]: 'foo'
            }
        }
    }

Vue.component("vote",{
        template:`
            <div>
                {{obj.name}}
            </div>
        `,
// 子组件注入obj
        inject:['obj']
    })
    let vm=new Vue({
        el:"#app",
        data:{
            obj:{
                name:"zhangsan"
            }
        },
// 父组件提供obj
        provide(){
            return {
                obj:this.obj
            }
        }
    })

    const Child = {
        inject: { s },
        // ...
    }

5 通$refs && $parent && $children

$parent 父组件,在子组件中直接可以通过$parent 获取到父组件的数据和方法
$children子组件,在父组件中直接可以通过$children 获取到子组件的方法 (注意:$children获取到的是数组形式,需要记住子组件的位置);

Vue.component("vote",{
            template:`
                <div>
                    <h3>{{num}}</h3>
                    <vote-content></vote-content>
                </div>
            `,
            data(){
                return {
                    num:100,
                    name:"huge"
                }
            },
            methods: {
                change(){
                    this.num++;
                }
            },
        })
        Vue.component('voteContent',{
            template:`
                <div>
                    <h4>子组件的标题</h4>
                    <p>{{$parent.num}}--- <button @click="$parent.change">改变</button></p>
                    <vote-content-child></vote-content-child>
                </div>
            `,
            created() {
                console.log(this);
                console.log(this.$parent);  // $parent就是获取父组件
            },
            components:{
                voteContentChild:{
                    template:`
                        <div>
                            <h4>子组件的标题312313</h4>
                        </div>
                    `,
                    created() {
                        console.log(this.$parent);
                    },
                }
            }
        })

$children子组件,在父组件中直接可以通过$children 获取到子组件的方法 (注意:$children获取到的是数组形式,需要记住子组件的位置);

Vue.component("vote", {
    template: `
        <div>
            <h3>{{num}}</h3>       
            <p>子组件的内容:---<button @click="fn()">执行handle方法</button></p>
            <vote-content></vote-content>
            <vote-footer></vote-footer>
        </div>
    `,
    data() {
        return {
            num: 100,
            name: "huge",
        }
    },
    methods: {
        change() {
            this.num++;
        },
        fn() {
            this.$children[0].handle(); // 直接通过$children获取子组件
            console.log(this.$children[0].m);
        },

    },
    components: {
        voteContent,
        voteFooter: {
            template: `<div></div>`
        }
    },
})

6.$refs 子组件 在父组件中直接可以通过$refs 获取到父组件的数据和方法 (获取的是对象形式)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值