一,父子组件间的通讯
在 vue 中,父子组件之间的关系可以概述为:props 向下,events 向上.父组件通过 props 向下传递数据给子组件,子组件通过 events 发送消息给父组件.
props-events.png
(1) 父传子
1. 父组件调用子组件时传入变量 log-content:
<log ref="log" :log-content="logContent"></log>
2. 子组件通过 props 接收父组件传来的变量 (可传递多个变量)
vm 实例中通过 this.logContent访问 }
<template>
<div class="log-content">
<pre v-text="logContent|| '暂时内容'">
</pre>
</div>
</template>
export default { // ... props: ['logContent']// 像 data 一样,prop 可以在组件模板内部使用,并且,还可以在
总结:
1. 不能(也不应该)直接在子组件模板中引用父组件数据,应该使用 props 将数据向下传递到子组件.
2. 当父组件属性更新,数据就会向下流动到子组件
(2) 子传父
1. 父组件使用 v-on 监听子组件触发的事件 close(自定义事件)
2. 子组件可通过 $emit 触发 close 事件,从而将自身内部的信息全部通知到父组件中.
<log ref="log" :log="logContent" v-on:close="closeLog"></log>
export default {
// ...
methods: {
closeLog (data) {
console.log(data) // 子组件通过emit传递数据给父组件
}
}
}
总结:
<template>
<div class="log-content">
<pre v-text="loghtml || '暂时日志内容'"></pre>
<button v-on:click="handleClose">关闭</button>
</div>
</template>
export default {
data () {
return {
text: '当关闭log时,子组件传递数据给父组件'
}
},
props: ['logContent'],
// ...
methods: {
handleClose () {
this.$emit('close', this.text)
}
}
}
1. 父组件监听子组件的事件 (使用 $on(eventName))
2. 子组件使用 $emit(eventName) 触发,可以传递参数
3. 父组件接收到监听,执行自身事件,实现数据更改
(3) 摘自官网
所有的 props 都是在子组件属性和父组件属性之间绑定的,按照自上而下单向流动方式构成:当父组件属性更新,数据就会向下流动到子组件,但是反过来却并非如此.这种机制可以防止子组件意外地修改了父组件的状态,会造成应用程序的数据流动变得难于理解.
此外,每次父组件更新时,子组件中所有的 props 都会更新为最新值.也就是说,你不应该试图在子组件内部修改 prop.如果你这么做,Vue 就会在控制台给出警告.
注意,在 JavaScript 中对象和数组会作为引用类型传入,因此,如果 prop 是一个对象或数组,在子组件内部修改对象或数组自身,将会影响父组件的状态.
二,非父子组件通信
使用一个空的 Vue 实例作为一个事件总线中心 (central event bus)
1. 新建 bus.js 文件
2. 引用 bus.js
import Vue from 'vue'export
default new Vue()
import bus from './bus'
3. 在组件 A 的 methods 方法中触发事件
4. 在组件 B 中监听事件
bus.$emit('START_LOADING')
bus.$emit('FINISH_LOADING')
在复杂场景中,应该考虑使用专门的状态管理模式(==> 快速理解 Vuex )
export
default {
data() {
return {
loading:
0 // 全局加载loading
}
},
mounted() {
this.initConfig()
},
// ...
methods: {
initConfig() {
bus.$on('START_LOADING', () = >{
this.loading++
}) bus.$on('FINISH_LOADING', () = >{
this.loading--
})
}
}
}
来源: http://www.jianshu.com/p/fb852f5ef73b