Vue 组件通信
当项目中的某一部分功能经常会被复用时,每次都写一段一样的代码显然并不妥当,为了方便我们可以把这部分代码封装成一个组件,当有需要用到的时候直接引用这个组件就好了。那么如何在调用组件的时候向其传入数据以及组件中的行为如何影响到调用他的父组件,简而言之,组件之间的通信是我们需要解决的问题。而组件通信分为父子组件通信和非父子组件通信。
1、父子组件通信
父向子传值
<addScale :title="title"></addScale>
向子组件传值的方式很简单,只要通过 v-bind
绑定特性就可以了,简写就是 :title
,这样就可以向子组件中传递一个名为 title 的变量。
<div>{{title}}</div>
export default {
props: {
'title': String
}
}
那么在子组件中通过 props
声明可被接受的数据就可以在子组件中使用了,如上就是在子组件中接收一个类型为字符串的变量,如果不需要校验类型那么直接可以以数组的方式接收。
export default {
props: ['title']
}
如果变量还有声明默认值还有第三种写法:
export default {
props: {
title:{
type: String,
default: 'hello'
}
}
}
子向父发送事件
既然获取数据已经实现了,那么如何在子组件中向父组件发送事件呢,只需通过 emit
和 on
就可以实现了。
//子组件
this.$emit('getId',this.id)
// 父组件
<addScale :title="title" v-on:getId="getId(id)"></addScale>
以上,子组件通过 emit 发送了一个名为 getId 的事件,并且传递了一个 id 作为参数,在父组件中我们使用 v-on
(也可用 @getId
)来监听这个事件以实现我们想要的功能。
好用的 ref
有些时候我们也会有需要在父组件中调用子组件的方法或数据,这个时候 ref
的优势便体现出来了:
//父组件
<addGoods ref="goodItem"></addGoods>
this.$refs['goodItem'].resetSearch()
当在组件上使用 ref
特性时, ref
便指向了这个组件的实例,可以通过这种方法调用子组件上的 resetSearch
方法,当然也可以使用组件实例中的数据。
而当 ref
用在普通的 DOM 元素上时便是指向这个 DOM,可以利用它完成一些 DOM 操作。
$parent
$parent
可以让子组件调用到父组件的方法, $root
指向根节点。
2、非父子组件通信
非父子组件通信的核心是拉来一个第三方做中间人,事件的发送和监听都绑定在这个第三方实例上,我们称之为 eventbus。使用方法有两种,一种是新建一个 bus.js 里面 new 一个 Vue 实例,在需要使用的组件中引用。
//bus.js
import Vue from 'vue'
export default new Vue
//组件 A
<template>
<div id="componentA">
<button @click="send">按钮</button>
</div>
</template>
import Bus from './bus.js'
export default {
data() {
return {
message: 'how are you?'
}
},
methods: {
send () {
Bus.$emit('msg', this.message)
}
}
}
//组件 B
import Bus from './bus.js'
export default {
data() {
return {
message: ''
}
},
mounted() {
Bus.$on('msg', (e) => {
console.log(`有人向你打招呼:${e}`)
})
}
}
这样两个组件都通过中间人 Bus 来获取和发送事件,便可以实现两个组件间的通信了。
还有一种方法是将 eventbus 放在 vue 的根实例下:
new Vue({
el: '#app',
router,
render: h => h(App),
data: {
// 空的实例放到根组件下,所有的子组件都能调用
Bus: new Vue()
}
})
//组件 A
<template>
<div id="componentA">
<button @click="send">按钮</button>
</div>
</template>
export default {
data() {
return {
message: 'how are you?'
}
},
methods: {
send () {
this.$root.Bus.$emit('msg', this.message)
}
}
}
这样通过 this.$root.Bus
去调用 eventbus 可以不用单独再引入 bus.js,所有在根实例下的组件都可以调用。
以上的方法在逻辑简单的组件通信中使用是很方便的,当数据量大逻辑复杂的时候,就可以考虑使用 vuex 进行状态管理了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论