返回

直观解析Vue组件间数据传递之父子组件与兄弟组件

前端

在Vue组件化的开发理念中,组件间的有效通信是至关重要的。无论是父子组件之间的数据传递,还是兄弟组件之间的交互,都需要了解特定的方式和技巧。本文将深入探讨Vue组件间的数据传递,重点关注父子组件和兄弟组件之间的数据传递方式,并提供代码示例,清晰直观地解释了如何实现数据共享和交互。

一、父子组件间的数据传递

在父子组件之间传递数据,主要有三种方式:

  1. props

props是Vue组件间传递数据的首选方式,它允许父组件向子组件传递数据,并由子组件接收和使用。父组件通过props属性向子组件传递数据,子组件通过props中的属性来接收数据。

<!-- 父组件 -->
<template>
  <SonComponent :message="message" />
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from parent!'
    }
  }
}
</script>


<!-- 子组件 -->
<template>
  <p>{{ message }}</p>
</template>

<script>
export default {
  props: ['message']
}
</script>
  1. ref

ref属性可以获取子组件的实例,从而可以在父组件中访问子组件的方法和属性。父组件通过ref属性获取子组件的实例,然后通过this.$refs.子组件名称来访问子组件的方法和属性。

<!-- 父组件 -->
<template>
  <SonComponent ref="son" />

  <button @click="callSonMethod()">Call Son Method</button>
</template>

<script>
export default {
  methods: {
    callSonMethod() {
      this.$refs.son.someMethod()
    }
  }
}
</script>


<!-- 子组件 -->
<template>
  <p>I am a son component.</p>
</template>

<script>
export default {
  methods: {
    someMethod() {
      console.log('Son method called!')
    }
  }
}
</script>
  1. $emit

emit事件可以向父组件发送事件,父组件通过监听该事件来接收数据。子组件通过emit()方法触发事件,父组件通过v-on指令监听该事件并执行相应的操作。

<!-- 子组件 -->
<template>
  <p>
    <input v-model="message" />
    <button @click="sendMessage">Send Message</button>
  </p>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    }
  },
  methods: {
    sendMessage() {
      this.$emit('send-message', this.message)
    }
  }
}
</script>


<!-- 父组件 -->
<template>
  <SonComponent @send-message="receiveMessage" />
</template>

<script>
export default {
  methods: {
    receiveMessage(message) {
      console.log(`Received message: ${message}`)
    }
  }
}
</script>

二、兄弟组件间的数据传递

在兄弟组件之间传递数据,主要有两种方式:

  1. Vuex

Vuex是一个状态管理库,它可以在不同组件之间共享数据。通过在Vuex中定义一个store,并使用mapState()和mapActions()将store中的数据和方法映射到组件,就可以实现兄弟组件之间的数据传递。

<!-- 父组件 -->
<template>
  <SonComponent1 />
  <SonComponent2 />
</template>

<script>
import { mapState, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['incrementCount'])
  }
}
</script>


<!-- 兄弟组件1 -->
<template>
  <p>{{ count }}</p>
  <button @click="incrementCount">Increment Count</button>
</template>

<script>
export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    ...mapActions(['incrementCount'])
  }
}
</script>


<!-- 兄弟组件2 -->
<template>
  <p>{{ count }}</p>
</template>

<script>
export default {
  computed: {
    ...mapState(['count'])
  }
}
</script>
  1. 事件总线

事件总线是一种通过自定义事件来传递数据的机制。创建一个名为eventBus的JavaScript对象,并使用Vue.prototype.eventBus = eventBus将其挂载到Vue原型上。组件可以通过eventBus.emit()方法触发事件,其他组件可以通过eventBus.$on()方法监听该事件并执行相应的操作。

<!-- 父组件 -->
<template>
  <SonComponent1 />
  <SonComponent2 />
</template>

<script>
import eventBus from './event-bus'

export default {
  mounted() {
    eventBus.$on('increment-count', this.incrementCount)
  },
  beforeDestroy() {
    eventBus.$off('increment-count')
  },
  methods: {
    incrementCount() {
      this.count++
    }
  }
}
</script>


<!-- 兄弟组件1 -->
<template>
  <button @click="incrementCount">Increment Count</button>
</template>

<script>
import eventBus from './event-bus'

export default {
  methods: {
    incrementCount() {
      eventBus.$emit('increment-count')
    }
  }
}
</script>


<!-- 兄弟组件2 -->
<template>
  <p>{{ count }}</p>
</template>

<script>
import eventBus from './event-bus'

export default {
  mounted() {
    eventBus.$on('increment-count', this.incrementCount)
  },
  beforeDestroy() {
    eventBus.$off('increment-count')
  },
  methods: {
    incrementCount() {
      this.count++
    }
  }
}
</script>

以上便是Vue组件间数据传递的常见方式,希望对您有所帮助。