当前位置: 首页 > article >正文

vue2和vue3组件之间的通信方式差异

Vue2 vs Vue3 组件通信方法对比

1. 父子组件通信

1.1 Props 传递

Vue2

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

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

<!-- 子组件 -->
<script>
export default {
  props: {
    message: String
  }
}
</script>

Vue3

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

<script setup>
import { ref } from 'vue'
const message = ref('Hello')
</script>

<!-- 子组件 -->
<script setup>
defineProps({
  message: String
})
</script>

1.2 自定义事件

Vue2

<!-- 子组件 -->
<template>
  <button @click="handleClick">点击</button>
</template>

<script>
export default {
  methods: {
    handleClick() {
      this.$emit('custom-event', { data: 'value' })
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <child @custom-event="handleEvent"></child>
</template>

<script>
export default {
  methods: {
    handleEvent(data) {
      console.log(data)
    }
  }
}
</script>

Vue3

<!-- 子组件 -->
<template>
  <button @click="handleClick">点击</button>
</template>

<script setup>
const emit = defineEmits(['custom-event'])

const handleClick = () => {
  emit('custom-event', { data: 'value' })
}
</script>

<!-- 父组件 -->
<template>
  <child @custom-event="handleEvent"></child>
</template>

<script setup>
const handleEvent = (data) => {
  console.log(data)
}
</script>

2. 跨层级组件通信

2.1 provide/inject

Vue2

<!-- 祖先组件 -->
<script>
export default {
  provide() {
    return {
      theme: this.theme,
      updateTheme: this.updateTheme
    }
  },
  data() {
    return {
      theme: 'dark'
    }
  },
  methods: {
    updateTheme(value) {
      this.theme = value
    }
  }
}
</script>

<!-- 后代组件 -->
<script>
export default {
  inject: ['theme', 'updateTheme']
}
</script>

Vue3

<!-- 祖先组件 -->
<script setup>
import { provide, ref } from 'vue'

const theme = ref('dark')
const updateTheme = (value) => {
  theme.value = value
}

provide('theme', {
  theme,
  updateTheme
})
</script>

<!-- 后代组件 -->
<script setup>
import { inject } from 'vue'

const { theme, updateTheme } = inject('theme')
</script>

2.2 事件总线

Vue2

// eventBus.js
import Vue from 'vue'
export const eventBus = new Vue()

// 组件 A
this.eventBus.$emit('custom-event', data)

// 组件 B
mounted() {
  this.eventBus.$on('custom-event', this.handleEvent)
},
beforeDestroy() {
  this.eventBus.$off('custom-event', this.handleEvent)
}

Vue3

// eventBus.ts
import mitt from 'mitt'
export const emitter = mitt()

// 组件 A
import { emitter } from './eventBus'
emitter.emit('custom-event', data)

// 组件 B
import { onMounted, onUnmounted } from 'vue'
import { emitter } from './eventBus'

onMounted(() => {
  emitter.on('custom-event', handleEvent)
})

onUnmounted(() => {
  emitter.off('custom-event', handleEvent)
})

3. 访问组件实例

3.1 ref 引用

Vue2

<!-- 父组件 -->
<template>
  <child-component ref="childRef"></child-component>
</template>

<script>
export default {
  mounted() {
    console.log(this.$refs.childRef.someData)
    this.$refs.childRef.someMethod()
  }
}
</script>

<!-- 子组件 -->
<script>
export default {
  data() {
    return {
      someData: 'value'
    }
  },
  methods: {
    someMethod() {
      // ...
    }
  }
}
</script>

Vue3

<!-- 父组件 -->
<template>
  <child-component ref="childRef"></child-component>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const childRef = ref(null)

onMounted(() => {
  console.log(childRef.value.someData)
  childRef.value.someMethod()
})
</script>

<!-- 子组件 -->
<script setup>
import { ref } from 'vue'

const someData = ref('value')
const someMethod = () => {
  // ...
}

defineExpose({
  someData,
  someMethod
})
</script>

3.2 父组件访问

Vue2

<!-- 子组件 -->
<script>
export default {
  methods: {
    accessParent() {
      console.log(this.$parent.parentData)
      this.$parent.parentMethod()
    }
  }
}
</script>

Vue3

<!-- 子组件 -->
<script setup>
import { getCurrentInstance } from 'vue'

const { proxy } = getCurrentInstance()
const accessParent = () => {
  console.log(proxy.$parent.parentData)
  proxy.$parent.parentMethod()
}
</script>

4. 主要差异总结

  1. 语法差异

    • Vue2 使用选项式 API
    • Vue3 推荐使用组合式 API 和 <script setup>
  2. 事件总线

    • Vue2 可以使用 Vue 实例作为事件总线
    • Vue3 移除了 $on, $off 等方法,需要使用第三方库(如 mitt)
  3. 组件实例访问

    • Vue2 可以直接访问组件实例的所有属性和方法
    • Vue3 需要通过 defineExpose 显式暴露要访问的属性和方法
  4. 响应式系统

    • Vue2 使用 Object.defineProperty
    • Vue3 使用 Proxy,提供了更好的响应式支持
  5. 性能优化

    • Vue3 提供了更好的性能优化机制
    • 组件通信的性能开销更小

5. 最佳实践建议

  1. 迁移策略

    • 逐步从 Vue2 迁移到 Vue3
    • 优先使用 Vue3 的新特性
    • 保持代码的一致性
  2. 代码组织

    • Vue3 中更推荐使用组合式 API
    • 将相关的逻辑组织在一起
    • 使用 hooks 复用逻辑
  3. 性能优化

    • 合理使用响应式数据
    • 避免不必要的组件通信
    • 及时清理事件监听器

http://www.kler.cn/a/518680.html

相关文章:

  • 【C++】特殊类设计、单例模式与类型转换
  • 探秘数据仓库新势力:网络建模
  • 基于微信的原创音乐小程序的设计与实现(LW+源码+讲解)
  • 机器人SLAM建图与自主导航
  • 2025年美赛数学建模B题管理可持续旅游
  • vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
  • 如何有效利用数据采集HTTP代理
  • ASP.NET代码审计 SQL注入篇(简单记录)
  • 2024年终总结:技术成长与突破之路
  • CCF开源发展委员会开源供应链安全工作组2025年第1期技术研讨会顺利举行
  • FastDFS的安装及使用
  • LabVIEW心音心电同步采集与实时播放
  • [c语言日寄]结构体的使用及其拓展
  • Arcgis国产化替代:Bigemap Pro正式发布
  • OpenHarmony5.0 AVPlayer新特性开发指导(二)
  • 基于本地事务表+MQ实现分布式事务
  • 计算机工程:解锁未来科技之门!
  • Spring Boot Actuator 集成 Micrometer(官网文档解读)
  • 警企联动齐发力、共筑反诈“防护墙”
  • 2025美赛B题-问题B:管理可持续旅游