props
props 用于父给子传值
// child
props: { msg: String }
// parents
<HelloWord msg='我是传个子组件的值'>
自定义事件
自定义事件用于子给父传值
// child
this.$emit('add', good)
// parent
<Card @add="cardAdd($event)"></Card>
自定义事件传参
// 一个参数
// child
this.$emit('add', good)
// parent
<Card @add="cardAdd($event)"></Card>
cardAdd (msg) {
console.log(msg)
}
// 多个参数
// child
this.$emit('add', good1, good2)
// parent
<Card @add="cardAdd(arguments)"></Card>
cardAdd (msg) {
console.log(msg[0], msg[1])
}
事件总线
任意两个组件之间传参通常使用事件总线或vuex
// Bus 事件派发,监听和回调管理
class Bus {
constructor () {
this.callbacks = []
}
$on (name, fn) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit (name, args) {
if (this.callbacks[name]) {
this.callback[name].forEach(cb => cb(args))
}
}
}
// main.js
Vue.prototype.$bus = new Bus()
// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')
vuex
创建唯一的全局数据管理者 store,通过它管理数据并通知组件状态变更
$parent/$root
兄弟组件之间的通信可以通过共同的祖辈搭桥,root
// brother1
this.$parent.$on('foo', handle)
// brother2
this.$parent.$emit('foo')
$on 与 $emit 实际上就是依靠共同的元素进行派、监听的,所以除了 $bus 外还可以通过 $parent 或 $root,及父级或祖先进行派发、监听
$children
父组件可以通过 $children 访问其子组件,从而实现父子通信
// parent
this.$children[0].xxx = 'xxx'
$children 不能够保证组件的顺序,及 $children[0] 获取到的并不一定是你想要的(组件异步加载等情况,而 $refs 则可以保证获取的是你想要得到的
$attrs/$listeners
包含了父作用域中不作为 prop 被识别(且获取)的特性绑定(class 和 style 除外)。当一组件没有声明任何 prop 时,这里会包含所有父作用域的绑定(class 和 style 除外),并且可以通过v-bind="$attrs"传入内部组件(在创建高级别组件是非常有用)
换成人话就是,如果父组件中传递的参数在子组件的 prop 中没有定义,那么他就会被放在 $attrs 中,可以通过 $attrs.xxx 获取;同理 $listeners 则是用来存储一些方法的
// child: 并未在 props 中声明 foo
<p>{{$attrs.foo}}</p>
// parent
<HelloWord foo="foo" />
ref
获取子节引用
// parent
<HelloWord ref="hw" />
mouted () {
this.$refs.hw.xx = 'xxx'
}
provide/inject
能够实现祖先和后代之间传值
// 祖先
provide () {
return {
foo: 'foo'
}
}
// 后代
inject: ['foo']
如果涉及到祖先与后代之间传参最好使用 vuex,因为 provide/inject 很难追踪数据来源,但是在开发一些组件时,它是非常方便的,可以摆脱对 vuex 的强依赖