Vue 3 brings a lot of exciting new features to the table, one of the most powerful being the Composition API. But the Composition API also came with its own syntax, <script setup>
, designed to make your code more modular, readable, and maintainable. In this blog, we’ll take a closer look at how <script setup>
works and how to utilize it effectively in your Vue applications.
Why Use <script setup>
?
The <script setup>
syntax simplifies Vue component development by eliminating boilerplate code, like the need for export default
. It enables us to define variables, functions, and lifecycle hooks directly within the setup
scope, making it easier to manage complex state and logic in a clean and efficient way.
Let's explore <script setup>
with various examples and understand how it changes the way we work with Vue components.
Basic Usage
The core idea of <script setup>
is straightforward: it allows us to define variables, functions, and even lifecycle hooks directly inside the setup function. Here’s a quick example to show how it works.
<template>
<div>
<p>Counter: {{ count }}</p>
<button @click="increment">Increase</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
// Define a reactive variable
const count = ref(0);
// Define a function to increment the counter
function increment() {
count.value++;
}
</script>
In this example:
- We used
ref
to create a reactivecount
variable. - The
increment
function can modify this reactive value, and it will automatically update the template.
Working with Reactive Data
In Vue 3, ref
and reactive
are essential to create reactive data within components:
ref
is for primitive types like numbers or strings.reactive
is for more complex structures like objects or arrays.
import { ref, reactive } from 'vue';
const count = ref(0); // Reactive primitive type
const user = reactive({ // Reactive object
name: 'Alice',
age: 25
});
Using ref
and reactive
in this way keeps your data reactive, meaning any changes to these values automatically reflect in your template.
Computed Properties and Watchers
Vue 3 provides computed
for creating computed properties and watch
for watching changes in reactive properties. Both of these are easy to use within <script setup>
.
<script setup>
import { ref, computed, watch } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2); // Define a computed property
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`);
});
</script>
In this snippet:
doubleCount
is a computed property that doubles the value ofcount
.watch
allows us to listen for changes incount
and take action accordingly.
Lifecycle Hooks
Vue 3 allows you to use lifecycle hooks in a much simpler way within <script setup>
. Common hooks like onMounted
and onUnmounted
are available as straightforward functions.
<script setup>
import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
console.log('Component has been mounted');
});
onUnmounted(() => {
console.log('Component is about to be unmounted');
});
</script>
These hooks work just as they do in the traditional Options API but are easier to use and read.
Using Props and Emits
In <script setup>
, you can define props
and emits
easily. Vue 3 provides defineProps
and defineEmits
to declare these in a type-safe way.
<template>
<button @click="handleClick">{{ label }}</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
label: String
});
const emit = defineEmits(['click']);
function handleClick() {
emit('click');
}
</script>
In this example:
defineProps
declareslabel
as a prop, making it available in the template.defineEmits
allows us to emit custom events likeclick
to parent components.
Full Example Using <script setup>
Combining everything we've discussed, here’s a complete example of a Vue 3 component that demonstrates the power of <script setup>
:
<template>
<div>
<h1>Welcome, {{ user.name }}!</h1>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue';
const count = ref(0);
const user = reactive({ name: 'Alice', age: 25 });
const doubleCount = computed(() => count.value * 2);
watch(count, (newVal) => {
console.log(`Count is now: ${newVal}`);
});
function increment() {
count.value++;
}
onMounted(() => {
console.log('Component mounted, fetching user data...');
// Simulate fetching user data
});
</script>
Key Benefits of Using <script setup>
- Code Organization: All variables and functions are available within the same scope, making it easier to track logic flow.
- Cleaner Syntax: Eliminates boilerplate like
export default
, making code concise and to the point. - Improved Readability: Functions, data, and methods are all located in one place, improving code readability and reducing complexity.
Wrapping Up
Vue 3's <script setup>
syntax is a game-changer, offering a streamlined and efficient way to work with the Composition API. It’s particularly helpful for organizing complex state, logic, and lifecycle management in a single file component.
This syntax removes boilerplate code and allows you to focus on what really matters: building components that are powerful, readable, and maintainable. Whether you’re working on a small project or a large-scale application, <script setup>
is a tool worth adopting in your Vue 3 journey. Give it a try, and see how it transforms your development experience!