组件通信方式:
1、props
适用于的场景:父子组件通信
注意事项:
①如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据
②如果父组件给子组件传递的数据(非函数):本质就是父组件给子组件传递数据
书写方式:['todos'],{type:Array},{type:Array,default:[]}
tip:路由的props
书写的形式:布尔值、对象、函数形式
2、 组件的自定义事件
1、一种组件间通信的方式,适用于:子组件===>父组件
2、使用场景:A是父组件,B是子组件,B想给A传传数据,那么就要在A中给B绑定自定义时间(事件的回调在A中)
3、绑定自定义事件:
1、第一种方式,在父组件中:
<Demo @fanglin=‘test’/>或<Demo v-on:fanglin='test'>
2、第二种方式,在父组件中:
<Demo ref='demo'/>
......
mounted(){
this.$refs.xxx.$on('fanglin',this.test)
}
3、若想让自定义时间只能触发一次,可以使用once修饰,或$once方法
4、触发自定义事件:this.$emit(‘fanglin’,数据)
5、解绑自定义事件:this.$off('fanglin')
6、组件上也可以绑定原生DOM事件,需要使用native修饰符
7、注意:通过this.$refs.xxx.$on('fanglin',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出现问题
3、全局事件总线(GlobalEventBus)
1、一种组件间通信的方式,适用于任意组件间通信
2、安装全局事件总线
new Vue({
...
beforeCreate(){
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vue
},
...
})
3、使用时间总线:
1、接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
methods(){
demo(data){...}
}
......
mounted(){
this.$bus.$on('xxx',this.demo)
}
2、提供数据:this.$bus.$emit('xxx',数据)
4、最好在beforeDestory钩子中,用$off去解绑当前组件所用的事件
4、 消息订阅与发布(pubsub)
pubsub-js,在react框架中使用比较多(发布于订阅)
适用于场景:万能
1、一种组件间通信的方式。适用于任意组件间通信
2、使用步骤:
1、安装pubsub:npm i pubsub-js
2、引入:import pubsub from 'pubsub-js'
3、接收数据:A组件想要接收数据,则在A组建中订阅消息,订阅的回调留在A组件自身
methods(){
demo(){...}
}
...
mounted(){
this.pid = pubsub.subscribe('xxx',this,demo)//订阅消息
}
4、提供数据:pubsub.publish('xxx',数据)
5、最好在beforeDestory钩子中,用pubsub.unsubscribe(pid)去<span style='color;red'>取消订阅</span>
5、Vuex(由于篇幅过长--下一篇文章有着重提及到)
适用于场景:万能
6、 插槽
1、作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于父组件==>子组件
2、分类:默认插槽、具名插槽、作用域插槽
3、使用方式:
1、默认插槽:
父组件中:
<Categroy>
<div>html结构</div>
</Categroy>
子组件中:
<template>
<div>
<slot>插槽默认内容<slot>
</div>
</template>
2、具名插槽:
父组件中:
<Categroy>
<template slot="center">
<div>html结构</div>
</template>
<template v-slot="footer">
<div>html结构</div>
</template>
</Categroy>
子组件中:
<template>
<div>
<!-- 定义插槽 -->
<slot name="center">插槽默认内容</slot>
<slot name="footer">插槽默认内容</solt>
</div>
</template>
3、作用域插槽
1、理解:数据在组件的自身,但根据数据生成的结构需要组建的使用者来决定,(game数据在Category组件中,但是用数据所遍历出来的结构由App组件决定)
2、具体编码:
父组件中:
<Category>
<template>
<ul>
<li v-for="g in scopeData.games" :key="g">{{g}}</li>
</ul>
</template>
</Category>
<Category>
<template>
<ol>
<li v-for="g in scopeData.games" :key="g">{{g}}</li>
</ol>
</template>
</Category>
子组件中:
<template>
<div>
<slot :games="games"><slot>
</div>
</template>
<script>
export default{
name:'Category',
props:['title'],
//数据在子组件自身
data(){
return {
games:['红色警戒','穿越火线','劲舞团','淮院']
}
}
}
</script>