Vue组件通信方式总结

1.父子组件通信:

1) 父向子传值:在父组件中,传递动态属性和静态属性,子组件通过props接收一个字符串数组或者对象( { }这种方式接受属性 可以对接受的值进行数据校验 );

2) 子向父传值:在父组件中,给子组件传递一个函数,子组件中,通过this.$emit('函数名',实参) 方法 调用函数同时传递参数;

<body>
    <div id='app'>
        <Father></Father>
    </div>
    <!-- 定义组件模板 -->
    <template id="father">
        <div>
            <h1>我是父组件</h1>
            <!-- 接收子组件传递过来的值 -->
            <span>{{message}}</span>
            <hr/>
            <!-- 使用单项数据绑定的方式 -->
            <!-- 属性名不能使用驼峰命名 -->
            <!-- 通过 title和attr-a 给子组件传值-->
            <Son title="son" :attr-a="msg" @deliver="deliverBySon"></Son>
        </div>
    </template>
    <template id="son">
        <div>
            <h2>我是子组件</h2>
            <h2>父组件传递过来数据:{{attrA}}</h2>
            <button @click="$emit('deliver',sonMsg)">向父组件传值</button>
        </div>
    </template>
</body>
<script type='text/javascript'>
    //父组件
    Vue.component('Father', {
        template: "#father",
        data() {
            return {
                msg: "我是父亲",
                message: ""
            }
        },
        methods: {
            deliverBySon(val) {
                this.message = val
            }
        }
    });
    //子组件
    Vue.component('Son', {
        template: "#son",
        //通过props接收
        props: {
            attrA: {
                type: String,
                default: "aaa"
            },
            title: String
        },
        data() {
            return {
                sonMsg: "我是儿子"
            }
        },
        mounted() {
            console.log(this.title) //返回"son"
        },
    });
    //根组件
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>

2.事件总线:兄弟组件传值: 通过中间Vue实例对象bus(快递员)进行数据传递,通过组件实例.$on('事件名称',事件方法(形参)) 声明事件, 通过 组件实例.$emit('事件名称',实参) 向外发送参数 触发事件.

<body>
    <div id='app'>
        <brother></brother>
        <br/>
        <sister></sister>
    </div>
    <!-- 兄弟组件 -->
    <template id="brother">
        <div>
            <h1>我是哥哥</h1>
            <button @click="handle">我要给姐姐传5</button>
            <span>{{msg}}</span>
        </div>
    </template>
    <!-- 姐妹组件 -->
    <template id="sister">
        <div>
            <h1>我是姐姐</h1>
            <button @click="handle">我要给哥哥传值6</button>
            <span>{{msg}}</span>
        </div>
    </template>

    <script type='text/javascript'>
        //
        let bus = new Vue();
        //兄弟组件
        Vue.component('brother', {
            template: "#brother",
            data() {
                return {
                    broMsg: "我是哥哥",
                    msg: ''
                }
            },
            methods: {
                handle() {
                    bus.$emit('addFive', 5)
                }
            },
            created() {
                const that = this;
                bus.$on('addSix', function(val) {
                    that.msg += val
                })
            },
        });
        //姐妹组件
        Vue.component('sister', {
            template: "#sister",
            data() {
                return {
                    sisMsg: "我是姐姐",
                    msg: ''
                }
            },
            created() {
                const that = this;
                //通过组件实例.$on('事件名称',事件方法(形参)) 声明事件
                bus.$on('addFive', function(val) {
                    console.log(this) //返回vue实例
                    console.log(that) //返回vue组件实例
                    that.msg += val
                })
            },
            methods: {
                //通过 组件实例.$emit('事件名称',实参) 向外发送参数 触发事件
                handle() {
                    bus.$emit('addSix', 6)
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {}
        });
    </script>
</body>

3. 依赖注入:provide 和 inject 祖先组件给后代组件传值 :通过provide 注入原始家产 (用法基本和data是一直的) 是一个字符串数组或返回一个对象的函数, 通过inject接受 (和props用法基本上是一一致) 是一个字符串数组 或 一个对象. 不是响应式的.

<body>
    <div id="app">
        <!-- A嵌套B组件 B组件又嵌套C组件 -->
        <a-component></a-component>
    </div>
    <script>
Vue.component('a-component', {
                data() {
                    return {
                        jc1: 100
                    }
                },
                provide() {
                    return {
                        jc: this.jc1 // 通过获取自己data中数据然后将其注入给后代
                    }
                },
                template: `
            <div>
              我是A组件--{{jc1}}
              <button @click='handleAdd'>点击A按钮</button>
              <b-component></b-component>
            </div>`,
                methods: {
                    handleAdd() {
                        setTimeout(async() => {
                            const res = await Promise.resolve(5000)
                            this.jc1 = res
                        }, 2000)
                    }
                },
            })
            //b组件
        Vue.component('b-component', {
                inject: ['jc'],
                template: `
            <div>
              我是B组件--{{jc}}
              <c-component></c-component>
            </div>`
            })
            //c组件
        Vue.component('c-component', {
            inject: {
                jcc: {
                    from: "jc", //用from表示需要注入的jc
                    default: () => {
                        return [1, 2, 3]
                    }
                }
            },
            template: `<div>我是C组件--{{jcc}}</div>`
        })
        var vm = new Vue({
            el: '#app'
        })
    </script>
</body>

4.v-model :子组件既要使用数据也要修改数据 .注意:一个组件上只能使用一次v-model ,默认传value和event 也可以通过model自定义属性名和事件名 实现父子组件通信

<body>
    <div id='app'>
        <father></father>
    </div>
    <!-- v-model的默认规则 -->
    <!-- 传递:props
        :followed="msg" 
        修改:自定义事件
        @updateFollowed="msg=$event"
    简写方式:在组件上使用v-model
        value="msg"
        @input="msg=$event"
    注意:一个组件上只能使用一次v-model-->
    <script type='text/javascript'>
        //子组件既要使用数据也要修改数据
        Vue.component('Father', {
            template: `<div>
            <h1>我是父组件的值{{msg}}</h1>
            <hr/>
            <son v-model="msg"></son>
            </div>`,
            data() {
                return {
                    msg: "father~"
                }
            }
        })
        Vue.component('Son', {
            template: `<div>
            <h2>我是子组件</h2>
            <span>接收父组件传值{{val}}</span>
            <input ref="iptRef" type="text"  @input="change">
            </div>`,
            model: {
                prop: 'valueFather',
                event: 'changeValue'
            },
            props: {
                valueFather: {
                    required: true
                }
            },
            data() {
                return {
                    val: this.valueFather
                }
            },
            methods: {
                change(event) {
                    console.log(this.val)
                    this.$emit('changeValue', event.target.value)
                        //console.log(this.$refs.iptRef.value)
                        //this.$emit('input', this.$refs.iptRef.value)
                }
            }
        })
        var vm = new Vue({
            el: '#app',
            data: {}
        });
    </script>
</body>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值