人之间的感情是复杂的以及需要维护的,那么就免不得各种打电话
你有多久没有打电话了呢?
你又有多久没有收到电话了呢?
你还记得你的手机来电铃声吗????
爸爸给儿子打电话 ☎️
父组件通过使用v-bind变量来实现数据的传入
// 父组件
<Child :name="name" :clickFn="handleClick"/>
子组件通过实现options上面的props来接受父组件传递过来的数据
props接受约束数据,下面罗列了四种方式:
// 方式1:直接传递变量名,不做任何的类型约束以及值约束
props:['name','handleClick']
// 方式2:传递变量名 + 类型的约束
props:{
name: String,
handleClick: Function
}
// 方式3 :传递变量名 + 多个类型的约束
props:{
name: [String, Number]
}
// 方式4:传递变量名 + 类型的约束 + 默认值
props:{
name:{
type:String,
default: 'zhangshan'
},
handleClick:{
type: Function,
default: ()=>{}
}
}
并且为了保证单行数据流,不会造成其他子组件使用到父组件传递过来的数据的异常,要求子组件是不能够修改props的数据的值(程序也会通过报错来告知我们)。
儿子给爸爸打电话 ☎️
vue的原型上实现了$emit的方法,用来做事件的发送
子组件会通过$emit发送事件给父组件,父组件通过v-on的形式来监听子组件发送来的事件
// 子组件
<button @click="$emit('onChildClick')">click me </button>
// 父组件
<Child @onChildClick=“onChildClick”/>
如果需要传递参数,可以直接在$emit的第二个参数处写入
// 子组件
<button @click="$emit('onChildClick', item)">click me </button>
// 父组件
<Child @onChildClick=“onChildClick”/>
onChildClick(item){
console.log('我接受到了子组件传递过来的参数啦!', item)
}
爸爸主动拿起了儿子的电话 ☎️
ref
是可以设置在子组件标签上面的一个属性,我们可以通过this.$refs.childRef
来获取到子组件的实例,从而从实例上面调用子组件的属性或者方法!
<Child ref="childRef"/>
this.$refs.childRef.onChildClick()
除了ref,还可以使用$children
来获取到子组件的实例,从而从实例上面调用子组件的属性或者方法!
this.$children[0] // 第一个孩子组件
儿子主动拿起了爸爸的电话 ☎️
在子组件可以通过this.$parent
来获取到父组件的实例,从而从实例上面调用子组件的属性或者方法!用法同上。
注:孩子有很多孩子,但是爸爸只有一个
爷爷给孙子打电话 ☎️
爷爷给孙子打电话有点累,爷爷不知道孙子的电话号码,于是发现只有必须先打给爸爸,爸爸再打给孙子!😢
爷爷说话又很慢,只能一个词一个词的说,
爷爷组件将参数一层一层原封不动的传递下去
// 爷爷
<Parent :name="name" :age="age" :gender=“gender”/>
// 父亲
<Child :name="name" :age="age" :gender=“gender”/>
props:['name', 'age', 'gender']
// 孙子
<div>{{name}} - {{age}} - {{gender}}</div>
props:['name', 'age', 'gender']
孙女羊羊🐑是我们家最聪明可爱的小萝莉!
羊羊看不下去了,于是找了个录音笔,把爷爷说的所有词录下来,然后把录音笔发给爸爸:
v-bind="$props"
传递全部的props,稍微减轻了一点工作量
// 爷爷
<Parent :name="name" :age="age" :gender=gender/>
// 爸爸 props接受 && props一起传
<Child v-bind="$props"/>
props:['name', 'age', 'gender']
// 儿子 props接受
<div>{{name}} - {{age}} - {{gender}}</div>
props:['name', 'age', 'gender']
但是发现爸爸需要把录音笔里面的所有词都全部拆解出来,再一个一个的传递给儿子,
羊羊看不下去了,告诉爸爸,你不需要听录音笔里面的词再告诉你儿子,你只需要把爷爷的这个录音笔直接给儿子啊!
v-bind="$attrs"
的其中一个功能是可以实现传递不在props里面的值,
父组件既不需要接受爷爷组件传递下来的一个一个的参数,也不需要一个一个的参数再传递下去给子组件!
// 爷爷
<Parent :name="name" :age="age" :gender=gender/>
// 父亲
<Child v-bind="$attrs"/>
// 儿子 props接受
<div>{{name}} - {{age}} - {{gender}}</div>
props:['name', 'age', 'gender']
// 儿子 props 不接受
<div>{{$attrs.name}} - {{$attrs.age}} - {{$attrs.gender}}</div>
孙子给爷爷打电话 ☎️
孙子先把电话$emit('onChildClick')
打给了爸爸,爸爸拆解了孙子要说的话,再打电话给爷爷@onChildClick="$emit('onChildClick')"
// 儿子
<button @click="$emit('onChildClick')" @click="$emit('onChildClick1')">click me </button>
// 爸爸
<Child @onChildClick="$emit('onChildClick')" @onChildClick1="$emit('onChildClick1')"/>
// 爷爷
<Parent @onChildClick="console.log('我终于收到了孙子辈的点击事件了!')" @onChildClick1="console.log('我终于收到了孙子辈的点击事件了1!')"/>
羊羊说爸爸你直接把电话转接到爷爷那里去吧!你干嘛要偷听别人通话!
v-on="$listeners"
可以实现事件的打包📦
// 儿子
<button @click="$emit('onChildClick')">click me </button>
// 爸爸
<Child v-on=“$listeners”/>
// 爷爷
<Parent @onChildClick="console.log('我终于收到了孙子辈的点击事件了!')"/>
秦始皇(老祖宗)给我打电话 ☎️
当我们的组件层级更深的时候,A -> B -> C -> D -> E -> F ,上面的方法都显得不太适用了,我们可以使用 provide & inject 来实现跨层级的数据传递。
父组件只要声明了provide
,在其子组件,孙组件,曾孙组件等能形成上下游关系的组件中交互,无论多深都能通过inject
来访问provider
中的数据。
// 最上面的组件 elForm
provide(){
return {elForm:this}
}
// 最下面的组件 elFormItem
inject:['elForm']
(葫芦娃)水娃给火娃打电话 ☎️
比较累的做法:props + emit + on
兄弟1组件emit -> 父组件on -> 兄弟2组件props
期望做法:兄弟1组件emit事件,兄弟2组件on事件
event bus
全局EventBus,虽然在某些示例中不提倡使用,但它是一种非常漂亮且简单的方法,可以跨组件之间共享数据。
1.定义一个空的Vue实例,作为中央事件总线。
2.A组件定义方法去触发自定义事件
3.B组件在钩子里面去监听
var EventBus = new Vue();
this.$bus.$emit('call',{...});
this.$bus.$on('call',($event) => {...})
vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
export default new Vuex.Store({
state: {
userInfo:{}
},
mutations: { // commit
updateUserInfo (state,Object) {
state.userInfo= Object
}
},
actions: { // dispatch 副作用
getUserInfo(context){
// 1.发送http请求,拿到用户信息数据
const userInfo = http()
// 2.通过commit发送mutation里面的方法修改state
context.commit('updateUserInfo', userInfo)
}
},
getters:{
userInfo: state.userInfo
}
})
总结
组件间的通信方式有很多种:
-
props实现数据的向下传递
-
on实现数据的发布与监听
-
parent, $children可以获取到组件的实例
-
attrs, $listeners可以实现数据/事件的打包📦运输
-
eventbus and vuex可以实现跨组件的通信
以及还有一些没有写出来的通信方式...
最后
最后,本篇也是一篇征友文,快来给我打电话吧!☎️