Vue----组件之间的数据共享


1 组件之间的关系

在项目开发中,组件之间的关系分为如下 3 种:

  1. 父子关系
  2. 兄弟关系
  3. 后代关系

2 父子组件之间的数据共享

父子组件之间的数据共享分为:

  1. 父 -> 子共享数据
  2. 子 -> 父共享数据
  3. 父 <-> 子双向数据同步

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 总结

  1. 父子关系

    ① 父 -> 子 属性绑定
    ② 子 -> 父 事件绑定
    ③ 父 <-> 子 组件上的 v-model

  2. 兄弟关系

    ④ EventBus

  3. 后代关系

    ⑤ provide & inject

  4. 全局数据共享

    ⑥ vuex

猜你喜欢

转载自blog.csdn.net/m0_53022813/article/details/124432164