组件之间的数据传递(通信)
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:{
"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:{
"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>
...
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"
}
}
}
}
})