# vue3_learning
**Repository Path**: mirror18/vue3_learning
## Basic Information
- **Project Name**: vue3_learning
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-05-06
- **Last Updated**: 2026-05-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Vue 3 完整项目手动创建指南
本文档详细记录了 Vue 3 学习项目的完整手动创建过程。通过本文档,您可以独立复现项目的每一个步骤,深入理解 Vue 3 项目的构建方式。
---
## 目录
1. [环境准备](#1-环境准备)
2. [项目初始化](#2-项目初始化)
3. [目录结构搭建](#3-目录结构搭建)
4. [核心配置文件](#4-核心配置文件)
5. [入口文件创建](#5-入口文件创建)
6. [路由系统配置](#6-路由系统配置)
7. [状态管理配置](#7-状态管理配置)
8. [组件开发](#8-组件开发)
9. [页面视图开发](#9-页面视图开发)
10. [依赖安装与测试](#10-依赖安装与测试)
---
## 1. 环境准备
### 1.1 必要环境
在开始之前,请确保您的开发环境满足以下要求:
| 环境要求 | 最低版本 | 推荐版本 | 检查命令 |
|---------|---------|---------|---------|
| Node.js | v16.x | v18.x+ | `node -v` |
| npm | v8.x | v9.x+ | `npm -v` |
### 1.2 环境检查
打开终端,执行以下命令检查环境:
```bash
# 检查 Node.js 版本
node -v
# 检查 npm 版本
npm -v
# 检查 Vue CLI(可选,用于验证安装)
vue --version
```
### 1.3 创建项目目录
```bash
# 进入工作目录
cd "c:\Users\mirror\Desktop\vue实践"
# 创建项目文件夹
mkdir vue3-learning
# 进入项目目录
cd vue3-learning
```
---
## 2. 项目初始化
### 2.1 手动初始化 package.json
手动创建 `package.json` 文件,这是 Node.js 项目的核心配置文件:
```json
{
"name": "vue3-learning",
"version": "1.0.0",
"description": "Vue 3 全面的学习示例项目",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.4.21",
"vue-router": "^4.3.0",
"pinia": "^2.1.7",
"axios": "^1.6.7"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"vite": "^4.5.2"
}
}
```
### 2.2 配置说明
| 字段 | 说明 |
|------|------|
| `name` | 项目名称 |
| `version` | 项目版本号 |
| `type: module` | 启用 ES6 模块化支持 |
| `scripts` | npm 脚本命令配置 |
| `dependencies` | 生产环境依赖 |
| `devDependencies` | 开发环境依赖 |
### 2.3 依赖说明
| 依赖包 | 版本 | 用途 |
|--------|------|------|
| vue | ^3.4.21 | Vue 3 核心框架 |
| vue-router | ^4.3.0 | Vue 官方路由管理 |
| pinia | ^2.1.7 | Vue 3 状态管理库 |
| axios | ^1.6.7 | HTTP 请求库 |
| vite | ^4.5.2 | Vite 构建工具 |
| @vitejs/plugin-vue | ^4.5.2 | Vite 的 Vue 插件 |
---
## 3. 目录结构搭建
### 3.1 创建目录结构
在项目中创建以下目录结构:
```
vue3-learning/
├── src/
│ ├── components/ # 可复用组件
│ ├── views/ # 页面视图组件
│ ├── router/ # 路由配置
│ ├── stores/ # Pinia 状态管理
│ └── assets/ # 静态资源
├── public/ # 公共资源
└── index.html # HTML 入口文件
```
### 3.2 创建命令
```bash
# Windows PowerShell
New-Item -ItemType Directory -Path src/components
New-Item -ItemType Directory -Path src/views
New-Item -ItemType Directory -Path src/router
New-Item -ItemType Directory -Path src/stores
New-Item -ItemType Directory -Path src/assets
New-Item -ItemType Directory -Path public
# 或使用 mkdir
mkdir src/components src/views src/router src/stores src/assets public
```
---
## 4. 核心配置文件
### 4.1 Vite 配置文件
创建 `vite.config.js`:
```javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
port: 3000,
open: true
}
})
```
**配置说明:**
| 配置项 | 说明 |
|--------|------|
| `plugins` | Vite 插件配置 |
| `server.port` | 开发服务器端口 |
| `server.open` | 自动打开浏览器 |
### 4.2 HTML 入口文件
创建 `index.html`:
```html
Vue 3 学习项目
```
### 4.3 全局样式文件
创建 `src/style.css`:
```css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
#app {
max-width: 1400px;
margin: 0 auto;
}
.card {
background: white;
border-radius: 12px;
padding: 24px;
margin-bottom: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
h2 {
color: #764ba2;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #667eea;
}
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
margin: 5px;
transition: transform 0.2s;
}
button:hover {
transform: translateY(-2px);
}
input, select, textarea {
padding: 8px 12px;
border: 2px solid #ddd;
border-radius: 6px;
margin: 5px;
}
.nav-menu {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 20px;
padding: 15px;
background: white;
border-radius: 12px;
}
.nav-menu a {
padding: 10px 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
text-decoration: none;
border-radius: 6px;
}
.nav-menu a.router-link-active {
background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}
.highlight-box {
background: #e8f4f8;
border-left: 4px solid #667eea;
padding: 15px;
margin: 10px 0;
}
.grid-demo {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 10px;
margin: 10px 0;
}
.code-block {
background: #f5f5f5;
padding: 15px;
border-radius: 6px;
font-family: 'Courier New', monospace;
margin: 10px 0;
}
```
---
## 5. 入口文件创建
### 5.1 主入口文件 main.js
创建 `src/main.js`:
```javascript
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import './style.css'
const app = createApp(App)
// 注册 Pinia 状态管理
app.use(createPinia())
// 注册 Vue Router
app.use(router)
// 挂载应用到 #app 元素
app.mount('#app')
```
**代码解析:**
| 代码行 | 说明 |
|--------|------|
| `createApp()` | 创建 Vue 应用实例 |
| `app.use()` | 注册插件(Pinia、Router) |
| `app.mount()` | 将应用挂载到 DOM |
### 5.2 根组件 App.vue
创建 `src/App.vue`:
```vue
Vue 3 全面学习项目
```
---
## 6. 路由系统配置
### 6.1 路由配置文件
创建 `src/router/index.js`:
```javascript
import { createRouter, createWebHistory } from 'vue-router'
// 路由懒加载
const Home = () => import('../views/Home.vue')
const ReactivityDemo = () => import('../views/ReactivityDemo.vue')
const ComputedDemo = () => import('../views/ComputedDemo.vue')
const WatchDemo = () => import('../views/WatchDemo.vue')
const LifecycleDemo = () => import('../views/LifecycleDemo.vue')
const ComponentsDemo = () => import('../views/ComponentsDemo.vue')
const ComposablesDemo = () => import('../views/ComposablesDemo.vue')
const DirectivesDemo = () => import('../views/DirectivesDemo.vue')
const RouterDemo = () => import('../views/RouterDemo.vue')
const PiniaDemo = () => import('../views/PiniaDemo.vue')
const TransitionsDemo = () => import('../views/TransitionsDemo.vue')
const HttpDemo = () => import('../views/HttpDemo.vue')
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: { title: '首页' }
},
{
path: '/reactivity',
name: 'Reactivity',
component: ReactivityDemo,
meta: { title: '响应式系统' }
},
{
path: '/computed',
name: 'Computed',
component: ComputedDemo,
meta: { title: '计算属性' }
},
{
path: '/watch',
name: 'Watch',
component: WatchDemo,
meta: { title: '监听器' }
},
{
path: '/lifecycle',
name: 'Lifecycle',
component: LifecycleDemo,
meta: { title: '生命周期' }
},
{
path: '/components',
name: 'Components',
component: ComponentsDemo,
meta: { title: '组件通信' }
},
{
path: '/composables',
name: 'Composables',
component: ComposablesDemo,
meta: { title: '组合式API' }
},
{
path: '/directives',
name: 'Directives',
component: DirectivesDemo,
meta: { title: '自定义指令' }
},
{
path: '/router',
name: 'Router',
component: RouterDemo,
meta: { title: '路由' }
},
{
path: '/pinia',
name: 'Pinia',
component: PiniaDemo,
meta: { title: '状态管理' }
},
{
path: '/transitions',
name: 'Transitions',
component: TransitionsDemo,
meta: { title: '过渡动画' }
},
{
path: '/http',
name: 'Http',
component: HttpDemo,
meta: { title: 'HTTP请求' }
},
{
path: '/:pathMatch(.*)*',
redirect: '/'
}
]
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
}
})
router.beforeEach((to, from, next) => {
document.title = to.meta.title ? `${to.meta.title} - Vue3学习` : 'Vue3学习'
console.log(`路由切换: ${from.path} -> ${to.path}`)
next()
})
router.afterEach((to, from) => {
console.log(`路由已切换到: ${to.path}`)
})
export default router
```
**路由配置说明:**
| 配置项 | 说明 |
|--------|------|
| `path` | 路由路径 |
| `name` | 路由名称(用于编程式导航) |
| `component` | 对应的组件 |
| `meta` | 元信息(页面标题等) |
| `redirect` | 重定向配置 |
**路由守卫说明:**
| 守卫 | 说明 |
|------|------|
| `beforeEach` | 全局前置守卫 |
| `afterEach` | 全局后置守卫 |
---
## 7. 状态管理配置
### 7.1 Pinia Store 创建
创建 `src/stores/userStore.js`:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useUserStore = defineStore('user', () => {
// ==================== 状态定义 ====================
const userInfo = ref({
id: 1,
name: '张三',
email: 'zhangsan@example.com',
role: 'admin'
})
const preferences = ref({
theme: 'light',
language: 'zh-CN',
notifications: true
})
const friends = ref([
{ id: 1, name: '李四', online: true },
{ id: 2, name: '王五', online: false },
{ id: 3, name: '赵六', online: true }
])
const isLoading = ref(false)
// ==================== 计算属性 ====================
const onlineFriendsCount = computed(() => {
return friends.value.filter(friend => friend.online).length
})
const offlineFriendsCount = computed(() => {
return friends.value.filter(friend => !friend.online).length
})
const isAdmin = computed(() => {
return userInfo.value.role === 'admin'
})
const userDisplayName = computed(() => {
return `${userInfo.value.name} (${userInfo.value.email})`
})
// ==================== 方法 ====================
function updateUserInfo(newInfo) {
userInfo.value = { ...userInfo.value, ...newInfo }
}
function updatePreferences(newPreferences) {
preferences.value = { ...preferences.value, ...newPreferences }
}
function addFriend(friend) {
friends.value.push({
id: Date.now(),
name: friend.name,
online: friend.online || false
})
}
function removeFriend(friendId) {
const index = friends.value.findIndex(f => f.id === friendId)
if (index > -1) {
friends.value.splice(index, 1)
}
}
function toggleFriendOnline(friendId) {
const friend = friends.value.find(f => f.id === friendId)
if (friend) {
friend.online = !friend.online
}
}
async function login(username, password) {
isLoading.value = true
try {
await new Promise(resolve => setTimeout(resolve, 1000))
userInfo.value = {
id: Date.now(),
name: username,
email: `${username}@example.com`,
role: 'user'
}
return { success: true }
} catch (error) {
return { success: false, error: error.message }
} finally {
isLoading.value = false
}
}
function logout() {
userInfo.value = {
id: null,
name: '游客',
email: '',
role: 'guest'
}
}
return {
userInfo,
preferences,
friends,
isLoading,
onlineFriendsCount,
offlineFriendsCount,
isAdmin,
userDisplayName,
updateUserInfo,
updatePreferences,
addFriend,
removeFriend,
toggleFriendOnline,
login,
logout
}
})
```
**Pinia Store 结构说明:**
| 部分 | 说明 |
|------|------|
| `state` | 状态数据(使用 ref) |
| `getters` | 计算属性(使用 computed) |
| `actions` | 操作方法(函数) |
---
## 8. 组件开发
### 8.1 组件创建规范
在 Vue 3 中,推荐使用 `
```
### 8.2 子组件示例
**PropsChild.vue - 演示 Props 用法:**
```vue
{{ title }}
接收到的消息: {{ message }}
接收到的计数: {{ count }}
```
**EmitChild.vue - 演示 Emit 用法:**
```vue
```
### 8.3 插槽组件示例
**SlotChild.vue - 演示插槽用法:**
```vue
```
---
## 9. 页面视图开发
### 9.1 首页视图
创建 `src/views/Home.vue`:
```vue
欢迎学习 Vue 3!
📚 学习路线
本项目涵盖了 Vue 3 的所有核心概念,请按顺序学习以下内容:
1. 响应式系统
学习 ref 和 reactive 创建响应式数据
开始学习 →
2. 计算属性
学习 computed 处理复杂逻辑
开始学习 →
```
### 9.2 响应式示例视图
创建 `src/views/ReactivityDemo.vue`:
```vue
响应式系统 (Reactivity)
1. ref() - 基础类型响应式
ref 用于创建基本类型的响应式数据
计数器值: {{ count }}
计数器翻倍: {{ count * 2 }}
2. reactive() - 对象响应式
reactive 用于创建对象或数组的响应式数据
姓名: {{ user.name }}
年龄: {{ user.age }}
```
### 9.3 计算属性视图
创建 `src/views/ComputedDemo.vue`:
```vue
```
---
## 10. 依赖安装与测试
### 10.1 安装依赖
```bash
# 进入项目目录
cd vue3-learning
# 安装所有依赖
npm install
```
**预期输出:**
```
added XX packages in Xs
```
### 10.2 启动开发服务器
```bash
# 启动开发服务器
npm run dev
```
**预期输出:**
```
VITE v4.5.14 ready in XXX ms
Local: http://127.0.0.1:3000/
Network: use --host to expose
```
### 10.3 构建生产版本
```bash
# 构建生产版本
npm run build
```
**预期输出:**
```
vite v4.5.14 building for production...
dist/assets/... X.XX KB
...
```
### 10.4 预览生产版本
```bash
# 预览生产版本
npm run preview
```
---
## 附录:常用命令汇总
| 命令 | 说明 |
|------|------|
| `npm install` | 安装项目依赖 |
| `npm run dev` | 启动开发服务器 |
| `npm run build` | 构建生产版本 |
| `npm run preview` | 预览生产版本 |
| `npm audit` | 检查安全漏洞 |
---
## 附录:文件清单
完整的项目文件结构:
```
vue3-learning/
├── package.json
├── vite.config.js
├── index.html
├── README.md
└── src/
├── main.js
├── App.vue
├── style.css
├── components/
│ ├── PropsChild.vue
│ ├── EmitChild.vue
│ ├── SlotChild.vue
│ ├── NamedSlotsChild.vue
│ ├── ScopedSlotsChild.vue
│ ├── ProvideInjectChild.vue
│ ├── DeepNestedChild.vue
│ └── LifecycleChildComponent.vue
├── views/
│ ├── Home.vue
│ ├── ReactivityDemo.vue
│ ├── ComputedDemo.vue
│ ├── WatchDemo.vue
│ ├── LifecycleDemo.vue
│ ├── ComponentsDemo.vue
│ ├── ComposablesDemo.vue
│ ├── DirectivesDemo.vue
│ ├── RouterDemo.vue
│ ├── PiniaDemo.vue
│ ├── TransitionsDemo.vue
│ └── HttpDemo.vue
├── router/
│ └── index.js
└── stores/
└── userStore.js
```
---
## 学习建议
1. **循序渐进**:按照导航菜单的顺序学习每个模块
2. **动手实践**:每个示例都尝试修改代码观察变化
3. **查看注释**:每个文件都有详细的中文注释
4. **阅读源码**:理解每个功能的核心实现原理
5. **举一反三**:尝试在现有基础上添加新功能
---
**文档结束**
祝学习愉快! 🚀