vue组件之间的数据通信

组件之间的数据传递(通信)

1.父子组件

1).在组件内部定义另一个组件称为父子组件
2).子组件只能在父组件中使用
3).默认情况下,子组件是无法访问父组件的数据的
html部分:
<div class="box" id="app">
    <my-hello></my-hello>
    
</div>

<template id="hello">
    <div>
        <p>我是hello组件</p>
        <p>我是hello组件的数据:{{name}},{{age}},{{user.id}}</p>
        <hr>
        <my-world></my-world>
    </div>
</template>

<template id="world">
    <div>
        <p>我是world子组件</p>
    </div>
</template>

js部分:
var vm = new Vue({
    el: "#app",
    data:{
        
    },
    components:{
        "my-hello":{
            template:"#hello",
            data:function(){
                return {
                    msg:"学习vue",
                    name:"yang",
                    age:27,
                    user:{id:666, userName:"杨义"}
                }
            },
            components:{         // 子组件 在hello父组件内部
                "my-world":{
                    template:"#world"
                }
            }
        }
    }
})

2.组件中的数据传递(通信)

2.1 子组件访问父组件的数据
a). 在子组件调用的时候,绑定需要访问的数据msg,并申明一个名字message。
    示例:<my-hello :message="msg"></my-hello>
b). 在子组件js内部,使用props来接受绑定的数据名

c). 最后在使用的时候{{申明的数据名}} ===> {{message}}
html部分:
    <div class="box" id="app">
        <my-hello></my-hello>

    </div>

    <template id="hello">
        <div>
            <p>我是hello组件</p>
            <p>我是hello组件的数据:{{name}},{{age}},{{user.id}}</p>
            <hr>
            <my-world v-bind:message="msg"></my-world>
        </div>
    </template>

    <template id="world">
        <div>
            <p>我是world子组件</p>
            <p>访问父组件的数据:{{message}}</p>
        </div>
    </template>

    js部分:
    var vm = new Vue({
        el: "#app",
        data:{
            
        },
        components:{
            "my-hello":{
                template:"#hello",
                data:function(){
                    return {
                        msg:"学习vue",
                        name:"yang",
                        age:27,
                        user:{id:666, userName:"杨义"}
                    }
                },
                components:{         // 子组件 在hello父组件内部
                    "my-world":{
                        template:"#world",
                        props:['message']
                    }
                }
            }
        }
    })

2.2 父组件访问子组件的数据
a).子组件使用 $emit发送数据给父组件,写法:this.$emit('事件名','需要发送的数据')
例:this.$emit('e-world',this.name,this,age)
b).子组件在父组件内调用的时候执行一个方法(@事件名="方法"),同时父组件自定义一个方法来接受子组件传过来的数据(例子中的getData方法)
例:
	<template id="world">
		<div>
			<p>我是父组件</p>
			<hello @e-world="getData"></hello>
		</div>
	</template>
	...
	// 这里是父组件内部的代码,不是vm根组件的代码
	data:{
		name:"",
		age:""
	},
	methods:{
		getData:function(name, age){
			this.name = name;
			this.age = age
		}
	}

3.父子组件间的单项数据流

父组件的数据一旦发生改变,子组件的数据会同步发生改变,反过来子组件数据改变时,父组件是不会改变的
而且子组件是不允许直接修改父组件的数据,会报错
解决方法:
    1).如果子组件想把父组件的数据拿到当成局部数据来使用,可以用一个变量存起来
    components:{
        "hello":{
            template:"#hello",
            props:["hellomsg"],     // 接受到父组件的hellomsg ==> <hello v-bind:hellomsg="msg"></hello>
            data:function(){
                return {
                    usermsg:this.hellomsg   //  拿usermsg存起来当局部数据来使用
                }
            }
        }
    }

    2).如果子组件想修改拿到父组件的数据,并同步给父组件有两个方法:
        a).可以使用修饰符:sync  1.0支持 2.0-2.2不支持
            html部分使用:
            <hello v-bind:hellomsg.sync="msg"></hello>

            js部分需要在子组件内methods使用:this.$emit("update:需要修改的数据","修改后的数据")
            components:{
                "hello":{
                    template:"#hello",
                    props:["hellomsg"],  
                    methods:function(){
                        this.$emit("update:hellomsg","hello world")
                    }
                }
            }
        b).因为js数据和对象都是引用类型指向同一内存空间,所以我们可以直接将父组件的数据包装成一个对象,修改对象的属性
            html部分使用:
            <hello v-bind:users="msg"></hello>

            js部分:
            users:{         // 父组件的属性,包装成一个对象
                age:18
            }
            -------------------------------------
            components:{
                "hello":{
                    template:"#hello",
                    props:["users"],  
                    methods:function(){
                        this.users.age = 100;
                    }
                }
            }

4.非父子组件之间的通信

非父子组件之间的通信,可以通过一个空的vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件
1).var Event = new Vue();

2).发送数据:Event.$emit("事件名","数据");
"my-b":{
    template:"#b",
    data:function(){
        return {
            age:18
        }
    },
    methods:{
        sendb:function(){
            Event.$emit("data-b",this.age)      // 发送age
        }
    }
}

3).接受数据:Event.$on("事件名",data=>{})  es6箭头函数,可以防止改变this指向
"my-c":{
    template:"#c",
    data:function(){
        return {    
            age:""          // 初始化age的值
        }
    },
    mounted:function(){         // 钩子函数 当模版编译完成之后执行
        Event.$on("data-a",data => {
            this.name = data;
        })
        Event.$on("data-b",data => {        // 接受age == data是回调函数的参数
            this.age = data;            // 这里的this如果不是箭头函数那指向的会是全局的vue实例 - Event
        })
    }
}

slot内容分发

用于获取组件内的原内容
组件:
<template id="hello">
    <div>
        <slot name="list1"></slot>      // 掉哟个slot时name = 组件调用时申明的slot名字      
        <p>{{name}}</p>
        <slot name="list2"></slot>
    </div>
</template>

组件调用(中间带内容)指定一个slot的名字:
<hello>
    <ul slot="list1">
        <li>aaa</li>
        <li>bbb</li>
        <li>ccc</li>
    </ul>
    <ol slot="list2">
        <li>111</li>
        <li>222</li>
        <li>333</li>
    </ol>
</hello>

js:
var vm = new Vue({
    el: "#app",
    data:{
        
    },
    components:{
        "hello":{
            template:"#hello",
            data:function(){
                return {
                    name:"yang"
                }
            }
        }
    }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值