Vue 3 中调用子组件方法

发布于:2025-07-18 ⋅ 阅读:(24) ⋅ 点赞:(0)

在 Vue 3 中调用子组件方法与 Vue 2 有显著差异,这源于 Vue 3 底层架构的革新。

一、核心差异对比表

特性 Vue 2 Vue 3
组件实例获取 this.$refs.childRef childRef.value
方法暴露方式 自动暴露所有方法 需手动使用 defineExpose 暴露
响应式系统 Object.defineProperty Proxy
Composition API 核心架构
类型支持 弱类型 强类型支持

二、具体实现方式对比

1. Vue 2 实现方式(Options API)
<!-- 父组件 -->
<template>
  <ChildComponent ref="childRef" />
  <button @click="callChild">调用子组件方法</button>
</template>

<script>
export default {
  methods: {
    callChild() {
      // 直接通过 $refs 访问子组件实例
      this.$refs.childRef.childMethod('参数');
    }
  }
}
</script>

<!-- 子组件 -->
<script>
export default {
  methods: {
    childMethod(param) {
      console.log('子组件方法被调用', param);
    }
  }
}
</script>
2. Vue 3 实现方式(Composition API + <script setup>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
import {onMounted, ref} from "vue";

const helloWorldRef = ref(null)
onMounted(()=>{
  helloWorldRef.value?.printLog()
})
</script>

<template>
  <HelloWorld ref="helloWorldRef"></HelloWorld>
</template>


<!-- 子组件 HelloWorld.vue -->
<script setup lang="ts">
// 必须显式暴露方法
const printLog = () => {
	console.log('Hello World ===')
}
// 关键!暴露方法给父组件
defineExpose({
	printLog
})
</script>

<template>
  <h1>Hello World</h1>
</template>


三、架构差异的本质原因

1. 响应式系统重构(Proxy vs Object.defineProperty)

Vue 3 使用 Proxy 实现响应式:

  • 封装性增强:Proxy 要求明确暴露接口
  • 性能优化:避免 Vue 2 中递归遍历所有属性
  • 安全控制:防止父组件意外修改子组件内部状态
2. 模块化与 Tree-shaking
  • 未暴露的方法不会进入父组件作用域
  • 减少不必要的代码关联
  • 提升应用可维护性

四、原理级差异总结

维度 Vue 2 Vue 3 优势
组件模型 类实例模型 函数作用域模型 更好的 Tree-shaking
访问控制 开放所有方法 白名单暴露机制 增强封装性
响应式追踪 全实例追踪 精准依赖追踪 减少不必要的渲染
内存占用 组件实例较大 轻量级代理 提升大型应用性能
TS 支持 类型推导困难 精准类型推断 开发体验提升

💡 架构演进本质:从 “组件即对象” (OOP) 到 “组件即函数” (FP) 的范式转变,体现了现代前端框架向函数式、组合式、类型安全方向的发展趋势。

这种设计变化虽然增加了显式暴露的步骤,但带来了更好的封装性、类型安全性和长期可维护性,是 Vue 框架走向成熟的重要标志。


网站公告

今日签到

点亮在社区的每一天
去签到