Skip to content
Advertisement

Access data property of child component from parent vue 3 typescript and composition api

I have setup two components parent and child:

App.vue //Parent

<template>
  <div class="common-layout">
    <Container>
      <Header><center>Vue JS 3 (Composition API and )</center></Header>
      <Main>
        <BookForm ref="bookRef" />
        <p v-if="bookRef">{{ bookRef }}</p>
      </Main>
    </Container>
  </div>
</template>
<script setup lang="ts">
  import BookForm from "./components/organism/bookForm/index.vue"
  import { ref } from "vue"
  import {
    ElContainer as Container,
    ElHeader as Header,
    ElMain as Main,
  } from "element-plus"

  const bookRef = ref<InstanceType<typeof BookForm>>()
</script>

BookForm.vue //child

<template>
  <Row span="20">
    <Column :span="12" :offset="6">
      <!-- <HelloWorld /> -->
      <Form label-position="top">
        <Input label="Title" v-model="title" />
        <Input label="Price" v-model="price" />
        <Button label="Add" type="success" :onClick="addBook" />
      </Form>
    </Column>
  </Row>
</template>
<script setup lang="ts">
  import { ElRow as Row, ElCol as Column, ElForm as Form } from "element-plus"
  import HelloWorld from "@/components/HelloWorld.vue"
  import Input from "@/components/atom/input/index.vue"
  import Button from "@/components/atom/button/index.vue"
  import { reactive, ref } from "vue"

  interface IBook {
    title: string
    price: string | number
  }
  const books = reactive<IBook[]>([])
  const title = ref<string>("")
  const price = ref<string | number>("")

  const addBook = () => {
    books.push({ title: title.value, price: price.value })
    title.value = ""
    price.value = ""
  }
</script>

I’ve followed this thread from vue forum for the solution but I cannot retrieve data from child component into parent component.

When I console log console.log(bookRef.value) I get undefined. What is the correct way to get child component’s data with typescript and composition api setup tag ?

Advertisement

Answer

Try to use defineexpose to expose the child component properties to the parent one :

<script setup lang="ts">
  import { ElRow as Row, ElCol as Column, ElForm as Form } from "element-plus"
  import HelloWorld from "@/components/HelloWorld.vue"
  import Input from "@/components/atom/input/index.vue"
  import Button from "@/components/atom/button/index.vue"
  import { reactive, ref,defineExpose } from "vue"

  interface IBook {
    title: string
    price: string | number
  }
  const books = reactive<IBook[]>([])
  const title = ref<string>("")
  const price = ref<string | number>("")

  const addBook = () => {
    books.push({ title: title.value, price: price.value })
    title.value = ""
    price.value = ""
  }

defineExpose({
  books, title, price, addBook
})
</script>
Advertisement