Bird
Raised Fist0
Vueframework~5 mins

Script setup syntax in Vue

Choose your learning style10 modes available
Introduction

The script setup syntax in Vue makes writing components simpler and cleaner by reducing extra code and boilerplate.

When you want to write Vue components with less code and easier readability.
When you want to use Composition API features without importing and returning everything manually.
When building small to medium components quickly with clear structure.
When you want better TypeScript support with less setup.
When you want to avoid the usual <code>export default</code> block and simplify component logic.
Syntax
Vue
<script setup>
import { ref } from 'vue'
// Your component logic here
const count = ref(0)
function increment() {
  count.value++
}
</script>
You do not need to write export default in script setup.
Variables and functions declared here are directly usable in the template.
Examples
Basic example showing a reactive variable used in the template.
Vue
<script setup>
import { ref } from 'vue'
const message = ref('Hello!')
</script>
<template>
  <p>{{ message }}</p>
</template>
Example with a reactive counter and a function to update it.
Vue
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
  count.value++
}
</script>
<template>
  <button @click="increment">Clicked {{ count }} times</button>
</template>
Using TypeScript with script setup for type safety.
Vue
<script setup lang="ts">
import { ref, type Ref } from 'vue'
const name: Ref<string> = ref('Vue')
</script>
<template>
  <h1>Hello, {{ name }}</h1>
</template>
Sample Program

This Vue component uses script setup to create a simple button that counts clicks. The count variable is reactive and updates the displayed number each time the button is clicked. The button includes an accessible label for screen readers.

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

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment" aria-label="Increment counter">
    Clicked {{ count }} times
  </button>
</template>
OutputSuccess
Important Notes

All top-level variables and functions in script setup are automatically exposed to the template.

You can import other modules normally inside script setup.

Use lang="ts" attribute for TypeScript support.

Summary

Script setup simplifies Vue component code by removing the need for export default.

Reactive variables and functions are directly usable in the template.

It supports TypeScript and improves readability for Composition API usage.

Practice

(1/5)
1. What is the main advantage of using <script setup> in a Vue component?
easy
A. It requires class-based components instead of functions.
B. It automatically adds CSS styles to the component.
C. It disables the use of reactive variables.
D. It removes the need for export default and simplifies code.

Solution

  1. Step 1: Understand the purpose of <script setup>

    This syntax is designed to simplify Vue components by removing boilerplate code like export default.
  2. Step 2: Compare options with this purpose

    Only It removes the need for export default and simplifies code. correctly states that it removes the need for export default and simplifies code.
  3. Final Answer:

    It removes the need for export default and simplifies code. -> Option D
  4. Quick Check:

    Script setup simplifies code = A [OK]
Hint: Remember script setup removes export default for simpler code [OK]
Common Mistakes:
  • Thinking script setup adds styles automatically
  • Believing reactive variables are disabled
  • Confusing script setup with class-based components
2. Which of the following is the correct way to declare a reactive variable inside <script setup>?
easy
A. let count = reactive(0);
B. const count = ref(0);
C. var count = reactiveRef(0);
D. const count = reactiveVar(0);

Solution

  1. Step 1: Recall Vue 3 Composition API reactive variable syntax

    Reactive variables use ref() to wrap primitive values like numbers.
  2. Step 2: Check each option

    const count = ref(0); uses ref(0), which is correct. Options A, C, and D use incorrect or non-existent functions.
  3. Final Answer:

    const count = ref(0); -> Option B
  4. Quick Check:

    Use ref() for reactive primitives = B [OK]
Hint: Use ref() for reactive primitives inside script setup [OK]
Common Mistakes:
  • Using reactive() for primitive values
  • Using undefined functions like reactiveRef or reactiveVar
  • Using var instead of const or let
3. Given the following <script setup> code, what will be rendered inside the template?
<script setup>
import { ref } from 'vue'
const message = ref('Hello')
message.value = 'Hi'
</script>

<template>
  <p>{{ message }}</p>
</template>
medium
A. <p>Hello</p>
B. Error: message is not defined
C. <p>Hi</p>
D. <p>[object Object]</p>

Solution

  1. Step 1: Understand how ref works in template interpolation

    In Vue, a ref is an object with a value property. To display the inner value, you must use message.value in script or just message in template because Vue unwraps refs in templates.
  2. Step 2: Check the template interpolation

    The template uses {{ message }}. Vue unwraps refs here, so it should display the string inside message.value, which is 'Hi'.
  3. Step 3: Identify the actual behavior

    In Vue 3 with <script setup>, refs are unwrapped automatically in templates, so it should display 'Hi'. The code sets message.value = 'Hi' correctly, so the output is 'Hi'.
  4. Final Answer:

    <p>Hi</p> -> Option C
  5. Quick Check:

    Template unwraps ref = Hi [OK]
Hint: Remember Vue unwraps refs automatically in templates [OK]
Common Mistakes:
  • Thinking you must write message.value in template
  • Confusing ref object with its value
  • Assuming message is undefined
4. Identify the error in the following <script setup> code snippet:
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0 })
function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment()">Increment</button>
  <p>Count: {{ state.count }}</p>
</template>
medium
A. There is no error; the code works correctly.
B. The increment function is not exposed to the template and cannot be called.
C. The reactive object should be declared with ref() instead of reactive().
D. The @click event syntax is incorrect; it should be v-on:click.

Solution

  1. Step 1: Analyze the reactive state and function

    The code uses reactive to create a reactive object state with a count property. The increment function modifies state.count.
  2. Step 2: Check template usage and event binding

    The template uses @click="increment()" which is valid shorthand for v-on:click. The function increment is defined in <script setup> and is automatically exposed to the template.
  3. Final Answer:

    There is no error; the code works correctly. -> Option A
  4. Quick Check:

    Script setup exposes functions automatically = C [OK]
Hint: Functions in script setup are auto-exposed to template [OK]
Common Mistakes:
  • Thinking reactive must be replaced by ref for objects
  • Believing functions need explicit export
  • Confusing @click with invalid syntax
5. You want to create a Vue component using <script setup> that fetches data asynchronously when the component mounts and stores it in a reactive variable. Which is the correct way to do this?
hard
A.
<script setup>
import { ref, onMounted } from 'vue'
const data = ref(null)
onMounted(async () => {
  const res = await fetch('https://api.example.com/data')
  data.value = await res.json()
})
</script>
B.
<script setup>
import { reactive } from 'vue'
const data = reactive(null)
async function fetchData() {
  const res = await fetch('https://api.example.com/data')
  data = await res.json()
}
fetchData()
</script>
C.
<script setup>
import { ref } from 'vue'
const data = ref(null)
fetch('https://api.example.com/data').then(res => {
  data = res.json()
})
</script>
D.
<script setup>
import { ref, onMounted } from 'vue'
const data = ref(null)
onMounted(() => {
  fetch('https://api.example.com/data').then(res => res.json()).then(json => {
    data.value = json
  })
})
</script>

Solution

  1. Step 1: Understand how to fetch data on component mount

    Use the onMounted lifecycle hook to run code after the component is ready.
  2. Step 2: Check reactive variable usage and async fetch

    Use ref(null) for reactive data. Inside onMounted, use async/await to fetch and assign data to data.value.
  3. Step 3: Evaluate each option

    <script setup>
    import { ref, onMounted } from 'vue'
    const data = ref(null)
    onMounted(async () => {
      const res = await fetch('https://api.example.com/data')
      data.value = await res.json()
    })
    </script>
    correctly uses ref, onMounted, and async/await with proper assignment to data.value.
    <script setup>
    import { reactive } from 'vue'
    const data = reactive(null)
    async function fetchData() {
      const res = await fetch('https://api.example.com/data')
      data = await res.json()
    }
    fetchData()
    </script>
    incorrectly tries to assign to a reactive object directly and calls fetchData immediately without lifecycle hook.
    <script setup>
    import { ref } from 'vue'
    const data = ref(null)
    fetch('https://api.example.com/data').then(res => {
      data = res.json()
    })
    </script>
    assigns data instead of data.value and lacks lifecycle hook.
    <script setup>
    import { ref, onMounted } from 'vue'
    const data = ref(null)
    onMounted(() => {
      fetch('https://api.example.com/data').then(res => res.json()).then(json => {
        data.value = json
      })
    })
    </script>
    uses promises correctly but
    <script setup>
    import { ref, onMounted } from 'vue'
    const data = ref(null)
    onMounted(async () => {
      const res = await fetch('https://api.example.com/data')
      data.value = await res.json()
    })
    </script>
    is cleaner and preferred with async/await.
  4. Final Answer:

    Option A code snippet -> Option A
  5. Quick Check:

    Use onMounted + ref + async/await = A [OK]
Hint: Use onMounted with async/await and ref for fetching data [OK]
Common Mistakes:
  • Assigning directly to reactive instead of .value
  • Not using lifecycle hooks for async fetch
  • Mixing reactive and ref incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard