How to pass props from parent to child component in Vue3JS with typescript

Viewed 180

its my first time in VueJS and we are creating a project in class using typescript. I need to pass the properties of the tabsData variable from the parent component (the view) to the child (the view component). I pass you the code:

<script setup lang="ts">
//import { reactive, ref, computed } from "vue";
import ArgumentTabComponent from "./components/ArgumentTabComponent.vue";
import $t from "@/core/utils/i18n/translate";
import Button from "primevue/button";
import type { IntArgumentListData } from "./types/IntArgumentListData";

const tabsData: IntArgumentListData[] = [
  {
    title: "Argumento 1",
    content: "texto1",
  },
  {
    title: "Argumento 2",
    content: "texto2",
  },
  {
    title: "Argumento 3",
    content: "texto3",
  },
  {
    title: "Argumento 4",
    content: "texto4",
  },
  {
    title: "Argumento 5",
    content: "texto5",
  },
];

const handleRedirect = () => {
  alert("Aceptando!");
};
</script>

<template>
  <br />
  <h1>Argumentarios</h1>
  <div class="">
    <ArgumentTabComponent> {{ tabsData }}</ArgumentTabComponent>
    <hr />
    <Button :label="$t('common.accept')" @click="handleRedirect" />
  </div>
</template>

I have been searching a lot on the internet and YouTube but everyone uses export default {} but with TypeScript, I can't do it. What I have tried is to pass the properties as I show you:

<script setup lang="ts">
import TabView from "primevue/tabview";
import TabPanel from "primevue/tabpanel";

// Lib imports
//import { ref } from "vue";
import type { IntArgumentListData } from "../types/IntArgumentListData";

// Properties
const props = defineProps<{
  title: IntArgumentListData;
  content: IntArgumentListData;
}>();
</script>

<template>
  <br />
  <div class="">
    <TabView>
      <TabPanel v-for="tab in props" :key="tab.title" :header="tab.title">
        <p>{{ tab.content }}</p>
      </TabPanel>
    </TabView>
  </div>
  <br />
</template>

But when using this way I am getting a strange error in the parent component:

error in parent component

So I'm pretty lost. I've spent many hours trying things and thinking about it but I don't understand what I'm doing wrong. Thank you all

Message error in English:

The type '{ tabData: IntArgumentListData[]; "tab data": IntArgumentListData[]; }' cannot be assigned to type 'IntrinsicAttributes & Partial<{}> & Omit<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ tabsData: IntArgumentListData[]; }>>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>'. Property "tabsData" is missing in type "{ tabData: IntArgumentListData[]; "tab-data": IntArgumentListData[]; }", but is required in type "Omit<Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{ tabsData: IntArgumentListData[ ]; }>>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>".ts(2322)

1 Answers

You defined your props as follows:

const props = defineProps<{
  title: IntArgumentListData;
  content: IntArgumentListData;
}>();

Which means you create two props, one called title with a type of IntArgumentListData and one called content with a type of IntArgumentListData.

In your type-definition IntArgumentListData you already defined title and content

So what you want to do is presumably something like this:

const props = defineProps<{
  tabsData: IntArgumentListData[];
}>();

And in your component you only need to loop over tabsData.

NOTE: When using defineProps the props will be available in the template without using props.tabsData; although in the script setup you need to access it with props.tabsData

 <TabPanel v-for="tab in tabsData" :key="tab.title" :header="tab.title">

this prop will then be exposed on the component when used in the parent. There you will have to bind the data to the prop on component call.

 <ArgumentTabComponent :tab-data="tabsData" />

Helpful documentation links:


Can you provide an english translation of the error?

It should result in something like this:

<script setup lang="ts">
//import { reactive, ref, computed } from "vue";
import ArgumentTabComponent from "./components/ArgumentTabComponent.vue";
import $t from "@/core/utils/i18n/translate";
import Button from "primevue/button";
import type { IntArgumentListData } from "./types/IntArgumentListData";

const tabsData: IntArgumentListData[] = [
  {
    title: "Argumento 1",
    content: "texto1",
  },
  {
    title: "Argumento 2",
    content: "texto2",
  },
  {
    title: "Argumento 3",
    content: "texto3",
  },
  {
    title: "Argumento 4",
    content: "texto4",
  },
  {
    title: "Argumento 5",
    content: "texto5",
  },
];

const handleRedirect = () => {
  alert("Aceptando!");
};
</script>

<template>
  <br />
  <h1>Argumentarios</h1>
  <div class="">
    <ArgumentTabComponent :tabs-data="tabsData" />
    <hr />
    <Button :label="$t('common.accept')" @click="handleRedirect" />
  </div>
</template>

Child:

<script setup lang="ts">
import TabView from "primevue/tabview.vue";
import TabPanel from "primevue/tabpanel.vue";

// Lib imports
//import { ref } from "vue";
import type { IntArgumentListData } from "../types/IntArgumentListData";

// Properties
const props = defineProps<{
  tabsData: IntArgumentListData[];
}>();
</script>

<template>
  <br />
  <div class="">
    <TabView>
      <TabPanel v-for="tab in tabsData" :key="tab.title" :header="tab.title">
        <p>{{ tab.content }}</p>
      </TabPanel>
    </TabView>
  </div>
  <br />
</template>
Related