vuejs-development
Comprehensive Vue.js development skill covering Composition API, reactivity system, components, directives, and modern Vue 3 patterns based on official Vue.js documentation
What this skill does
# Vue.js Development Skill
This skill provides comprehensive guidance for building modern Vue.js applications using the Composition API, reactivity system, single-file components, directives, and lifecycle hooks based on official Vue.js documentation.
## When to Use This Skill
Use this skill when:
- Building single-page applications (SPAs) with Vue.js
- Creating progressive web applications (PWAs) with Vue
- Developing interactive user interfaces with reactive data
- Building component-based architectures
- Implementing forms, data fetching, and state management
- Creating reusable UI components and libraries
- Migrating from Options API to Composition API
- Optimizing Vue application performance
- Building accessible and maintainable web applications
- Integrating with TypeScript for type-safe development
## Core Concepts
### Reactivity System
Vue's reactivity system is the core mechanism that tracks dependencies and automatically updates the DOM when data changes.
**Reactive State with ref():**
```javascript
import { ref } from 'vue'
// ref creates a reactive reference to a value
const count = ref(0)
// Access value with .value
console.log(count.value) // 0
// Modify value
count.value++
console.log(count.value) // 1
// In templates, .value is automatically unwrapped
// <template>{{ count }}</template>
```
**Reactive Objects with reactive():**
```javascript
import { reactive } from 'vue'
// reactive creates a reactive proxy of an object
const state = reactive({
name: 'Vue',
version: 3,
features: ['Composition API', 'Teleport', 'Suspense']
})
// Access and modify properties directly
console.log(state.name) // 'Vue'
state.name = 'Vue.js'
// Nested objects are also reactive
state.features.push('Fragments')
```
**When to Use ref() vs reactive():**
```javascript
// Use ref() for:
// - Primitive values (string, number, boolean)
// - Single values that need reactivity
const count = ref(0)
const message = ref('Hello')
const isActive = ref(true)
// Use reactive() for:
// - Objects with multiple properties
// - Complex data structures
const user = reactive({
id: 1,
name: 'John',
email: '[email protected]',
preferences: {
theme: 'dark',
notifications: true
}
})
```
**Computed Properties:**
```javascript
import { ref, computed } from 'vue'
const count = ref(0)
// Computed property automatically tracks dependencies
const doubled = computed(() => count.value * 2)
console.log(doubled.value) // 0
count.value = 5
console.log(doubled.value) // 10
// Writable computed
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(newValue) {
[firstName.value, lastName.value] = newValue.split(' ')
}
})
fullName.value = 'Jane Smith'
console.log(firstName.value) // 'Jane'
console.log(lastName.value) // 'Smith'
```
**Watchers:**
```javascript
import { ref, watch, watchEffect } from 'vue'
const count = ref(0)
const message = ref('Hello')
// Watch a single ref
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`)
})
// Watch multiple sources
watch([count, message], ([newCount, newMessage], [oldCount, oldMessage]) => {
console.log(`Count: ${newCount}, Message: ${newMessage}`)
})
// Watch reactive object property
const state = reactive({ count: 0 })
watch(
() => state.count,
(newValue, oldValue) => {
console.log(`State count changed from ${oldValue} to ${newValue}`)
}
)
// watchEffect automatically tracks dependencies
watchEffect(() => {
console.log(`Count is ${count.value}`)
// Automatically re-runs when count changes
})
// Immediate execution
watch(count, (newValue) => {
console.log(`Count is now ${newValue}`)
}, { immediate: true })
// Deep watching
const user = reactive({ profile: { name: 'John' } })
watch(user, (newValue) => {
console.log('User changed:', newValue)
}, { deep: true })
```
### Composition API
The Composition API provides a set of function-based APIs for organizing component logic.
**Basic Component with <script setup>:**
```vue
<script setup>
import { ref, computed, onMounted } from 'vue'
// Props
const props = defineProps({
title: String,
count: {
type: Number,
default: 0
}
})
// Emits
const emit = defineEmits(['update', 'delete'])
// Reactive state
const localCount = ref(props.count)
const message = ref('Hello Vue!')
// Computed
const doubledCount = computed(() => localCount.value * 2)
// Methods
function increment() {
localCount.value++
emit('update', localCount.value)
}
// Lifecycle
onMounted(() => {
console.log('Component mounted')
})
</script>
<template>
<div>
<h2>{{ title }}</h2>
<p>{{ message }}</p>
<p>Count: {{ localCount }}</p>
<p>Doubled: {{ doubledCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
```
**Component without <script setup> (verbose syntax):**
```vue
<script>
import { ref, computed, onMounted } from 'vue'
export default {
name: 'MyComponent',
props: {
title: String,
count: {
type: Number,
default: 0
}
},
emits: ['update', 'delete'],
setup(props, { emit }) {
const localCount = ref(props.count)
const message = ref('Hello Vue!')
const doubledCount = computed(() => localCount.value * 2)
function increment() {
localCount.value++
emit('update', localCount.value)
}
onMounted(() => {
console.log('Component mounted')
})
return {
localCount,
message,
doubledCount,
increment
}
}
}
</script>
```
### Single-File Components
Single-file components (.vue) combine template, script, and styles in one file.
**Complete SFC Example:**
```vue
<script setup>
import { ref, computed } from 'vue'
const tasks = ref([
{ id: 1, text: 'Learn Vue', completed: false },
{ id: 2, text: 'Build app', completed: false }
])
const newTaskText = ref('')
const completedCount = computed(() =>
tasks.value.filter(t => t.completed).length
)
const remainingCount = computed(() =>
tasks.value.filter(t => !t.completed).length
)
function addTask() {
if (newTaskText.value.trim()) {
tasks.value.push({
id: Date.now(),
text: newTaskText.value,
completed: false
})
newTaskText.value = ''
}
}
function toggleTask(id) {
const task = tasks.value.find(t => t.id === id)
if (task) task.completed = !task.completed
}
function removeTask(id) {
tasks.value = tasks.value.filter(t => t.id !== id)
}
</script>
<template>
<div class="todo-app">
<h1>Todo List</h1>
<div class="add-task">
<input
v-model="newTaskText"
@keyup.enter="addTask"
placeholder="Add new task"
>
<button @click="addTask">Add</button>
</div>
<ul class="task-list">
<li
v-for="task in tasks"
:key="task.id"
:class="{ completed: task.completed }"
>
<input
type="checkbox"
:checked="task.completed"
@change="toggleTask(task.id)"
>
<span>{{ task.text }}</span>
<button @click="removeTask(task.id)">Delete</button>
</li>
</ul>
<div class="stats">
<p>Completed: {{ completedCount }}</p>
<p>Remaining: {{ remainingCount }}</p>
</div>
</div>
</template>
<style scoped>
.todo-app {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.add-task {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.add-task input {
flex: 1;
padding: 8px;
font-size: 14px;
}
.task-list {
list-style: none;
padding: 0;
}
.task-list li {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
border-bottom: 1px solid #eee;
}
.task-list li.completed span {
text-decoration: line-through;
opacity: 0.6;
}
.stats {
margin-top: 20px;
padding-top: 20px;
border-top: 2px solid #eee;
}
.stats p {
margin: 5px 0;
}
</style>
```
### Template Syntax and Directives
Vue uRelated in frontend
angular-development
IncludedComprehensive Angular framework development covering components, directives, services, dependency injection, routing, and reactive programming based on official Angular documentation
javascript-fundamentals
IncludedCore JavaScript language features, patterns, and best practices including ES6+ syntax, async/await, closures, prototypes, and modern development patterns
nextjs-development
IncludedComprehensive Next.js development skill covering App Router, Server Components, data fetching, routing patterns, API routes, middleware, and full-stack Next.js applications
react-development
IncludedComprehensive React development with hooks, components, state management, context, effects, and performance optimization based on official React documentation
frontend-architecture
IncludedComponent architecture, design patterns, state management strategies, module systems, build tools, and scalable application structure
responsive-design
IncludedMobile-first responsive design covering fluid layouts, media queries, flexbox, grid, viewport units, and responsive images