父子组件
- props
on (子传父)
children
- ref
listeners(2.4.0 新增)
兄弟组件
- $parent
- $root
- eventBus
- vuex
跨层级关系
- eventBus
- vuex
- provide/inject
1. 父组件 => 子组件
a. 属性props
// 子组件
props: {msg: String}
// 父组件
<Helloworld msg="welcome to vue"></Helloworld>
b. 特性$attrs
// 子组件
<p>{{ $arres.foo }}</p>
// 父组件
<HelloWorld foo="这是一个特殊属性" />
c. 引用refs
// 父组件
<Helloworld ref="fo" />
mounted () {
this.$refs.fo.xx = 'xxxxxx' // 在父组件中修改子组件属性
}
// 子组件
...
d. 子元素 $children
$parent用法差不多
// 父组件
created () {
this.$children[0].xx = 'xxxxxx' // 子元素不保证顺序
}
2. 子组件 => 父组件
自定义事件
// 子组件
this.$emit('add', foo)
// 父组件
<Cart $add="cartAdd($event)"></Cart>
methods: {
cartAdd(data) {console.log('获取到子组件传递过来的数据:', data)}
}
3. 兄弟组件:通过共同祖辈组件
root
// 兄弟1
this.$parent.$on('foo', function() {...})
// 兄弟2
this.$parent.$emit('foo', 'foo')
4. 祖先与后代之间 provide/inject
由于嵌套层数过多,传递props不实际,vue提供了 provide/inject API完成该任务
// 祖先元素
provide() {
return {foo: 'xxxxx'}
}
// 子元素
inject: ['foo']
5. 任意两个组件之间
事件总线或vuex
// bus.js 创建一个bus类,负责事件的派发和监听,回调管理
class bus {
constructor() {
this.callbacks = {}
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name, args) {
this.callbacks[name].forEach(f => f(args))
}
}
// main.js
import Bus from './bus'
Vue.prototype.$bus = new Bus()
// comporent1
this.$bus.$on('func', function() {...})
// comporent2
this.$bus.$emit('func', 'fo')
实践中可以用Vue代替Bus,因为它已经实现了相应功能