DEV Community

Cover image for Feature: Vue 3 script setup
Alexandru Ghiura
Alexandru Ghiura

Posted on • Edited on • Originally published at ghalex.com

Feature: Vue 3 script setup

I have been doing a lot of Vue.js in the last 6 months and I need to say Vue is awesome.

I am coming from “React ❤️ world” but with the release of Vue 3 and composition API, writing code in Vue or writing code in React is pretty much the same.

What I want to share today is a RFC that will bring even more love for Vue from React world.

Welcome script setup

What is <script setup> ? What are we talking about here ?

We talk about a compile step for <script /> tag to improve the authoring experience when using the Composition API inside Single File Components.

Lot’s of words 😄, let me give you an example. Let’s say we have this component:

<template>
  <button @click="inc">{{ count }}</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const inc = () => count.value++

    return {
      count,
      inc,
    }
  },
}
</script>
Enter fullscreen mode Exit fullscreen mode

As you can see we have our count ref and we export it to the <template /> by return it in the setup() method.

This is pretty clear when you have few exports or one function but when the component becomes bigger and you have 10 exports or more that return becomes BIG 🤯 pretty fast.

This is where <script setup /> can help, you don’t need to return anything or use setup function. The code looks much cleaner and nice.

<template>
  <button @click="inc">{{ count }}</button>
</template>

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

  export const count = ref(0)
  export const inc = () => count.value++
</script>
Enter fullscreen mode Exit fullscreen mode

Isn’t that a piece of beauty ? ❤️ 🤩 🥳

Just export what you use in template using export keyword and you are done.

With Typescript

But what convinced me to use this and made me love this even more is the integration with Typescript, look at next example and how you define your props:

<template>
  <button>{{ computedMsg }}</button>
</template>

<script setup="props" lang="ts">
import { computed } from 'vue'

declare const props: {
  msg: string
}

export const computedMsg = computed(() => props.msg + '!!!')
</script>
Enter fullscreen mode Exit fullscreen mode

Look at those props 🤩

If you want to lean more on what is supported and how to use this please check the official page where you can find easy to read examples for all cases.

Thank you so much for reading!

If there is anything I can do to help, please reach out. Check out my blog for more articles.

Have a nice day!

Top comments (12)

Collapse
 
dennila2 profile image
Denni

Hi Alexandru
Thanks for you post!

In vue-2 I set component name like this:

<script>
const name = 'App';
export default {
  name,
};
</script>
Enter fullscreen mode Exit fullscreen mode

How can i set component name with 'vue-3 setup syntax?

Collapse
 
ghalex profile image
Alexandru Ghiura

You can still export default the component:

<script setup="props">
// ... other logic here

export default {
  name: 'ComponentName',
};
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dennila2 profile image
Denni

What if I want use imported components in SFC?

Collapse
 
ghalex profile image
Alexandru Ghiura

Hi Denni,

A good question, here is an example:

<script setup>
export { default as Foo } from './Foo.vue'
export { default as Bar } from './Bar.vue'
export const ok = Math.random()
</script>

<template>
  <Foo/>
  <Bar/>
  <component :is="ok ? Foo : Bar"/>
</template>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dennila2 profile image
Denni

Hi Alexandru,
thank you!

Collapse
 
bairrada97 profile image
bairrada97

What if we want pass arguments on setup?

Collapse
 
ghalex profile image
Alexandru Ghiura

If you ask how to use emit and other args you pass to setup() function here is an example:

<script setup="props, { emit }">
// call emit() here
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bairrada97 profile image
bairrada97

good thats what I wanted to know, thanks

Collapse
 
bairrada97 profile image
bairrada97 • Edited

It looks much more cleaner, gotta give a try

Collapse
 
defucc profile image
DeFUCC

What about defining emits used in the template with $emit('eventName')? I've found the function defineEmit(), but can't figure out how to use it...

Collapse
 
jjclxrk profile image
jjclxrk

If anyone else is stuck on this too, I eventually found the answer here: github.com/vuejs/rfcs/pull/227#iss...

const emit = defineEmit(['foo']);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dajpes profile image
dajpes

what if I want to use async/await?