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

Vue3 Options API中inject获取值为undefined的原因及解决方法

问题原因
  1. provide执行时机太晚:你把provide('isToggled')放在了按钮点击的onDigitizePolygon方法里,只有用户点击按钮时才会执行provide操作。但注入者组件在mounted阶段就尝试获取注入值,此时provide还没执行,自然拿到undefined。
  2. Options API中provide的错误用法:在Options API里,provide应该在组件初始化阶段(比如created钩子)执行,或者通过组件的provide选项声明,而不是在触发式的方法中调用——因为注入是组件初始化时就会完成的操作,晚于注入时机的provide无法被感知。
解决方案

下面提供两种符合Options API规范的解决方式:

方式一:使用组件的provide选项声明要提供的值

将响应式对象通过provide选项暴露,组件初始化时就完成提供,注入者组件可以直接拿到值,后续修改响应式对象的value时,注入者会自动感知变化。

修改后的提供者组件:

<template>
    <button id="idBtnDigitizePolygon" class="clsBtnDigitizePolygon" @click="onDigitizePolygon()" :disabled="isBtnDigitizePolygonDisabled">
        test
    </button>
</template>

<script>
import { ref } from 'vue';

export default {
    data() {
        return {
            // 将响应式对象放到data中,方便方法里修改
            isToggleBtnLabelDigitizePolygon: ref(true)
        };
    },
    props: {
        isBtnDigitizePolygonDisabled: {
            type: Boolean,
            default: false,
        },
    },
    // 通过provide选项提供响应式对象
    provide() {
        return {
            isToggled: this.isToggleBtnLabelDigitizePolygon
        };
    },
    methods: {
        onDigitizePolygon() {
            // 直接修改响应式对象的value即可,无需再次调用provide
            this.isToggleBtnLabelDigitizePolygon.value = !this.isToggleBtnLabelDigitizePolygon.value;
        },
    },
};
</script>

方式二:在created钩子中调用provide

如果更习惯用组合式API的provide函数,可以在组件的created钩子中执行provide,确保注入者初始化时能拿到值:

修改后的提供者组件:

<template>
    <button id="idBtnDigitizePolygon" class="clsBtnDigitizePolygon" @click="onDigitizePolygon()" :disabled="isBtnDigitizePolygonDisabled">
        test
    </button>
</template>

<script>
import { provide, ref } from 'vue';

export default {
    data() {
        return {
            isToggleBtnLabelDigitizePolygon: ref(true)
        };
    },
    props: {
        isBtnDigitizePolygonDisabled: {
            type: Boolean,
            default: false,
        },
    },
    created() {
        // 组件初始化时执行provide,注入者能及时获取
        provide('isToggled', this.isToggleBtnLabelDigitizePolygon);
    },
    methods: {
        onDigitizePolygon() {
            this.isToggleBtnLabelDigitizePolygon.value = !this.isToggleBtnLabelDigitizePolygon.value;
        },
    },
};
</script>

注入者组件的优化

建议使用Options API的inject选项来声明要注入的值,这样可以直接通过this访问,也能设置默认值避免undefined:

<script>
import { inject } from 'vue'

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  // 用inject选项声明要注入的key
  inject: ['isToggled'],
  mounted() {
    console.log('injected', this.isToggled); // 现在能拿到响应式ref对象
    // 监听状态变化
    this.$watch('isToggled.value', (newState) => {
      console.log('按钮切换状态:', newState);
    });
  }
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:22