一、父子组件
父子组件之间是
单向数据流
。
1、父组件向子组件传递prop
父组件通过prop向子组件传递属性,子组件通过props接受属性。
由于JS的数组、对象引用关系
,子组件一定不能修改父组件传来的数组、对象
属性。
## html
<div id="app">
<input type="text" v-model='inputMsg'/>
<!-- 这个是静态绑定 <child my-message="hello!"></child> -->
<child :my-message="inputMsg"></child>
</div>
## js
//子组件
Vue.component('child', {
props: {
//类型校验。
myMessage : {
type : Number,
required : true
}
}
computed : {
addMyMessage : function(){
//return ++this.myMessage; //这样写 Vue会报错。
//将父组件传来的属性,赋值于一个新变量,然后做更改。
let a = this.myMessage;
return ++a;
}
},
template: '<span>{{addMyMessage}} </span>'
})
const vm = new Vue({
el: '#app',
data: {
inputMsg : 1
}
})
2、子组件向父组件传递消息
父组件通过
v-on
在子组件的标签上监听子组件触发的事件。
子组件在内部通过$emit
触发相应事件。
## html
<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
## js
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
increment: function () {
this.counter += 1
this.$emit('increment')
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
二、非父子组件
非父子组件之间借助$emit(emiter,value) 和 $on(emiter,fn) 来进行数据传递。
首先我们需要先创建一个空的vue示例
,用来做中转站
。
需要注意的是:在事件监听的回调函数需要绑定监听组件的this,否则会获取不到事件监听组件的属性。
## html
<div id="app">
<comp1></comp1>
<comp2></comp2>
</div>
## js
//空的Vue实例,用作中转站
const bus = new Vue();
//触发事件的组件
Vue.component('comp1', {
methods : {
sendMsg(){
//通过中转站 bus.$emit,触发一个 fromComp1的事件。
bus.$emit('fromComp1',this.$refs.input.value);
}
},
template: '<div>\
<input ref="input" />\
<button v-on:click="sendMsg()">点击</button>\
</div>'
})
//监听事件的组件
Vue.component('comp2', {
data :function(){
return {
Comp1 : 0
}
},
created(){
const _this = this; //this.$vnode.tag="vue-component-2-comp2";
//借助中转站bus.$on,监听fromComp1,事件,通过回调函数来接收传递过来的值。
//注意这里需要给回调函数进行this上下文的转化。
bus.$on('fromComp1',function(val){
this.Comp1 = val;
}.bind(_this))
},
template: '<span>{{Comp1}} </span>'
})
;
const vm = new Vue({
el : '#app'
});