Vue中父子组件进行通信的方式
写在前面:传参的几种方式
父子组件怎样进行通信?兄弟组件又怎样通信?
一、自定义事件—子传父
1、声明自定义事件—子组件
- 开发者为自定义组件封装的 自定义事件,必须事先在 emits 节点中声明:
//子组件index-list
export default {
name: 'index-list',
emits:['select'],
}
2、绑定自定义事件—子组件
- 为子组件绑定点击事件onItemClick,在该事件中绑定(触发)自定义事件
//子组件index-list
<ul>
<li
v-for="item in group.list"
:key="item.id"
class="item"
@click="onItemClick(item)"
>
<img class="avatar" v-lazy="item.pic" alt="">
<span class="name">{{item.name}}</span>
</li>
</ul>
3、派发自定义事件—子组件
- 在 emits 节点下声明的自定义事件,可以通过this.$emit(‘自定义事件的名称’) 方法进行触发。
- 自定义事件名称为select,传入item参数(singer)
//子组件index-list
// 为该点击事件绑定自定义事件
function onItemClick(item){//item为点击的singer数据
emit('select',item)
//自定义事件,当点击时自动将item传给使用它的组件即父组件(singer)
//this.$emit('select', item)
}
4、监听自定义事件—父组件
- 在使用自定义的组件时,可以通过== v-on==的形式 监听自定义事件 。
- 在singer组件中调用index-list,并通过v-on绑定自定义事件select,定义该事件名称为selectSinger
//父组件singer
<div class="singer" v-loading="!singers.length">
<index-list
:data="singers"
@select="selectSinger"
>
</index-list>
<router-view :singer="selectedSinger"></router-view>
</div>
5、定义自定义事件—父组件
- 在父组件中为定义名叫selectSinger的自定义select事件
//父组件singer
methods: {
selectSinger(singer){
this.selectedSinger =singer
this.$router.push({
path:`/singer/${singer.mid}`
})
}
}
二、props—父传子
1、父组件绑定动态数据
- 为父组件的子组件绑定动态数据:data=“singers”
//父组件singer
<div class="singer" v-loading="!singers.length">
<index-list
:data="singers"
@select="selectSinger"
>
</index-list>
</div>
2、父组件传入数据
- 页面初始化时就调用created钩子函数给singers赋值
//父组件singer
async created() {
const result = await getSingerList()
this.singers = result.singers
},
3、子组件接收数据
- 子组件通过props接收父组件传来的数据data(里面包含了singers)
//子组件index-list
props: {
data: {
type: Array,
default() {
return []
}
}
},
4、子组件读取数据
- 子组件通过v-for遍历即可读取数据,v-for=“group in data”
- group 是全部歌手的分类,group.list是每一组歌手数据,item是每一位歌手
//子组件index-list
<ul ref="groupRef">
<li
v-for="group in data"
:key="group.title"
class="group"
>
<h2 class="title">{{group.title}}</h2>
<ul>
<li
v-for="item in group.list"
:key="item.id"
class="item"
@click="onItemClick(item)"
>
<img class="avatar" v-lazy="item.pic" alt="">
<span class="name">{{item.name}}</span>
</li>
</ul>
</li>
</ul>
三、provide 与 inject—父传子
1、作用:
实现祖与后代组件间通信
2、套路:
父组件有一个 provide 选项来提供数据,后代组件有一个 inject选项来开始使用这些数据
3、具体写法:
主组件中:
setup(){
......
let car = reactive({name:'奔驰',price:'40万'})
provide('car',car)
......
}
后代组件中:
setup(props,context){
......
const car = inject('car')
return {car}
......
}