| name | vue |
| description | Vue.js progressive JavaScript framework for building user interfaces |
| category | web-development |
| difficulty | intermediate |
| tags | ["frontend","javascript","framework","component-based"] |
| author | Vue.js Team |
| version | 3.4 |
| last_updated | 2024-01-15T00:00:00.000Z |
Vue.js
What I Do
I am Vue.js, a progressive JavaScript framework for building user interfaces. I combine declarative rendering with reactive data binding to create interactive web applications. My core philosophy centers on being incrementally adoptable - you can start using just my template syntax and gradually incorporate more advanced features as needed. I provide a reactive system that automatically tracks dependencies and updates the DOM when your data changes, eliminating the need for manual DOM manipulation. My Single File Components (SFCs) with .vue extension allow you to encapsulate template, logic, and styles in a single, maintainable file. I offer the Composition API for flexible code organization, built-in state management through Pinia, and seamless integration with the Vue Router for single-page application development. My gentle learning curve makes me an excellent choice for teams transitioning from traditional web development to modern frameworks.
When to Use Me
- Building interactive single-page applications (SPAs)
- Creating reusable UI component libraries
- Developing progressive web applications (PWAs)
- Adding interactivity to existing server-rendered applications
- Rapid prototyping of user interfaces
- Projects requiring a gentle learning curve
- Applications needing fine-grained reactivity
- Teams transitioning from vanilla JavaScript or jQuery
Core Concepts
Reactive Data Binding: Vue's reactivity system automatically updates the DOM when reactive data changes using ref() and reactive() declarations.
Component Architecture: Build encapsulated, reusable components that manage their own state and expose props for configuration.
Directives: Special attributes like v-if, v-for, v-bind, and v-on that provide declarative behavior to templates.
Composition API: Organize component logic by concern using functions like setup(), computed(), watch(), and lifecycle hooks.
Single File Components: .vue files containing <template>, <script>, and <style> blocks for complete component encapsulation.
Pinia State Management: Modern, type-safe state management with modular stores for centralized application state.
Vue Router: Official client-side routing solution for building single-page applications with nested routes and navigation guards.
Server-Side Rendering: Nuxt.js framework enables SSR, static site generation, and SEO-friendly Vue applications.
Code Examples
Example 1: Reactive Component with Composition API
<script setup>
import { ref, computed, onMounted } from 'vue'
const props = defineProps({
userId: { type: String, required: true }
})
const user = ref(null)
const isLoading = ref(true)
const error = ref(null)
const fullName = computed(() =>
user.value ? `${user.value.firstName} ${user.value.lastName}` : ''
)
const fetchUser = async () => {
try {
isLoading.value = true
const response = await fetch(`/api/users/${props.userId}`)
if (!response.ok) throw new Error('User not found')
user.value = await response.json()
} catch (e) {
error.value = e.message
} {
isLoading. =
}
}
(fetchUser)
</script>
Example 2: Composable for Data Fetching
import { ref } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
const loading = ref(false)
const execute = async () => {
loading.value = true
error.value = null
try {
const response = await fetch(url)
if (!response.ok) throw new Error(`HTTP error ${response.status}`)
data.value = await response.json()
} catch (e) {
error.value = e.message
} finally {
loading.value = false
}
}
return { data, error, loading, execute }
}
Example 3: Pinia Store for Cart Management
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCartStore = defineStore('cart', () => {
const items = ref([])
const promoCode = ref('')
const discount = ref(0)
const totalItems = computed(() =>
items.value.reduce((sum, item) => sum + item.quantity, 0)
)
const subtotal = computed(() =>
items.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
)
const total = computed(() => subtotal.value - discount.value)
function addItem(product, quantity = 1) {
const existing = items.value.find( => i. === product.)
(existing) {
existing. += quantity
} {
items..({ ...product, quantity })
}
}
() {
items. = items..( item. !== productId)
}
() {
(code === ) discount. = subtotal. *
}
() {
items. = []
promoCode. =
discount. =
}
{
items, promoCode, discount, totalItems,
subtotal, total, addItem, removeItem,
applyPromo, clearCart
}
})
Example 4: Vue Router with Navigation Guards
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const routes = [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue')
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/views/Dashboard.vue'),
meta: { requiresAuth: true }
},
{
path: '/admin',
name: 'Admin',
component: () => import('@/views/Admin.vue'),
meta: { requiresAuth: true, role: 'admin' }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
router.beforeEach((to, from, next) => {
const authStore = useAuthStore()
if (to.meta. && !authStore.) {
({ : , : { : to. } })
} (to.. && authStore. !== to..) {
({ : })
} {
()
}
})
router
Example 5: Custom Directive for Input Validation
export default {
mounted(el, binding) {
const validateEmail = (value) => {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const isValid = regex.test(value)
el.classList.toggle('valid', isValid)
el.classList.toggle('invalid', !isValid)
return isValid
}
const onInput = () => validateEmail(el.value)
el.addEventListener('input', onInput)
el.addEventListener('blur', () => validateEmail(el.value))
if (binding.value) {
el.value = binding.value
validateEmail(el.value)
}
},
updated(el, binding) {
el.value = binding.value
el.classList.remove('valid', 'invalid')
}
}
Best Practices
- Use
<script setup> syntax for cleaner, more concise components
- Keep components small and focused on a single responsibility
- Use Pinia for state management instead of Vuex (deprecated)
- Define PropTypes with
defineProps() for type safety and documentation
- Extract reusable logic into composables for DRY code
- Use async components with
defineAsyncComponent() for code splitting
- Implement proper error boundaries with
errorCaptured() hook
- Follow consistent naming conventions: PascalCase for components, kebab-case for templates
- Use Vue DevTools for debugging and performance profiling
- Consider Nuxt.js for SSR/SSG and improved SEO
Core Competencies
- Declarative template syntax with reactive data binding
- Composition API for flexible component logic organization
- Single File Components for encapsulated, maintainable code
- Pinia state management for centralized application state
- Vue Router for client-side navigation and routing
- Transition and animation system for smooth UI changes
- Provide/inject for cross-component communication
- Custom directives for reusable DOM behaviors
- Server-side rendering capabilities with Nuxt.js
- Vue DevTools for debugging and performance monitoring