服务公告
Vue.js - Vue.js实战案例 配置详解
发布时间:2026-04-29 12:02
一、前言
干了X年前端,遇到过太多项目做着做着就变成屎山,组件耦合严重,状态管理混乱,代码根本没法维护。Vue.js这玩意儿入门简单,但真要写出能打的代码,还是得靠实战经验。这次把项目里踩过的坑、总结的方法全部抖出来,从项目初始化到生产部署,手把手带你走一遍。
二、操作步骤
步骤1:Node.js环境准备与版本选择
Node.js版本直接影响项目依赖的兼容性,这一步搞错后面全是坑。
# 检查当前Node.js版本
node --version
# 使用nvm管理多版本Node.js(推荐)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 安装LTS版本(Vue 3项目推荐v18及以上)
nvm install --lts
nvm use --lts
# 验证安装
node --version
npm --version预期输出:
v18.17.0
9.6.7步骤2:使用Vite创建Vue 3项目
Vite这玩意儿比webpack快太多,谁用谁知道。create-vue是官方推荐的新项目脚手架。
# 创建项目(根据需要勾选TypeScript、Vue Router、Pinia)
npm create vue@latest my-vue-project
# 进入项目目录
cd my-vue-project
# 安装依赖
npm install
# 启动开发服务器
npm run dev预期输出:
VITE v5.0.0 ready in 234 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help步骤3:项目目录结构设计
目录结构决定代码的可维护性,别TM随便堆一起。推荐按照功能模块划分。
# 推荐的目录结构
my-vue-project/
├── src/
│ ├── assets/ # 静态资源
│ ├── components/ # 公共组件
│ ├── composables/ # 组合式函数(Vue 3核心)
│ ├── layouts/ # 布局组件
│ ├── router/ # 路由配置
│ ├── stores/ # Pinia状态管理
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具函数
│ ├── views/ # 页面组件
│ ├── App.vue
│ └── main.ts
├── public/
├── index.html
├── vite.config.ts
└── package.json预期输出:
# 创建目录结构
mkdir -p src/{assets,components,composables,layouts,router,stores,styles,utils,views}
mkdir -p public步骤4:组合式组件开发实战
Composition API是Vue 3的核心,写法比Options API灵活得多,能复用逻辑。直接上实战例子。
<!-- src/composables/useUserList.ts -->
import { ref, computed, onMounted } from 'vue'
import { userStore } from '@/stores/user'
export function useUserList() {
const loading = ref(false)
const searchKeyword = ref('')
const error = ref(null)
// 从Pinia store获取数据
const userStoreInstance = userStore()
const userList = computed(() => userStoreInstance.filteredUsers(searchKeyword.value))
const total = computed(() => userStoreInstance.totalCount)
// 获取用户列表
const fetchUsers = async () => {
loading.value = true
error.value = null
try {
await userStoreInstance.fetchUserList()
} catch (e) {
error.value = '获取用户列表失败,请稍后重试'
console.error('Fetch error:', e)
} finally {
loading.value = false
}
}
onMounted(() => {
fetchUsers()
})
return {
loading,
searchKeyword,
error,
userList,
total,
fetchUsers
}
}
预期输出:
# 组件结构预览
✅ useUserList composable created
✅ 包含:loading状态、searchKeyword、error处理、userList计算属性
✅ 集成Pinia store
✅ 支持异步数据获取步骤5:Pinia状态管理配置
Pinia是Vue官方推荐的状态管理库,比Vuex简洁太多,没有mutations那套绕口的东西。
<!-- src/stores/user.ts -->
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useUserStore = defineStore('user', () => {
// State
const users = ref([])
const currentUser = ref(null)
// Getters
const totalCount = computed(() => users.value.length)
const filteredUsers = computed(() => {
return (keyword: string) => {
if (!keyword) return users.value
return users.value.filter(user =>
user.name.toLowerCase().includes(keyword.toLowerCase()) ||
user.email.toLowerCase().includes(keyword.toLowerCase())
)
}
})
// Actions
async function fetchUserList() {
const response = await fetch('/api/users')
if (!response.ok) throw new Error('Network response was not ok')
users.value = await response.json()
}
function setCurrentUser(user: any) {
currentUser.value = user
}
return {
users,
currentUser,
totalCount,
filteredUsers,
fetchUserList,
setCurrentUser
}
})
预期输出:
# Pinia Store配置完成
✅ State: users, currentUser
✅ Getters: totalCount, filteredUsers
✅ Actions: fetchUserList, setCurrentUser
✅ 使用setup语法糖,TypeScript友好步骤6:Vue Router路由守卫实战
路由守卫用来做权限控制,没有这玩意儿你的后台就TM是裸奔的。
<!-- src/router/index.ts -->
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
import { useUserStore } from '@/stores/user'
const routes: RouteRecordRaw[] = [
{
path: '/login',
name: 'Login',
component: () => import('@/views/Login.vue'),
meta: { requiresAuth: false }
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('@/views/Dashboard.vue'),
meta: { requiresAuth: true, roles: ['admin', 'user'] }
},
{
path: '/admin',
name: 'Admin',
component: () => import('@/views/Admin.vue'),
meta: { requiresAuth: true, roles: ['admin'] }
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('@/views/NotFound.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 路由守卫
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore()
const requiresAuth = to.meta.requiresAuth !== false
if (requiresAuth && !userStore.currentUser) {
// 检查本地存储的token
const token = localStorage.getItem('auth_token')
if (token) {
try {
await userStore.fetchCurrentUser()
} catch {
next({ name: 'Login', query: { redirect: to.fullPath } })
return
}
} else {
next({ name: 'Login', query: { redirect: to.fullPath } })
return
}
}
// 角色权限检查
const allowedRoles = to.meta.roles as string[] | undefined
if (allowedRoles && !allowedRoles.includes(userStore.currentUser?.role)) {
next({ name: 'Dashboard' }) // 无权限重定向到主页
return
}
next()
})
export default router
预期输出:
# Vue Router配置完成
✅ 路由配置:Login, Dashboard, Admin, NotFound
✅ 路由元信息:requiresAuth, roles
✅ 全局守卫:身份验证 + 角色权限双重检查
✅ 懒加载组件优化首屏加载步骤7:生产环境构建与优化
npm run build出来的代码直接部署?那TM肯定要吃亏。build后还要做这些优化。
# 开发环境构建(查看输出大小)
npm run build
# 查看构建输出
ls -lah dist/assets/
# 使用 gzip 预压缩(nginx配置示例)
# 在 nginx.conf 中添加:
# gzip on;
# gzip_types text/plain text/css application/json application/javascript;
# gzip_min_length 1000;预期输出:
dist/assets/index-[hash].js 128.45 KB │ gzip: 42.31 KB
dist/assets/index-[hash].css 14.22 KB │ gzip: 4.15 KB
dist/assets/vendor-[hash].js 245.67 KB │ gzip: 78.45 KB
✓ built in 2.35s
✓ compressed size reduction: 67%三、常见问题FAQ
Q1:Composition API和Options API到底用哪个?
用Composition API,没啥好纠结的。Options API的data、methods、computed全搅在一起,组件逻辑超过200行根本没法看。Composition API让你按照逻辑功能组织代码,哪里用到哪个composable直接引用,代码复用也方便。某些老项目里如果Options API跑得好好的,别TM手欠去重构。
Q2:Pinia和Vuex选哪个?小型项目需要状态管理吗?
新项目直接上Pinia,Vuex已经进入维护模式了,官方自己都在推Pinia。小型项目(非SPA、就几个简单页面)用props加$emit就够,别过度设计。什么时候需要状态管理?多个组件共享状态、页面刷新需要持久化、有异步数据流的时候。判断标准很简单:如果 props drilling超过两层,赶紧上状态管理。
Q3:keep-alive缓存组件后数据不更新怎么办?
这TM是keep-alive的经典问题。组件被缓存后不会再触发onMounted,接口数据不会刷新。解决方案有两个:一是使用onActivated钩子重新拉取数据,二是通过watch监听路由参数变化主动刷新。推荐后者,逻辑更清晰。示例:watch(() => route.params.id, () => loadData(), { immediate: true })。
Q4:生产环境部署后刷新页面404怎么解决?
这TM是路由history模式的问题,URL请求到服务器时找不到对应文件。nginx配置加上try_files就行:location / { try_files $uri $uri/ /index.html; }。Apache用mod_rewrite,核心都是把所有请求重定向到index.html,让Vue Router自己处理路由。
四、总结
Vue.js实战核心要点:环境用Vite脚手架快速启动,项目结构按功能模块划分避免屎山;组件开发用Composition API组织逻辑,composables封装复用逻辑;状态管理新项目直接Pinia,小项目别过度设计;路由守卫做身份验证和权限控制;生产环境注意代码压缩和history模式配置。前端框架只是工具,真正值钱的是项目经验和架构设计能力。
延伸阅读:
- Vue.js官方文档:https://vuejs.org/guide/
- Pinia状态管理:https://pinia.vuejs.org/
- Vite构建工具:https://vitejs.dev/
相关推荐
已经是最后一篇啦!