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

Vue3中如何判断组件的prop是否为父组件显式传入

Vue3如何区分prop是父组件显式传入还是使用默认值

核心实现思路

Vue3移除了Vue2的$options.propsData API,我们可以通过当前组件VNode上挂载的原始传入属性集合判断,该集合仅包含父组件实际传递的属性,不包含使用默认值补全的prop。


具体实现方案

方案1:基于组件实例VNode判断(推荐)

组合式API写法

<script setup>
import { getCurrentInstance } from 'vue'

// 声明带默认值的prop
const props = defineProps({
  name: {
    type: String,
    default: 'Friend'
  }
})

// 获取当前组件实例
const instance = getCurrentInstance()
// 父组件实际传入的所有属性集合
const passedProps = instance.vnode.props

// 判断name是否为显式传入
const isNameExplicitlyPassed = Reflect.has(passedProps, 'name')
// 父组件调用<Greeting name="Friend" />时返回true,调用<Greeting />时返回false
</script>

选项式API写法

export default {
  props: {
    name: {
      type: String,
      default: 'Friend'
    }
  },
  mounted() {
    // 获取父组件实际传入的属性集合
    const passedProps = this.$.vnode.props
    const isNameExplicitlyPassed = Reflect.has(passedProps, 'name')
    console.log(isNameExplicitlyPassed)
  }
}

方案2:默认值打标法(轻量场景适用)

如果不想依赖组件内部实例,也可以在默认值工厂函数中为默认值加特殊标记,后续通过标记判断:

<script setup>
import { computed } from 'vue'

const props = defineProps({
  name: {
    type: [String, Object],
    default: () => ({
      __isDefault: true,
      value: 'Friend'
    })
  }
})

// 处理为实际业务使用的name值
const name = computed(() => {
  if (typeof props.name === 'object' && props.name?.__isDefault) {
    return props.name.value
  }
  return props.name
})

// 判断是否使用了默认值
const usedDefault = typeof props.name === 'object' && props.name?.__isDefault
</script>

注意:该方案需要调整prop的类型声明,且要避免父组件传入带__isDefault标记的同名属性,否则会出现误判。


注意事项

  • getCurrentInstance仅能在setup函数或组件生命周期钩子中同步调用,异步回调中调用可能无法拿到实例。
  • 模板中使用kebab-case命名的prop,Vue会自动转为camelCase存储在vnode.props中,直接用prop声明的camelCase名称判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:36:07