一、父组件与子组件通信(父传子)
- 属性props
//父
<Helloworld info="Hello World!" />
//子
props:{info:String} - refs
//父
<Helloworld ref="hw" />
this.$refs.hw.xxx='xxxx'// 此处xxx对应Helloworld子组件中的数据
ps:需要注意父组件created中拿不到子组件ref,因为父组件先于子组件创建,DOM还没挂载渲染好,一般在mounted中使用 - 子元素$children
//父
this.$children[index].xx='xxx'
ps:需要注意子元素不保证顺序,也不是响应式,改值没有问题但不要试图修改、替换children树,只读
二、子组件与父组件通信
自定义事件:在子组件派发一个事件在父组件监听、处理(观察者模式?)
// 子
this.$emit('add', count)
//父
<Cart @add="onAdd($event)">// 此处是Cart组件上监听的,谁派发谁监听
三、兄弟组件通信
通过共同祖辈进行通信,$parent或$root(共同的父或共同的根)
//父
<HelloWorld msg="123" ref="hw" @add="onAdd($event)">
<HelloWorld2>
//子
<div @click="$parent.$emit('biu')">//通过父去派发,监听 本该由父亲组件来做,可以在子组件中通过父去监听
created(){
this.$parent.$on('biu',()=>{
console.log('biubiubiu~~~')
})
}
四、祖先和后代(跨代传参)
由于嵌套层数过多,传递props不切实际,Vue提供了provide/inject API完成==>实现祖先给后代传值,反过来不适用,常用于组件库的开发
//ancestor
provide(){return foo: 'foo'}//{foo:'foo'}对象函数都可以
component:{}
//descendant
inject:['foo']//数组
props:{}
五、任意两个组件之间通信:事件总线或vuex
事件总线:创建一个Bus类负责事件派发、监听和回调管理
//跟$parent和$root做中介类似,通过一个独立Vue实例做中介
//Bus事件派发、监听和回调管理---栗子1
class Bus{
constructor(){
this.callbacks={}
}
}
$on(name,fn){
this.callbacks[name]=this.callback[name]||[]
this.callbacks[name].push(fn)
}
$emit(name,args){
if(this.callbacks[name]){
this.callbacks[name].forEach(cb=>cb(args))
}
}
Vue.prototype.$bus=new Bus()//main.js
this.$bus.$on('foo',handle)//child1
this.$bus.$emit('foo')//child2
栗子2:
import Vue from 'vue';export default new Vue();//bus.js
import Bus ...; Bus.$emit('goBank',data) // child1
import Bus ...; Bus.$on('goBank',res=>{})
六、Vuex:创建全局唯一状态管理,管理数据并通知组件状态变更
插槽:Vue实现的内容分发API,用于复合组件开发。该技术在通用组件库开发中有大量应用。(基本父-->子)
一、匿名插槽
<com1>hello</comp1>//父组件传过来的值显示在子组件插槽中
<div><slot></slot></div> //comp1
二、具名插槽
将内容分发到子组件指定位置
<com2>//父
<template v-slot:default>具名插槽</template>
<template v-slot:content>内容插槽</template>
</com2>
<div>//comp2
<slot></slot>
<slot name="content"></slot>
</div>
三、作用域插槽
分发内容要用到子组件中的数据(数据由孩子组件传过来)
<com3>//父// 把v-slot的值指定为作用域上下文对象
<template v-slot:default="slotProps">
{{slotProps.foo}}</template>
//解构用法,foo对象中有bla,bar
<template v-slot:content="{bla,bar}">
{{bla}}</template>
</com3>
<div>//comp3
<slot :foo="foo"></slot>
<slot name="content" :foo="foo" ></slot>
</div>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。