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

Vue3 + TypeScript中如何读取父组件属性?

Vue3 + TypeScript 子组件无法获取父组件state属性问题

我在编写子组件AccordionPane时,需要获取父组件AccordionControl的state属性,但注释的代码无法生效,state变量始终为null。父组件的getProps计算属性显示state prop已正确定义,但网上TypeScript相关示例较少,难以直接从JavaScript示例适配。

类型定义

export type AccordionKeys = "open" | "disabled";

export type AccordionState = {
    [key: string]: {[key in AccordionKeys]: boolean; };
}

子组件 AccordionPane 代码

<script lang="ts">
    import { AccordionState } from "@/types/global";
    import { defineComponent, useAttrs } from "vue";

    export default defineComponent({
      name: "AccordionPane",
      props: {
        panelName: {
          type: String,
          required: true,
        },
      },
      computed: {
        open(): boolean {
          // const attrs = useAttrs();
          // const state = attrs.state as AccordionState;
          // return state[this.panelName].open && !state[this.panelName].disabled;
          return true;
        },
        disabled(): boolean {
          // const attrs = useAttrs();
          // const state = attrs.state as AccordionState;
          // return state[this.panelName].disabled;

          return false;
        },
      }
    });
</script>

父组件 AccordionControl 代码

<template>
    <div class="accordionControl">
      <slot ref="content"></slot>
    </div>
    <textarea class="debug" v-model="getProps"></textarea>
</template>

<script lang="ts">
import { type AccordionState } from '@/types/global';
import { defineComponent, type PropType } from 'vue';

export default defineComponent({
  name: "AccordionControl",
  props: {
    state: {
      type: Object as PropType<AccordionState>,
      required: true,
    },
    isVert: {
      type: Boolean,
      default: false,
    },
    allOpen: {
      type: Boolean,
      default: false,
    }
  },
  computed: {
    getProps(): string {
      return JSON.stringify(this.$props, null, '  ');
    }
  }
});
</script>

问题原因与解决方法

问题根源

你试图通过useAttrs()获取父组件的state,但useAttrs()仅能获取传递给当前组件的非props属性。而父组件的state是自身的props,并没有传递给插槽内的子组件,因此子组件自然拿不到该值。

解决步骤

1. 修改父组件,通过作用域插槽传递state

在父组件的插槽中,将自身的state作为插槽props传递出去:

<template>
    <div class="accordionControl">
      <!-- 将state作为插槽props传递给子组件 -->
      <slot ref="content" :state="state"></slot>
    </div>
    <textarea class="debug" v-model="getProps"></textarea>
</template>

2. 子组件定义state props并接收

子组件显式定义state为props,直接从父组件传递的属性中获取值:

<script lang="ts">
import { AccordionState } from "@/types/global";
import { defineComponent, type PropType } from "vue";

export default defineComponent({
  name: "AccordionPane",
  props: {
    panelName: {
      type: String,
      required: true,
    },
    // 添加state props定义
    state: {
      type: Object as PropType<AccordionState>,
      required: true,
    },
  },
  computed: {
    open(): boolean {
      return this.state[this.panelName].open && !this.state[this.panelName].disabled;
    },
    disabled(): boolean {
      return this.state[this.panelName].disabled;
    },
  }
});
</script>

3. 在父组件插槽中传递state给子组件

使用AccordionControl时,通过插槽props接收state并传递给AccordionPane:

<AccordionControl :state="yourAccordionState">
  <template #default="{ state }">
    <AccordionPane panelName="panel1" :state="state" />
    <AccordionPane panelName="panel2" :state="state" />
  </template>
</AccordionControl>

这样修改后,子组件就能正确获取到父组件的state属性,计算属性也能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:37:27