Vue.js 开发指南
渐进式 JavaScript 框架,构建现代化用户界面
1. 简介
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它被设计为可以自底向上逐层应用,核心库只关注视图层,易于上手且便于与第三方库或既有项目整合。
渐进式
可以逐步采用,不必重构整个应用
响应式
数据驱动,自动更新视图
组件化
可复用的组件系统
生态丰富
完整的工具链和生态系统
2. 安装和配置
方法一:CDN 引入
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
方法二:npm 安装
npm install vue@next
# 或者
yarn add vue@next
方法三:Vite 创建项目
npm create vue@latest my-vue-app
cd my-vue-app
npm install
npm run dev
3. 基础语法
模板语法
<div id="app">
<h1>{{ title }}</h1>
<p>{{ message }}</p>
<button @click="handleClick">点击我</button>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
title: '欢迎使用 Vue.js',
message: '这是一个简单的示例'
}
},
methods: {
handleClick() {
this.message = '按钮被点击了!';
}
}
}).mount('#app');
</script>
数据绑定
<!-- 文本插值 -->
<span>{{ msg }}</span>
<!-- 属性绑定 -->
<img :src="imageSrc" :alt="imageAlt">
<!-- 双向绑定 -->
<input v-model="inputValue">
<!-- 条件渲染 -->
<p v-if="isVisible">这段文字是可见的</p>
<p v-else>这段文字是隐藏的</p>
<!-- 列表渲染 -->
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
4. 组件系统
单文件组件
<!-- UserCard.vue -->
<template>
<div class="user-card">
<img :src="user.avatar" :alt="user.name">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
<button @click="sendMessage">发送消息</button>
</div>
</template>
<script>
export default {
name: 'UserCard',
props: {
user: {
type: Object,
required: true
}
},
methods: {
sendMessage() {
this.$emit('message-sent', this.user);
}
}
}
</script>
<style scoped>
.user-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
text-align: center;
}
.user-card img {
width: 80px;
height: 80px;
border-radius: 50%;
}
</style>
Props 和 Events
<!-- 父组件 -->
<template>
<div>
<user-card
v-for="user in users"
:key="user.id"
:user="user"
@message-sent="handleMessageSent"
></user-card>
</div>
</template>
<script>
import UserCard from './UserCard.vue';
export default {
components: {
UserCard
},
data() {
return {
users: [
{ id: 1, name: '张三', email: 'zhangsan@example.com', avatar: '/avatars/1.jpg' },
{ id: 2, name: '李四', email: 'lisi@example.com', avatar: '/avatars/2.jpg' }
]
}
},
methods: {
handleMessageSent(user) {
console.log('发送消息给:', user.name);
}
}
}
</script>
5. 指令
v-if / v-else
条件渲染
<div v-if="isLoggedIn">
欢迎回来!
</div>
<div v-else>
请先登录
</div>
v-for
列表渲染
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.name }}
</li>
</ul>
v-model
双向绑定
<input v-model="message">
<textarea v-model="content"></textarea>
<select v-model="selected">
<option value="a">A</option>
<option value="b">B</option>
</select>
v-on (@)
事件监听
<button @click="handleClick">点击</button>
<input @keyup.enter="handleEnter">
<div @mouseover="handleHover">悬停</div>
6. 生命周期
创建阶段
- beforeCreate - 实例初始化之前
- created - 实例创建完成
挂载阶段
- beforeMount - 挂载开始之前
- mounted - 挂载完成
更新阶段
- beforeUpdate - 数据更新之前
- updated - 数据更新完成
销毁阶段
- beforeUnmount - 销毁之前
- unmounted - 销毁完成
export default {
data() {
return {
message: 'Hello Vue!'
}
},
beforeCreate() {
console.log('beforeCreate: 实例初始化之前');
},
created() {
console.log('created: 实例创建完成');
// 可以访问 data 和 methods
console.log(this.message);
},
beforeMount() {
console.log('beforeMount: 挂载开始之前');
},
mounted() {
console.log('mounted: 挂载完成');
// 可以访问 DOM 元素
console.log(this.$refs.myElement);
},
beforeUpdate() {
console.log('beforeUpdate: 数据更新之前');
},
updated() {
console.log('updated: 数据更新完成');
},
beforeUnmount() {
console.log('beforeUnmount: 销毁之前');
// 清理定时器、取消订阅等
},
unmounted() {
console.log('unmounted: 销毁完成');
}
}
7. 组合式 API
Vue 3 引入了组合式 API,提供了更灵活的代码组织方式和更好的 TypeScript 支持。
<template>
<div>
<h2>计数器: {{ count }}</h2>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="reset">重置</button>
<p>用户信息: {{ user.name }} - {{ user.email }}</p>
</div>
</template>
<script>
import { ref, reactive, computed, watch, onMounted } from 'vue';
export default {
setup() {
// 响应式数据
const count = ref(0);
const user = reactive({
name: '张三',
email: 'zhangsan@example.com'
});
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 方法
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => count.value = 0;
// 监听器
watch(count, (newValue, oldValue) => {
console.log(`计数从 ${oldValue} 变为 ${newValue}`);
});
// 生命周期钩子
onMounted(() => {
console.log('组件已挂载');
});
// 返回模板中需要的数据和方法
return {
count,
user,
doubleCount,
increment,
decrement,
reset
};
}
}
</script>
8. 路由
安装 Vue Router
npm install vue-router@4
路由配置
// 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',
component: About
},
{
path: '/user/:id',
name: 'User',
component: User,
props: true
},
{
path: '/dashboard',
name: 'Dashboard',
component: () => import('../views/Dashboard.vue'), // 懒加载
meta: { requiresAuth: true }
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
// 路由守卫
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
// 检查用户是否已登录
const isAuthenticated = checkAuth();
if (!isAuthenticated) {
next('/login');
} else {
next();
}
} else {
next();
}
});
export default router;
使用路由
<template>
<nav>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-link :to="{ name: 'User', params: { id: userId } }">
用户详情
</router-link>
</nav>
<router-view></router-view>
</template>
<script>
import { useRouter, useRoute } from 'vue-router';
export default {
setup() {
const router = useRouter();
const route = useRoute();
const goToUser = (userId) => {
router.push({ name: 'User', params: { id: userId } });
};
const goBack = () => {
router.go(-1);
};
return {
goToUser,
goBack,
currentRoute: route
};
}
}
</script>
9. 状态管理 (Pinia)
安装 Pinia
npm install pinia
创建 Store
// stores/user.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null,
isLoggedIn: false,
preferences: {
theme: 'light',
language: 'zh-CN'
}
}),
getters: {
userName: (state) => state.user?.name || '游客',
isAdmin: (state) => state.user?.role === 'admin'
},
actions: {
async login(credentials) {
try {
const response = await authAPI.login(credentials);
this.user = response.data.user;
this.isLoggedIn = true;
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
},
logout() {
this.user = null;
this.isLoggedIn = false;
authAPI.logout();
},
updatePreferences(newPreferences) {
this.preferences = { ...this.preferences, ...newPreferences };
}
}
});
// stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', () => {
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
const reset = () => {
count.value = 0;
};
return {
count,
increment,
decrement,
reset
};
});
在组件中使用 Store
<template>
<div>
<h2>欢迎,{{ userName }}!</h2>
<p>计数器:{{ count }}</p>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="reset">重置</button>
<button v-if="!isLoggedIn" @click="showLogin">登录</button>
<button v-else @click="logout">退出</button>
</div>
</template>
<script>
import { useUserStore } from '@/stores/user';
import { useCounterStore } from '@/stores/counter';
export default {
setup() {
const userStore = useUserStore();
const counterStore = useCounterStore();
const showLogin = () => {
// 显示登录对话框
};
return {
// 解构 store
...userStore,
...counterStore
};
}
}
</script>
10. 构建和部署
Vite 构建配置
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
},
build: {
outDir: 'dist',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'pinia'],
ui: ['element-plus']
}
}
}
},
server: {
port: 3000,
open: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
});
环境变量配置
# .env.development
VITE_APP_TITLE=Vue 应用 - 开发环境
VITE_API_BASE_URL=http://localhost:8080/api
VITE_APP_VERSION=1.0.0
# .env.production
VITE_APP_TITLE=Vue 应用
VITE_API_BASE_URL=https://api.example.com
VITE_APP_VERSION=1.0.0
部署脚本
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"deploy": "npm run build && npm run upload",
"upload": "scp -r dist/* user@server:/var/www/html/"
}
}
学习总结
Vue.js 是一个强大且灵活的前端框架,具有以下核心优势:
- 渐进式采用 - 可以逐步引入到现有项目中
- 响应式系统 - 数据变化自动更新视图
- 组件化开发 - 提高代码复用性和维护性
- 丰富的生态 - Vue Router、Pinia、Vuetify 等
- 优秀的开发体验 - 热重载、TypeScript 支持