You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js嵌套SFC组件使用$refs调用方法报错的解决方案咨询

Vue嵌套单文件组件中通过$refs调用子组件方法的问题解决

问题概述

控制台报错:
TypeError: this.$refs.smile.sayHi is not a function

复现步骤

  • 使用npm create vue@latest创建Vue.js项目;
  • 创建src/components/Smile.vue组件;
  • 创建src/components/BigSmile.vue组件:在<script setup>中导入Smile组件,同时在常规<script>里定义sayHi方法;
  • 修改src/components/TheWelcome.vue:导入BigSmile组件并设置ref为smile,在mounted钩子中调用this.$refs.smile.sayHi();

现象:当BigSmile.vue中导入Smile组件时调用报错,移除该导入则调用正常。

核心结论

嵌套单文件组件(SFC)场景下完全可以通过$refs调用子组件方法,问题出在<script setup>与常规<script>混用时的方法暴露规则上。

原因分析

当组件使用<script setup>时,Vue会默认封装组件内部的属性和方法,常规<script>中定义的methods不会自动暴露给父组件。一旦在BigSmile.vue中启用<script setup>(哪怕只是用来导入Smile组件),组件的上下文就会被<script setup>接管,未显式暴露的sayHi方法无法被父组件的$refs访问。

解决方案

方案1:在<script setup>中显式暴露方法

使用Vue的defineExpose宏,将需要外部访问的方法暴露出去。如果要保留常规<script>的methods,可以通过getCurrentInstance获取组件实例后再暴露:

<!-- src/components/BigSmile.vue -->
<script setup>
import Smile from './Smile.vue'
import { getCurrentInstance } from 'vue'

const instance = getCurrentInstance()
// 显式暴露常规script中的sayHi方法
defineExpose({
  sayHi: instance?.proxy?.sayHi
})
</script>

<script>
export default {
  methods: {
    sayHi() {
      console.log('Hello from BigSmile!')
    }
  }
}
</script>

或者直接将方法定义在<script setup>中再暴露:

<!-- src/components/BigSmile.vue -->
<script setup>
import Smile from './Smile.vue'

const sayHi = () => {
  console.log('Hello from BigSmile!')
}

// 显式暴露方法
defineExpose({
  sayHi
})
</script>

方案2:移除<script setup>,统一使用选项式API

如果不需要<script setup>的语法糖,直接用选项式API编写组件,此时methods会自动暴露给父组件:

<!-- src/components/BigSmile.vue -->
<script>
import Smile from './Smile.vue'

export default {
  components: {
    Smile
  },
  methods: {
    sayHi() {
      console.log('Hello from BigSmile!')
    }
  }
}
</script>

总结

使用$refs调用嵌套子组件方法的关键是确保子组件的目标方法被正确暴露:

  • 若使用<script setup>,必须通过defineExpose显式声明需要外部访问的方法或属性;
  • 若使用选项式API,组件的methods默认对外暴露,无需额外操作。

内容的提问来源于stack exchange,提问作者Fandi Susanto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:02:37