Vue 组件之间传值
父子组件之间
父组件向子组件传值
- 属性props
//child
props:{msg:String}
//parent
<child msg="由父组件传入"></child>
- 特性 $attrs
//child,并未在组件中声明props
<p>{{$attrs.msg}}<p>
//parent
<child msg="有父组件传入"></child>
- 引用
//parent
<child ref="children"></child>
mounted () {
//该方法是通过访问子组件已有的选项对其进行赋值,如果xx不存在,则会报错
this.$refs.children.xx='xxx'
}
- children
//parent
//children中的元素不保证顺序
this.$children[0].xx = 'xxx'
注意:
1、Vue中的$chilren属性始终按照创建时的先后顺序来保存子组件的实例,而不是子组件实例在整个组件树中的顺序
2、如果子组件创建完成后没有因为数据改变而改变其在组件树中的位置,那么$children中的顺序即为组件在组件树中的顺序
3、如果组件因为数据变化改变了其在组件树中的位置,那么这种变化时不能够展现在$children中的,因为$children始终按照创建的先后顺序保存组件实例
子组件向父组件传值:自定义事件
//child
//子组件派发 change 事件
this.$emit('change',value)
//parent
<child @change="onChanage($event)"></child>
注意:对于事件,谁派发谁监听,虽然上述监听函数写在了父组件中,但是真正执行监听的是派发事件的元素(子组件)
兄弟组件:通过共同父辈组件
- 通过共同父辈搭桥,$parent或者$root、总线模式
//brother1 执行
this.$parent.$on('foo',() => {...}))
//brother2派发事件
this.$parent.$emit('foo')
祖先和后代之间
- provide/inject
由于嵌套层数过多,传递props不切实际,vue提供了provide/inject API完成该任务
//ancestor
//用法类似于data
provide () {
return {
msg: 'something'
}
}
//descendant
//用法类似于props
inject: ['msg']
任意两个组件之间: 事件总线或者vuex
//Bus:事件派发、监听和回调管理
class Bus {
constructor () {
this.callback = {}
}
}
$on (name, fn){
this.callback[name] = this.callback[name]||[]
this.callback[name].push(fn)
}
$emit(name,args){
if (this.callback[name]) {
this.callback[name].forEach(element => element(args));
}
}
//main.js
Vue.$bus = new Bus()
//child1
this.$bus.$emit('change')
//child2
this.$bus.$on('change',handle)
注意,实践中,可以使用Vue代替Bus是因为Vue实现了上述代码的$on和$emit
- vuex
创建唯一的全局数据管理者store,通过它管理数据并通知组件状态变更