Vue 3 毕设实战入门
背景
Vue 3 是目前国内使用最广泛的前端框架之一,面试必问、毕设高频。其渐进式设计让你能从简单的数据绑定逐步过渡到大型 SPA 应用。
核心概念
1. 响应式系统
Vue 3 使用 Proxy 实现响应式,替代了 Vue 2 的 Object.defineProperty:
import { ref, reactive, computed, watch } from 'vue'
const count = ref(0)
count.value++
const user = reactive({ name: '张三', age: 22 })
const doubled = computed(() => count.value * 2)
watch(count, (newVal, oldVal) => {
console.log(`count 从 ${oldVal} 变为 ${newVal}`)
})
2. Composition API vs Options API
| 特性 |
Options API |
Composition API |
| 数据 |
data() |
ref / reactive |
| 方法 |
methods |
普通函数 |
| 计算属性 |
computed |
computed() |
| 生命周期 |
mounted |
onMounted() |
| 逻辑复用 |
Mixins(冲突) |
自定义 Composables |
| TypeScript |
支持一般 |
原生完美支持 |
毕设建议:一律用 Composition API + <script setup>,这是 Vue 3 的默认推荐。
3. 组件通信
<!-- 父传子:props -->
<Child :title="pageTitle" :count="10" />
<!-- 子组件接收 -->
<script setup>
const props = defineProps<{ title: string; count: number }>()
</script>
<!-- 子传父:emit -->
<script setup>
const emit = defineEmits<{
update: [value: string]
close: []
}>()
</script>
4. 状态管理:Pinia
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
const token = ref('')
const userInfo = ref(null)
async function login(username: string, password: string) {
const res = await fetch('/api/login', { method: 'POST', body: JSON.stringify({ username, password }) })
const data = await res.json()
token.value = data.token
}
return { token, userInfo, login }
})
分步操作:搭建毕设基础架构
Step 1: 创建项目
npm create vue@latest my-graduation-project
cd my-graduation-project
npm install
npm run dev
Step 2: 安装 UI 组件库(Element Plus)
npm install element-plus @element-plus/icons-vue
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
Step 3: 目录结构
src/
api/ # 接口请求
components/ # 公共组件
composables/ # 自定义 hooks
stores/ # Pinia store
views/ # 页面
router/ # 路由配置
utils/ # 工具函数
Step 4: 前后端联调
import axios from 'axios'
const http = axios.create({
baseURL: 'http://localhost:3000/api',
timeout: 10000,
})
http.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
})
export default http
思考题
ref 和 reactive 有什么区别?什么场景用哪个?
- 如何用
defineExpose 向父组件暴露子组件方法?
- Vue Router 的路由守卫如何实现登录拦截?
毕设常用搭配
| 场景 |
技术栈 |
| 管理后台 |
Vue3 + Element Plus + Pinia + Axios |
| 全栈 |
Nuxt3 + Prisma + PostgreSQL |
| 移动端 |
Vue3 + Vant UI |
| 可视化 |
Vue3 + ECharts + Axios |