文章目录
1 组件之间的关系
在项目开发中,组件之间的关系分为如下 3 种:
- 父子关系
- 兄弟关系
- 后代关系
2 父子组件之间的数据共享
父子组件之间的数据共享分为:
- 父 -> 子共享数据
- 子 -> 父共享数据
- 父 <-> 子双向数据同步
2.1 父组件向子组件共享数据
父组件通过 v-bind 属性绑定向子组件共享数据。同时,子组件需要使用 props 接收数据。
<template>
<div>
<h1>App 组件-父组件</h1>
<hr>
<Test :msg="message"></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
data() {
return {
message: 'hello vue'
}
},
components: {
Test
}
}
</script>
<style>
</style>
<template>
<div>
<h3>Test 组件-子组件</h3>
<div>{
{ msg }}</div>
<hr>
</div>
</template>
<script>
export default {
name: 'Test',
props: {
msg: String
}
}
</script>
<style>
</style>
2.2 子组件向父组件共享数据
子组件通过自定义事件的方式向父组件共享数据。
<template>
<div>
<h3>Test 组件-子组件</h3>
<div>父组件传过来的数据:{
{ msg }}</div>
<!-- 点击按钮向父组件传值 -->
<button @click="submit">向父组件传值</button>
<hr>
</div>
</template>
<script>
export default {
name: 'Test',
props: {
msg: String
},
data() {
return {
sonmsg: 'sonMessage'
}
},
emits: ['submitMsg'],
methods: {
submit() {
this.$emit( 'submitMsg', this.sonmsg )
}
}
}
</script>
<style>
</style>
<template>
<div>
<h1>App 组件-父组件</h1>
<div>子组件传递过来的值:{
{ SonMsg }}</div>
<hr>
<Test :msg="message" @submitMsg="getMsg"></Test>
</div>
</template>
<script>
import Test from './Test.vue'
export default {
name: 'App',
data() {
return {
message: 'hello vue',
SonMsg: ''
}
},
components: {
Test
},
methods: {
getMsg( val ) {
// val为子组件传过来的参数
this.SonMsg = val
}
}
}
</script>
<style>
</style>
2.3 父子组件之间数据的双向同步
父组件在使用子组件期间,可以使用 v-model 指令维护组件内外数据的双向同步。
父子组件之间通过 v-model 实现数据的双向同步,与在组件上使用 v-model 一样。
Vue----组件上的 v-model
3 兄弟组件之间的数据共享
兄弟组件之间实现数据共享的方案是 EventBus。可以借助于第三方的包 mitt 来创建 eventBus 对象,从而实现兄弟组件之间的数据共享。
3.1 安装 mitt 依赖包
在项目中运行如下的命令,安装 mitt 依赖包
npm i mitt
3.2 创建公共的 EventBus 模块
在项目中创建公共的 eventBus 模块
// 导入mitt
import mitt from 'mitt'
// 创建eventBus的实例对象
const bus = mitt()
// 将eventBus的实例对象共享出去
export default bus
3.3 在数据接发送方触发事件
在数据发送方,调用 bus.emit(‘事件名称’, 要发送的数据) 方法触发自定义事件。
<template>
<h3>Bro1 数据发送方</h3>
<div>Bro1 内的数据: {
{ bro1msg }}</div>
<button @click="send"> 发送数据 </button>
</template>
<script>
// 导入eventBus模块的,得到bus对象
import bus from './eventBus.js'
export default {
name: 'Bro1',
data() {
return {
bro1msg: 'bro1msg数据'
}
},
methods: {
send() {
// 发送数据
bus.emit( 'broSendMsg', this.bro1msg )
}
}
}
</script>
<style>
</style>
3.4 在数据接收方自定义事件
在数据接收方,调用 bus.on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件。
<template>
<h3>Bro2 数据接收方</h3>
<div>获得的数据: {
{ msg }}</div>
</template>
<script>
// 导入eventBus模块的,得到bus对象
import bus from './eventBus.js'
export default {
name: 'Bro2',
data() {
return {
msg: ''
}
},
created() {
// bus.on 方法注册一个自定义事件,通过事件的处理函数形参接收数据
bus.on( 'broSendMsg', (val)=>{
this.msg = val
} )
}
}
</script>
<style>
</style>
4 后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用 provide 和 inject 实现后代关系组件之间的数据共享。
4.1 父节点通过 provide 共享数据
父节点的组件可以通过 provide 方法,对其子孙组件共享数据。
<template>
<div>
<h1>App 组件</h1>
<div> color: {
{color}} </div>
<hr>
<Son></Son>
</div>
</template>
<script>
import Son from './son.vue'
export default {
name: 'App',
data() {
return {
color: 'red'
}
},
// provide 函数return的对象中包含了要向子孙组件共享的数据
provide() {
return {
color: this.color
}
},
components: {
Son
}
}
</script>
<style>
</style>
4.2 子孙节点通过 inject 接收数据
子孙节点可以使用 inject 数组,接收父级节点向下共享的数据。
<template>
<div>
<h3>Son 组件</h3>
<div> son_count: {
{color}} </div>
<hr>
<Grandson></Grandson>
</div>
</template>
<script>
import Grandson from './Grandson.vue'
export default {
name: 'Son',
// 子孙组件使用 inject 接收父组件共享的数据
inject: ['color'],
components: {
Grandson
}
}
</script>
<style>
</style>
<template>
<div>
<h3>Grandson 组件</h3>
<div> Grandson_count: {
{ color }} </div>
</div>
</template>
<script>
export default {
name: 'Grandson',
// 子孙组件使用 inject 接收父组件共享的数据
inject: ['color'],
}
</script>
<style>
</style>
4.3 父节点对外共享响应式的数据
父节点使用 provide 向下共享数据时,可以结合 computed 函数向下共享响应式的数据。
<template>
<div>
<h1>App 组件</h1>
<div> color: {
{color}} </div>
<div>count: {
{ count }}</div>
<button @click="add"> +1 </button>
<hr>
<Son></Son>
</div>
</template>
<script>
// 从vue中按需导入computed函数
import {
computed } from 'vue'
import Son from './son.vue'
export default {
name: 'App',
data() {
return {
count: 0,
color: 'red'
}
},
methods: {
add() {
this.count++
}
},
// provide 函数return的对象中包含了要向子孙组件共享的数据
provide() {
return {
// 使用 computed 函数,把共享数据包装为响应式数据
count: computed( ()=>this.count ),
color: this.color
}
},
components: {
Son
}
}
</script>
<style>
</style>
4.4 子孙节点使用响应式的数据
如果父级节点共享的是响应式的数据,则子孙节点必须以 .value 的形式进行使用。
<template>
<div>
<h3>Son 组件</h3>
<div> son_count: {
{color}} </div>
<div> son_count: {
{count.value}} </div>
<hr>
<Grandson></Grandson>
</div>
</template>
<script>
import Grandson from './Grandson.vue'
export default {
name: 'Son',
// 子孙组件使用 inject 接收父组件共享的数据
inject: ['color', 'count'],
components: {
Grandson
}
}
</script>
<style>
</style>
<template>
<div>
<h3>Grandson 组件</h3>
<div> Grandson_count: {
{ color }} </div>
<div> Grandson_count: {
{count.value}} </div>
</div>
</template>
<script>
export default {
name: 'Grandson',
// 子孙组件使用 inject 接收父组件共享的数据
inject: ['color', 'count'],
}
</script>
<style>
</style>
5 vuex
vuex 是终极的组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共变得高 效、清晰、且易于维护。
vuex将要共享的数据存放于一个区域,要使用共享数据的组件,直接引入。
6 总结
- 父子关系
① 父 -> 子 属性绑定
② 子 -> 父 事件绑定
③ 父 <-> 子 组件上的 v-model - 兄弟关系
④ EventBus
- 后代关系
⑤ provide & inject
- 全局数据共享
⑥ vuex