前言
Vue
组件传参方也是面试最常考的内容,犹记得当初刚出来实习的时候,遇到一个需求,大概就是一个tabs
下面有五个子页面,每个子页面表示订单的一种状态。当时是把五个子页面抽成了五个组件,做完后又有一个问题,就是在一个页面更改了数据状态之后,切换到另一个页面的时候要通知这个页面更新数据,当时是完全没有思路,找带我的大哥教我,讲了半天还是没有懂,最后还是大哥手把手的教我写完的,那时候觉得大哥好厉害,666,现在一想起来,不就是最简单的兄弟组件之前参数传递吗?😓今天就来回忆一下工作中常用的几种组件传参的方式。
父子组件之间传参
父子组件之间最常用的组件传参方式就是:父传子使用v-bind:attr
传递,子组件使用props
接收,子传父使用方法传递,父组件在方法参数中获取,即$emit['method':val]
,父组件使用@method
接收。
// 父传子
// 父组件
<template>
<div>
父组件
<br/>
<child :name="name" @getChild="getChild"/>
</div>
</template>
<script>
export default {
data(){
return {
name:'father'
}
},
methods:{
getChild(val){
console.log(val) // 123
}
}
}
</script>
// 子组件
<template>
<div>
子组件
<br/>
{{name}}
<button @click="toParent">传到父组件</button>
</div>
</template>
<script>
export default {
props:{
name:{ type: String, default:''}
},
data(){
return {
}
},
methods:{
toParent(){
this.$emit('getChild',123)
}
}
}
</script>
除此之外,vue
还提供了一种语法糖,可以简单的实现父子组件间数据的双向绑定。
// 父组件
<template>
<div>
父组件
<br/>
<child :name.sync="name" />
</div>
</template>
<script>
export default {
data(){
return {
name:'father'
}
}
}
</script>
// 子组件
<template>
<div>
子组件
<br/>
{{name}}
<button @click="toParent">传到父组件</button>
</div>
</template>
<script>
export default {
props:{
name:{ type: String, default:''}
},
data(){
return {
}
},
methods:{
toParent(){
this.$emit('update:name',123)
}
}
}
</script>
父组件还可以使用$refs直接调用子组件的所有属性和方法,但是并不推荐使用这种方法。
<child ref="child"></child>
// 父组件可以使用$refs.child.xxx直接调用子组件的属性和方法
兄弟组件之间传参
兄弟组件之间传参可以使用vuex
、localStorage
、sessionStorage
、EventBus
事件中转,前面三种方法无非就是找第三方把数据存起来,需要的时候再获取就行,这里主要讲一下事件中转的用法。
// 1.首先在app.vue种定义一个中转站,再挂载到全局对象上面。
// App.vue
Vue.prototype.$eventBus = new Vue()
// 2.在需要传递的页面使用$emit(eventName,params)发射参数
this.$eventBus.$emit(eventName,params)
// 3.在需要接收参数的页面使用$on(eventName,(params) => {}) 接收参数
this.$eventBus.$on(eventName,(params) => {})
这种方法其实还可以用于跨层级传参,以前我很抵触这种用法,后来用过一次之后觉得真香啊。还有需要注意的一点就是在组件销毁的时候记得移除监听的事件绑定,使用$eventBus.$off(eventName)
实现事件监听移除。
provide/inject传参
provide/inject
可以用于跨层级传参,不过只能从上到下:
// 在上级组件中使用provide修饰的数据,在下级组件中可以使用inject接收,类似于props
// 上级组件
<script>
export default {
data(){
return {
age: 12
}
},
provide(){
return {
name: 111,
age: this.age
}
}
}
// 下级组件
<script>
export default {
data(){
return {
}
},
inject:['name','age'] // 使用时当data数据使用就行
}
</script>
值得注意的是,如果上级组件传的数据是响应式的,那么接收到的数据就是响应式的,反之亦然。
以上就是我在工作中常用的组件传参方式,喜欢的话就点个赞再走吧。