1.props / $emit
1.1. props
props用于父组件向子组件传递数据
父组件:
<template>
<div class="f_container">
<h2>父组件</h2>
<Son :msg="msg" :Fn="fn"></Son>
</div>
</template>
<script>
import Son from './Son'
export default {
name: 'Father',
data() {
return {
msg: '你好,我是父组件的内容'
}
},
methods: {
fn() {
alert('我是父组件的方法')
}
},
components: { Son }
}
</script>
<style scoped>
.f_container {
padding: 20px;
background-color: lightcoral;
}
</style>
子组件:
<template>
<div class="s_container">
<h2>子组件</h2>
<div>父组件传递的数据是:{{ msg }}</div>
<button @click="Fn">父组件传递到的方法</button>
</div>
</template>
<script>
export default {
name: 'Son',
// 接收父组件传递的数据
props: ['msg', 'Fn']
}
</script>
<style scoped>
.s_container {
padding: 20px;
background-color: lightgreen;
}
</style>
效果:
1.2 $emit
$emit 用于子组件向父组件传递数据。$emit 绑定一个自定义事件,当这个事件被执行的时候就会将参数传递给父组件。
父组件:
<template>
<div class="f_container">
<h2>父组件</h2>
<div>
<span>子组件传递的信息为:</span>
<span>姓名:{{ name }} 年龄:{{ age }}</span>
</div>
<Son @receiveUser="reactive"></Son>
</div>
</template>
<script>
import Son from './Son'
export default {
name: 'Father',
data() {
return {
name: '',
age: null
}
},
methods: {
reactive(val) {
this.name = val.name
this.age = val.age
}
},
components: { Son }
}
</script>
<style scoped>
.f_container {
padding: 20px;
background-color: lightcoral;
}
</style>
子组件:
<template>
<div class="s_container">
<h2>子组件</h2>
<button @click="userInfo(user)">向父组件传递数据</button>
</div>
</template>
<script>
export default {
name: 'Son',
data() {
return {
// 传向父组件的数据
user: {
name: '张三',
age: 30
}
}
},
methods: {
userInfo(user) {
// 触发父组件的方法,并传递参数user
this.$emit('receiveUser', user)
}
}
}
</script>
<style scoped>
.s_container {
padding: 20px;
background-color: lightgreen;
}
</style>
效果展示:
小结一波:
- 父传子:自定义属性
- 子传父:自定义方法
2.EventBus
在vue2中,兄弟组件之间数据共享的方案是EventBus。
使用步骤:
- 创建eventBus.js模块,并向外共享一个Vue的实例对象
- 在数据发送方,调用bus.$emit('事件名称',要发送的数据) 方法触发自定义事件
- 在数据接收方,调用bus.$on('事件名称',事件处理函数) 方法注册一个自定义事件
EventBus.js:
import Vue from 'vue'
// 向外共享Vue 的实例对象
export default new Vue()
兄弟组件(数据发送方):
<template>
<div class="s_container">
<h2>子组件(数据发送方)</h2>
<button @click="sendMsg">传数据给Son1组件</button>
</div>
</template>
<script>
// 导入 EventBus 模块
import bus from './EventBus.js'
export default {
name: 'Son',
data() {
return {
msg: '我是发送的消息'
}
},
methods: {
sendMsg() {
bus.$emit('share', this.msg)
}
}
}
</script>
<style scoped>
.s_container {
width: 100%;
padding: 20px;
background-color: lightgreen;
}
</style>
兄弟组件(数据接收方):
<template>
<div class="s_container">
<h2>子组件1(数据接收方)</h2>
<div>兄弟组件传来的数据为:{{ msg1 }}</div>
</div>
</template>
<script>
// 导入 EventBus 模块
import bus from './EventBus.js'
export default {
name: 'Son1',
data() {
return {
msg1: ''
}
},
created() {
bus.$on('share', val => {
this.msg1 = val
console.log(val)
})
}
}
</script>
<style scoped>
.s_container {
width: 100%;
padding: 20px;
background-color: lightblue;
}
</style>
效果展示:
3.ref / $refs
如果将ref用在组件身上,那么它就指向了该组件的实例。如果用在DOM元素上,就指向该DOM元素。注意:这里的ref和vue3中ref函数的区别。
我们可以在使用子组件的时候为组件绑定ref,然后通过this.$refs获取到对应的值
父组件:
<template>
<div class="f_container">
<h2>父组件</h2>
<div>
<span>子组件传递的信息为:</span>
<span>姓名:{{ name }} 年龄:{{ age }}</span>
</div>
<button @click="userinfo">获取子组件的信息</button>
<Son ref="son"></Son> <!-- ref指向子组件实例 -->
</div>
</template>
<script>
import Son from './Son'
export default {
name: 'Father',
data() {
return {
name: '',
age: null
}
},
methods: {
userinfo() {
// 获取子组件的信息
this.name = this.$refs.son.user.name
this.age = this.$refs.son.user.age
}
},
components: { Son }
}
</script>
<style scoped>
.f_container {
padding: 20px;
background-color: lightcoral;
}
</style>
子组件:
<template>
<div class="s_container">
<h2>子组件</h2>
</div>
</template>
<script>
export default {
name: 'Son',
data() {
return {
// 传向父组件的数据
user: {
name: '张三',
age: 30
}
}
}
}
</script>
<style scoped>
.s_container {
padding: 20px;
background-color: lightgreen;
}
</style>
效果展示:
4.provide / inject
这种方式是vue中依赖注入,该方法用于父子组件之间的通信,也可以用于祖孙组件之间通信。使用这种依赖注入,可以避免一层一层的传数据。
父组件:
<template>
<div class="f_container">
<h2>父组件</h2>
<Son></Son>
</div>
</template>
<script>
import Son from './Son'
export default {
name: 'Father',
data() {
return {
msg: '我是传递的数据'
}
},
provide() {
return {
msg: this.msg
}
},
components: { Son }
}
</script>
<style scoped>
.f_container {
padding: 20px;
background-color: lightcoral;
}
</style>
子组件:
<template>
<div class="s1_container">
<h2>子组件</h2>
<div>从Father 组件传递的数据是:{{ msg }}</div>
</div>
</template>
<script>
export default {
name: 'Son1',
data() {
return {}
},
inject: ['msg']
}
</script>
<style scoped>
.s1_container {
/* width: 100%; */
padding: 20px;
background-color: lightblue;
}
</style>
效果演示:
等风来,不如追风去!