VUE组件
尽管父子组件可以通过 this.
p
a
r
e
n
t
,
t
h
i
s
.
parent,this.
parent,this.child,this.$root互相访问,但是子组件应当避免直接依赖父组件的数据
- 父组件与子组件紧密耦合
- 只看父组件,很难理解父组件的状态,因为它可能被任意子组件修改。在理想状态下,只有组件自己可以修改状态
因为作用域是有层次的,所以我们可以在作用域上传递事件。如果要通知整个事件系统,就要向下广播。每个VUE实例都是一个事件触发器
- $on() —— 监听事件
- $emit() —— 把事件沿着作用链向上传送
- $dispatch() —— 派发事件,事件沿着父链冒泡
- $broadcast() —— 广播事件,事件向下传导给所有后代
(1)VUE自定义事件,用于在组件树中通信
代码如下(示例):
<body>
<!-- 子组件模块 -->
<template id="child-template">
<input v-model="msg">
<buton v-on:click="notify">Dispatch Event</button>
</template>
<!-- 父组件模板 -->
<div id="events-example">
<p>Message:{{ message | json }}</p>
<child></child>
</div>
</body>
<script>
//注册子组件
//将当前的消息派发出去
Vue.component('child',{
template:'#child-template',
data : function(){
return {msg : 'hello'}
},
methods:{
notify:function(){
if(this.msg.trim()){
//派发事件,事件将沿着父链冒泡,事件名称child-msg,参数this.msg
this.$dispatch('child-msg',this.msg)
this.msg = ''
}
}
}
})
//初始化父组件
//收到消息时将事件推入一个数组中
var parent = new Vue({
el:'#events-example',
data:{
message:[]
},
//创建实例时,‘events’选项简单的调用'$on'
events:{
'child-msg':function(msg){
//事件回调内的'this'自动绑定到注册它的实例上
this.message.push(msg)
}
}
})
</script>
(2)也可以在子组件用到的地方声明事件处理器,这样可以更直观
代码如下(示例):
<body>
<!-- 子组件模板 -->
<template id='child-template'>
<input v-model="msg">
<button v-on:click="notify">Dispatch Event</button>
</template>
<!-- 父组件模板 -->
<div id="event-example">
<p>Message:{{ message | json }}</p>
<child v-on:child-msg="handleIt"></child>
</div>
</body>
<script>
//注册子组件
//将当前消息源派发出去
Vue.component('child',{
template : '#child-template',
data:function(){
return {msg : 'hello'}
},
methods:{
notify:function(){
if(this.msg.trim()){
this.$dispatch('child-msg',this.msg)
this.msg = ''
}
}
}
})
//初始化父组件
//在收到消息时将事件推入一个数组中
var parent = new Vue({
el : '#events-example',
data:{
messages:[]
},
methods:{
'handleIt':function(){
alert("a")
}
}
})
</script>
这样就很清楚了——当子组件触发了child-msg事件时,父组件的handleIt方法将会被调用,所有影响父组件状态的代码都放在父组件的handleIt方法中;子组件只关注触发事件。
总结
(1)在子组件中触发事件
(2)在父模板中用到子组件的地方声明事件触发器,并绑定到父模板中的方法上
这样,父组件状态控制由父组件的方法决定,子组件只管触发事件即可