javascriptvue.jsvuejs3vue-composition-apivue-script-setup

How to use props in <script setup> in vue3


Just like the title says, related Links: New script setup (without ref sugar)

<template>
  <TopNavbar title="room" />
  <div>
    {{ no }}
  </div>
</template>

<script setup>
import TopNavbar from '@/layout/TopNavbar.vue'
import { defineProps, reactive } from 'vue'

defineProps({
  no: String
})

const state = reactive({
  room: {}
})

const init = async () => {
  // I want use props in this
  // const { data } = await getRoomByNo(props.no)
  // console.log(data);
}
init()

</script>

<style>
</style>

Solution

  • To use props with <script setup> you need to call defineProps() with the component prop options as the argument, this defines the props on the component instance and returns a reactive object with the props which you can use as follows:

    <template>
      <TopNavbar title="room" />
      <div>
        {{ no }}
      </div>
    </template>
    
    <script setup>
    import TopNavbar from "@/layout/TopNavbar.vue";
    import { defineProps, reactive } from "vue";
    
    const props = defineProps({
      no: String,
    });
    
    const { no } = toRefs(props);
    
    const state = reactive({
      room: {},
    });
    
    const init = async () => {
      const { data } = await getRoomByNo(no.value);
      console.log(data);
    };
    
    init();
    </script>
    

    If you are using typescript the alternative way to do this is pass a type only declaration and infer the prop types from that. Pro's are that you'll get stricter type safety but you cannot have default values.

    <template>
      <TopNavbar title="room" />
      <div>
        {{ no }}
      </div>
    </template>
    
    <script setup>
    import TopNavbar from "@/layout/TopNavbar.vue";
    import { defineProps, reactive } from "vue";
    
    const props = defineProps<{
      no: string,
    }>();
    
    const { no } = toRefs(props);
    
    const state = reactive({
      room: {},
    });
    
    const init = async () => {
      const { data } = await getRoomByNo(no.value);
      console.log(data);
    };
    
    init();
    </script>
    

    EDIT

    Defaults with type only props are now possible:

    interface Props {
      msg?: string
    }
    
    const props = withDefaults(defineProps<Props>(), {
      msg: 'hello'
    })