一、父子通信:
1、props(组件传参)
从父到子,用props属性绑定(通过props向子组件传递数据)。
注意:props静态传入的都是字符,不管里面写的是Number、Boolean、Array还是Object类型,如果想传入除字符之外的类型,就需要动态传入。
实例一:
<div id="app">
<alert msg="hhhhhhh"></alert>
</div>
Vue.component('alert', {
template: '<button @click="on_click">点击</button>',
props: ['msg'],
methods: {
on_click: function(){
alert(this.msg);
}
}
})
new Vue({
el: '#app'
})
实例二:
<div id="app">
<user username="samve"></user>
</div>
Vue.component('user', {
template: `
<a :href="'user/' + username">{{username}}</a>
`,
props: ['username']
})
new Vue({
el: '#app'
})
Prop 验证:
<div id="app">
<my-component
:num="100"
:msg="'sdf'"
:cust="8"
></my-component>
</div>
Vue.component('my-component', {
props: {
num: Number,
propB: [String, Number],
msg: {
type: String,
require: true
},
num1: {
type: Number,
default: 1000
},
object: {
type: Object,
default: function(){//对象必须以这种方式返回
return {
message: 'hello'
}
}
},
list: function(){//对象必须以这种方式返回
return ['第1项', '第2项', '第3项'];
},
cust: {
validator: function(value){
return value>10
}
}
},
template: `<div>
<p>{{num}}</p>
<p>{{msg}}</p>
<p>{{num1}}</p>
<p>{{object}}</p>
<p>{{cust}}</p>
</div>`
});
new Vue({
el: '#app'
})
这里都是通过验证了的,能够全部输出来,而且控制台没有报错。
如果有不符合的,控制台会报错。
2、特性$attrs
只读
详细:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
// parent
<Helloworld foo="foo"/>
// child,并未在props中申明foo
<p>{{$attrs.foo}}</p>
3、引用refs
// parent
<Helloworld ref="foo"/>
mounted(){
this.$ref.foo.xx="xxx";
}
4、子元素$children
只读
详细:当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
this.$children[0].xx="xxx"
二、子父组件通信:从子组件向上传递数据
<div id="app">
<parent-comp1></parent-comp1>
<parent-comp1></parent-comp1>
</div>
Vue.component('child-comp1', {
template: `
<button @click="send">发送</button>
`,
data(){
return {
child_comp1: 'hello world!'
}
},
methods: {
send(){
this.$emit('child_comp1_send', this.child_comp1);
}
}
});
Vue.component('parent-comp1', {
template: `
<div>
<child-comp1 @child_comp1_send="get"></child-comp1>
<p>{{parent_comp1}}</p>
</div>
`,
data(){
return {
parent_comp1: ''
}
},
methods: {
get(data){
this.parent_comp1 = data;
}
}
});
new Vue({
el: '#app'
})
另一种方式:
有的时候用一个事件来抛出一个特定的值是非常有用的。这时可以使用 $emit 的第二个参数来提供这个值,然后当在父级组件监听这个事件的时候,我们可以通过 $event 访问到被抛出的这个值:
<div id="app">
<div id="blog-posts-events-demo">
<div :style="{fontSize: postFontSize+'em'}">
<my-component @enlarge-text="postFontSize+=$event"></my-component>
<p>Sometimes this is desirable for readability.</p>
</div>
</div>
</div>
Vue.component('my-component', {
template: `<button @click="$emit('enlarge-text', 0.2)">Enlarge text</button>`
});
let vm = new Vue({
el: '#app',
data: {
postFontSize: 1
}
});
三、兄弟组件之间通信
通过共同的祖辈组件搭桥:$parent或$root
<div id="app">
<comp1></comp1>
<comp2></comp2>
</div>
let event = new Vue();
Vue.component('comp1', {
template: `
<div>
<p>我是第一个组件</p>
<input type="text" @keyup="send" v-model="comp1_msg"/>
</div>
`,
data(){
return {
comp1_msg: ''
}
},
methods: {
send(){
event.$emit('comp1_send', this.comp1_msg);
}
}
});
Vue.component('comp2', {
template: `
<div>
<P>我是第二个组件</P>
<p>{{comp2_msg}}</p>
</div>
`,
data(){
return {
comp2_msg: ''
}
},
mounted(){
let me = this;
event.$on('comp1_send', function(data){
me.comp2_msg = data;
});
}
});
new Vue({
el: "#app"
})
四、祖先和后代之间通信
由于嵌套层数过多,传递props不切实际,vue提供provide和inject API完成该任务。
provide和inject能够实现祖先给后代元素传值。
// 祖先
provide(){
return {
foo: 'foo'
}
}
// 后代
inject: ["foo"]
五、任意组件之间通信:事件总线或vuex
事件总线:创建一个Bus类负责事件派发、监听和回调管理。