🎨 Frontend
Vue.js Framework
Last updated: 2025-09-25 02:29:54
Vue.js Progressive Framework
Vue.js is a progressive JavaScript framework for building user interfaces.
Vue 3 Composition API
// Vue 3 component with Composition API
{{ title }}
Count: {{ count }}
Count is getting high!
-
{{ item.name }}
Vue Router
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import User from '../views/User.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// Lazy loading
component: () => import('../views/About.vue')
},
{
path: '/user/:id',
name: 'User',
component: User,
props: true,
meta: {
requiresAuth: true
}
},
{
path: '/admin',
children: [
{
path: '',
component: () => import('../views/AdminDashboard.vue')
},
{
path: 'users',
component: () => import('../views/AdminUsers.vue')
}
],
beforeEnter: (to, from, next) => {
// Route-specific guard
if (store.getters.isAdmin) {
next()
} else {
next('/login')
}
}
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// Global navigation guard
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !store.getters.isAuthenticated) {
next('/login')
} else {
next()
}
})
export default router
Vuex State Management
// store/index.js
import { createStore } from 'vuex'
import axios from 'axios'
const store = createStore({
state: {
user: null,
posts: [],
loading: false,
error: null
},
getters: {
isAuthenticated: state => !!state.user,
isAdmin: state => state.user?.role === 'admin',
publishedPosts: state => state.posts.filter(post => post.published)
},
mutations: {
SET_LOADING(state, loading) {
state.loading = loading
},
SET_ERROR(state, error) {
state.error = error
},
SET_USER(state, user) {
state.user = user
},
SET_POSTS(state, posts) {
state.posts = posts
},
ADD_POST(state, post) {
state.posts.push(post)
},
UPDATE_POST(state, updatedPost) {
const index = state.posts.findIndex(p => p.id === updatedPost.id)
if (index !== -1) {
state.posts.splice(index, 1, updatedPost)
}
},
DELETE_POST(state, postId) {
state.posts = state.posts.filter(p => p.id !== postId)
}
},
actions: {
async login({ commit }, credentials) {
try {
commit('SET_LOADING', true)
const response = await axios.post('/api/login', credentials)
const user = response.data.user
commit('SET_USER', user)
localStorage.setItem('token', response.data.token)
return user
} catch (error) {
commit('SET_ERROR', error.response?.data?.message || 'Login failed')
throw error
} finally {
commit('SET_LOADING', false)
}
},
async fetchPosts({ commit }) {
try {
commit('SET_LOADING', true)
const response = await axios.get('/api/posts')
commit('SET_POSTS', response.data)
} catch (error) {
commit('SET_ERROR', 'Failed to fetch posts')
} finally {
commit('SET_LOADING', false)
}
},
async createPost({ commit }, postData) {
try {
const response = await axios.post('/api/posts', postData)
commit('ADD_POST', response.data)
return response.data
} catch (error) {
commit('SET_ERROR', 'Failed to create post')
throw error
}
}
},
modules: {
// You can split state into modules
auth: {
namespaced: true,
state: {/* auth specific state */},
mutations: {/* auth specific mutations */},
actions: {/* auth specific actions */}
}
}
})
export default store
Custom Composables
// composables/useApi.js
import { ref, reactive } from 'vue'
import axios from 'axios'
export function useApi() {
const loading = ref(false)
const error = ref(null)
const request = async (config) => {
try {
loading.value = true
error.value = null
const response = await axios(config)
return response.data
} catch (err) {
error.value = err.response?.data?.message || err.message
throw err
} finally {
loading.value = false
}
}
const get = (url, config = {}) => request({ ...config, method: 'GET', url })
const post = (url, data, config = {}) => request({ ...config, method: 'POST', url, data })
const put = (url, data, config = {}) => request({ ...config, method: 'PUT', url, data })
const del = (url, config = {}) => request({ ...config, method: 'DELETE', url })
return {
loading,
error,
request,
get,
post,
put,
delete: del
}
}
// composables/useLocalStorage.js
import { ref, watch } from 'vue'
export function useLocalStorage(key, defaultValue) {
const storedValue = localStorage.getItem(key)
const value = ref(storedValue ? JSON.parse(storedValue) : defaultValue)
watch(
value,
(newValue) => {
localStorage.setItem(key, JSON.stringify(newValue))
},
{ deep: true }
)
return value
}
// Using composables in a component