一、前置知识准备(夯实基础)
1.1 JavaScript 核心基础
作为 Vue.js 的底层依赖,需掌握以下核心能力:
- 变量与数据类型:原始类型(string/number/boolean/null/undefined/symbol)与引用类型(object/array/function)
- DOM 操作:节点增删改查、事件绑定(addEventListener)、事件冒泡与捕获
- 异步编程:回调函数、Promise、async/await(Vue 项目中接口请求核心)
- 函数进阶:箭头函数、闭包、原型链(理解 Vue 实例本质)
1.2 必学 ES6 核心特性
ES6 是 Vue 开发的语法基础,重点掌握:
- 变量声明:let/const 替代 var(块级作用域、无变量提升、不可重复声明)
// 经典面试题:let与var的区别
for (var i = 0; i {
setTimeout(() => console.log(i), 0); // 输出3个3(var全局作用域)
}
for (let j = 0; j ++) {
setTimeout(() => console.log(j), 0); // 输出0、1、2(let块级作用域)
}
- 解构赋值:数组 / 对象快速取值(Vue 组件传参常用)
// 对象解构(组件props接收常用)
const { name, age } = this.user;
// 数组解构(接口返回数据处理)
const [data, total] = await fetchList();
- 模板字符串:支持换行与变量嵌入
- 箭头函数:简化回调,绑定外层 this(避免 Vue 中 this 指向问题)
- 模块化:import/export(Vue 组件导入导出核心)
注:ES6 是 ECMAScript 2015 的标准,是 JavaScript 的语言规范,Vue 3 源码基于 ES6 + 编写,掌握这些特性可大幅提升开发效率。
1.3 Flex 布局思维导图(核心知识点)
工具推荐:使用知犀思维导图可快速绘制可视化布局图,支持多平台同步与模板复用。
1.4 前置知识考核方案
|------|--------------------------------------------------------|-----------------|
| 考核类型 | 考核内容 | 合格标准 |
| 理论笔试 | ES6 特性、Flex 布局、JS 异步编程 | 80 分以上(共 100 分) |
| 实操编程 | 1. 用 ES6 语法重构普通 JS 代码 > 2. 用 Flex 实现响应式布局 | 代码规范、功能完整 |
| 面试问答 | 1. let/const 与 var 的区别 2. 箭头函数与普通函数的差异 3. Flex 布局的应用场景 | 回答准确、逻辑清晰 |
二、Vue.js 入门(从零到一)
2.1 学习指南
学习路径:基础概念 → 简单实例 → 核心特性 → 小型实战
学习资源:Vue 3 官方文档(优先)、Vue CLI 官方指南
学习建议:先使用 `.js,熟悉基础语法后再使用 Vue CLI 构建项目。
2.2 Web 前端开发概述
- 核心技术栈:HTML(结构)+ CSS(样式)+ JavaScript(交互)+ 框架(Vue)
- Vue 的定位:渐进式 JavaScript 框架,可按需引入核心功能(如仅用双向绑定,或全套生态)
- 应用场景:单页应用(SPA)、多页应用(MPA)、移动端 H5、小程序(通过 uni-app 等适配)
- 2024 前端趋势:Vue 3 成为主流、Vite 替代 Webpack、TypeScript 普及、跨端开发常态化
2.3 第一个 Vue 实例(最简实现)
引入Vue.js -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
. HTML模板 -->
id="app">
<h1>{``{ message }}</h1>
<button @click="changeMessage">修改文本
</div>
3. Vue逻辑 -->
Vue应用实例
const app = Vue.createApp({
// data:数据对象(响应式数据源)
data() {
return {
message: "Hello Vue!"
}
},
// methods:方法(处理交互逻辑)
methods: {
changeMessage() {
this.message = "Vue入门成功!";
}
}
});
// 挂载到DOM元素
app.mount('#app');
</script>
核心要点:
- {{ }}:插值语法,用于渲染数据
- @click:事件绑定语法(简写 v-on:click)
- data():返回响应式数据对象(必须是函数,避免组件复用冲突)
- mount('#app'):将 Vue 实例挂载到指定 DOM 节点
2.4 章节测试(入门级)
- 填空题:Vue 3 的入口函数是______,挂载方法是______。
- 编程题:实现一个计数器,点击 "+" 按钮数字加 1,点击 "-" 按钮数字减 1。
- 简答题:简述 Vue 的渐进式设计理念。
三、Vue 基础特性(核心能力)
3.1 学习指南
重点目标:掌握 Vue 响应式核心、指令系统、事件处理、计算属性等基础能力
学习方法:边学边练,每个特性编写至少 2 个示例(基础用法 + 实际场景)
3.2 Vue 实例常用构造选项
|----------|------------------|-------------------------------------------|
| 选项 | 作用 | 示例 |
| data | 定义响应式数据 | data() { return { count: 0 } } |
| methods | 定义实例方法 | methods: { increment() { this.count++ } } |
| computed | 定义计算属性 | 见 3.7 节 |
| watch | 监听数据变化 | 见 3.7 节 |
| created | 生命周期钩子(实例创建完成) | created() { console.log('实例已创建') } |
| mounted | 生命周期钩子(DOM 挂载完成) | mounted() { console.log('DOM已挂载') } |
| props | 接收父组件传递的参数 | 见 6.4.1 节 |
| emits | 声明组件触发的事件 | 见 6.4.2 节 |
3.3 data 数据对象
- 核心规则:必须是函数,返回一个对象(组件复用场景下避免数据污染)
- 响应式特性:数据变化时,视图自动更新(Vue 3 基于 Proxy 实现)
- 注意事项:
-
- 直接添加新属性不会触发响应式(需用 Vue.set 或 ES6 语法)
-
- 数组索引修改不会触发响应式(需用数组方法如 push/splice)
3.4 methods 方法
- 定义方式:函数声明式(不推荐箭头函数,避免 this 指向问题)
- 调用方式:
-
- 模板中:@click="methodName" 或 @click="methodName(参数)"
-
- 实例中:this.methodName()
- 特性:每次组件渲染都会重新创建函数实例(性能影响可忽略,复杂场景可用 computed 替代)
3.5 常用指令
|-----------------------|-------------------|-----------------------------|
| 指令 | 作用 | 示例 |
| v-text | 渲染文本(替代 {{}}) | `-text="message"> |
| v-html | 渲染 HTML(慎用,防 XSS) | ` v-bind |
| v-if/v-else-if/v-else | 条件渲染(销毁 / 创建 DOM) | `v-if="isShow"> 显示内容 |
| v-show | 条件渲染(显示 / 隐藏 DOM) | `-show="isShow"> 显示内容 |
| v-on | 事件绑定(简写 "@") | `@click="handleClick"> 点击 |
关键区别:v-if vs v-show
- v-if:适合条件不频繁变化的场景(切换开销大)
- v-show:适合条件频繁变化的场景(初始渲染开销大)
3.6 事件修饰符
用于简化事件处理逻辑,常用修饰符:
- .stop:阻止事件冒泡 → handleClick">点击>
- .prevent:阻止默认行为 → `<a @click.prevent="handleLink"> 跳转
- .once:事件只触发一次 → <button @click.once="handleClick">点击>
- .self:只有事件目标是自身时触发 → click.self="handleDiv">容器 .enter:键盘回车事件 → up.enter="handleSubmit">`
3.7 计算属性与监听属性
3.7.1 计算属性(computed)
- 作用:处理复杂逻辑计算,缓存结果(依赖数据不变时不会重新计算)
- 示例:
computed: {
// 计算总价(依赖goodsList数据)
totalPrice() {
return this.goodsList.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
}
- 优势:比 methods 更高效(缓存机制),比 watch 更简洁(适合多依赖计算)
3.7.2 监听属性(watch)
- 作用:监听数据变化,执行副作用操作(如接口请求、日志打印)
- 示例:
watch: {
// 监听username变化
username(newVal, oldVal) {
console.log(`用户名从${oldVal}改为${newVal}`);
// 触发接口请求
this.fetchUserInfo(newVal);
},
// 深度监听对象
user: {
handler(newVal) {
console.log('用户信息变化', newVal);
},
deep: true, // 开启深度监听
immediate: true // 初始渲染时执行一次
}
}
3.8 filters 过滤器(Vue 3 兼容写法)
- 作用:格式化数据(如日期、价格、文本)
- 定义与使用:
// 全局过滤器(main.js)
app.config.globalProperties.$filters = {
// 价格格式化(保留2位小数)
formatPrice(price) {
return `¥${price.toFixed(2)}`;
}
};
// 模板中使用
>{``{ price | formatPrice }}</div>
- Vue 3 注意事项:filters 选项已被废弃,推荐使用计算属性或全局方法替代
四、内置指令(进阶)
4.1 学习指南
重点目标:掌握 Vue 内置指令的高级用法,解决实际开发场景问题
核心指令:v-cloak、v-pre、v-once、v-memo、v-slot(插槽指令)
五、Vue 项目化开发(工程化)
5.1 学习指南
前置要求:掌握 Node.js 基础、npm 常用命令、ES6 模块化
学习目标:学会使用 Vue CLI 构建项目、理解项目结构、配置开发环境
5.2 Vue CLI 三个主要工具
- @vue/cli:核心脚手架工具,提供项目创建、配置、运行、打包等命令
- @vue/cli-service:项目本地开发服务与构建工具,内置 Webpack/Vite 配置
- @vue/cli-plugin-xxx:扩展插件(如 @vue/cli-plugin-typescript、@vue/cli-plugin-router)
核心能力:通过插件化机制,可快速集成路由、状态管理、TS 等功能,简化项目配置。
5.3 Vue 脚手架项目环境配置
5.3.1 环境准备
- 安装 Node.js(推荐 16.x 以上版本)
- 安装 Vue CLI:npm install -g @vue/cli
- 验证安装:vue --version(显示版本号即安装成功)
5.3.2 核心配置文件
- package.json:项目依赖、脚本命令(serve/build/lint)
- vue.config.js:Vue CLI 配置(如端口、代理、插件)
// vue.config.js 示例
module.exports = {
devServer: {
port: 8080, // 开发端口
proxy: { // 跨域代理配置
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
},
css: {
loaderOptions: {
scss: {
``additionalData: `@import "@/assets/scss/variables.scss";```
}
}
}
};
5.4 使用 Vue CLI 快速构建项目
5.4.1 构建步骤
- 创建项目:vue create my-vue-project
- 选择预设:默认预设(Vue 3 + Babel + ESLint)或手动选择功能
- 进入项目:cd my-vue-project
- 运行项目:npm run serve
- 打包项目:npm run build
5.4.2 Vue 脚手架项目目录说明
my-vue-project/
├── node_modules/ # 项目依赖包
├── public/ # 静态资源(不会被Webpack处理)
│ ├── index.html # 入口HTML文件
│ └── favicon.ico # 网站图标
├── src/ # 源代码目录(核心)
│ ├── assets/ # 静态资源(会被Webpack处理)
│ │ ├── css/ # 样式文件
│ │ └── img/ # 图片资源
│ ├── components/ # 通用组件
│ ├── views/ # 页面组件
│ ├── router/ # 路由配置(需手动创建)
│ ├── store/ # 状态管理(需手动创建)
│ ├── App.vue # 根组件
│ └── main.js # 入口文件(初始化Vue应用)
├── .eslintrc.js # ESLint配置文件
├── .gitignore # Git忽略文件
├── package.json # 项目配置文件
└── README.md # 项目说明文档
六、Vue 组件开发(核心模块)
6.1 学习指南
核心目标:掌握组件化思想、组件通信、插槽使用,能独立开发可复用组件
学习重点:组件通信机制(Vue 开发高频面试题)
6.2 组件的简介
- 定义:组件是 Vue 应用的基本组成单元,是可复用的 Vue 实例
- 核心思想:拆分复杂 UI 为独立、可复用的模块(单一职责原则)
- 组件分类:
-
- 基础组件(UI 组件):按钮、输入框、卡片等通用组件
-
- 业务组件:订单卡片、商品列表等业务相关组件
-
- 页面组件:首页、详情页等路由对应的组件
6.3 组件的使用
6.3.1 组件注册
- 局部注册(仅当前组件可用):
<Child />
>
Child from './Child.vue'; // 导入组件
export default {
components: { Child } // 注册组件
};
>
- 全局注册(所有组件可用,main.js):
import { createApp } from 'vue';
import App from './App.vue';
import Button from './components/Button.vue';
const app = createApp(App);
app.component('MyButton', Button); // 全局注册组件
app.mount('#app');
6.3.2 组件使用规则
- 组件名推荐使用 PascalCase(如 MyComponent)或 kebab-case(如 my-component)
- 模板中使用 kebab-case(HTML 不区分大小写)
- 组件必须有唯一根元素(Vue 3 支持多根元素,但需指定 key)
6.4 组件之间的通信
6.4.1 父组件向子组件通信(Props)
- 核心流程:父组件通过属性传递数据 → 子组件通过 props 接收数据
- 示例:
父组件 Parent.vue -->
<template>
<Child :username="username" :age="age" />
</template>
>
export default {
data() {
return {
username: '张三',
age: 20
};
}
};
</script>
子组件 Child.vue -->
username }} age }}</div>
</template>
export default {
// 接收父组件传递的props
props: {
username: {
type: String, // 类型校验
required: true, // 必传属性
default: '未知用户' // 默认值(仅非必传属性有效)
},
age: {
type: Number,
validator: (value) => {
return value >= 0; // 自定义校验规则
}
}
}
};
- 注意事项:子组件不能直接修改 props(单向数据流),需通过事件通知父组件修改
6.4.2 子组件向父组件通信(自定义事件)
- 核心流程:子组件通过 $emit 触发事件 → 父组件通过 @监听事件
- 示例:
<!-- 子组件 Child.vue -->
handleClick">修改用户名</button>
{
emits: ['update:username'], // 声明触发的事件(Vue 3推荐)
methods: {
handleClick() {
// 触发事件,传递新值
this.$emit('update:username', '李四');
}
}
};
</script>
组件 Parent.vue -->
<template>
@update:username="handleUpdateUsername" />
</template>
export default {
data() {
return {
username: '张三'
};
},
methods: {
handleUpdateUsername(newName) {
// 父组件修改数据
this.username = newName;
}
}
};
>
- 语法糖:v-model(父子组件双向绑定)
父组件简化写法 -->
<Child v-model:username="username" />
等价于 -->
<Child :username="username" @update:username="username = $event" />
6.5 组件实战案例:计数器组件
<!-- Counter.vue -->
<template>
class="counter">
crement" :disabled="count <= 0">->
count }} crement">+
</template>
export default {
props: {
initialCount: {
type: Number,
default: 0
}
},
emits: ['update:count'],
data() {
return {
count: this.initialCount
};
},
methods: {
increment() {
this.count++;
this.$emit('update:count', this.count);
},
decrement() {
if (this.count > 0) {
this.count--;
this.$emit('update:count', this.count);
}
}
}
};
</script>
oped>
.counter {
display: flex;
align-items: center;
gap: 10px;
}
button {
padding: 5px 10px;
cursor: pointer;
}
</style>
6.6 内容分发 slot(插槽)
- 作用:实现组件内容的灵活分发,提高组件复用性
- 分类与示例:
- 默认插槽:
.vue -->
card">
>默认内容(无分发内容时显示)>
</template>
父组件使用 -->
<Card>
<div>这是分发的内容</div>
</Card>
- 具名插槽(多插槽分发):
子组件 Card.vue -->
<template>
<div class="card">
-header">
name="header">默认头部</slot>
</div>
class="card-body">
">默认内容
</div>
</template>
组件使用 -->
>
header>
2>卡片标题2>
>
body>
<p>卡片内容
</Card>
- 作用域插槽(子组件向父组件传递数据):
组件 List.vue -->
<template>
>
-for="item in list" :key="item.id">
="item" :index="index">
{``{ item.name }}
>
</template>
export default {
data() {
return {
list: [{ id: 1, name: 'Vue' }, { id: 2, name: 'React' }]
};
}
};
-->
">
scope.index + 1 }}. {``{ scope.item.name }}</span>
>
七、路由插件 Vue Router
7.1 学习指南
核心目标:掌握单页应用路由原理、路由配置、路由传参、路由守卫
学习重点:路由模式(hash/history)、动态路由、嵌套路由
7.2 路由的基本使用
7.2.1 安装与配置
- 安装:npm install vue-router@4(Vue 3 对应版本)
- 创建路由配置文件(src/router/index.js):
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import About from '@/views/About.vue';
// 路由规则
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
// 创建路由实例
const router = createRouter({
history: createWebHistory(), // history模式(无#)
// history: createWebHashHistory(), // hash模式(有#)
routes
});
export default router;
- 在 main.js 中引入:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App)
.use(router) // 安装路由插件
.mount('#app');
7.2.2 路由使用
- 路由链接(替代 a 标签):
-link to="/">首页</router-link>
````-link to="/about">关于我们```````
2. 路由出口(渲染匹配的组件):
```````vue````
<router-view>>
7.3 路由传参及获取参数
7.3.1 传参方式
- query 参数(URL 拼接,如?name=Vue):
detail?name=Vue&version=3">详情页</router-link>
或编程式导航 -->
this.$router.push({
path: '/detail',
query: { name: 'Vue', version: 3 }
});
<script>
export default {
mounted() {
console.log(this.$route.query.name); // Vue
console.log(this.$route.query.version); // 3
}
};
</script>
- params 参数(动态路由,如 /detail/1):
// 路由配置
{
path: '/detail/:id', // 动态路由参数
name: 'Detail',
component: Detail
}
// 跳转
<router-link to="/detail/1">详情页-link>
编程式导航 -->
this.$router.push({
name: 'Detail', // 必须用name跳转
params: { id: 1 }
});
// 获取参数
this.$route.params.id; // 1
八、Axios 插件(接口请求)
8.1 学习指南
核心目标:掌握 Axios 基本使用、请求 / 响应拦截、错误处理、跨域解决
学习重点:Axios 封装(企业级实战必备)
8.2 Axios 的使用
8.2.1 安装与基础使用
- 安装:npm install axios
- 基础使用:
import axios from 'axios';
// GET请求
axios.get('/api/user', {
params: { id: 1 } // URL参数
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// POST请求
axios.post('/api/login', {
username: 'admin',
password: '123456'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
8.2.2 Axios 封装(企业级实战)
创建 src/api/request.js:
import axios from 'axios';
import { ElMessage } from 'element-plus'; // 错误提示(需安装element-plus)
// 创建Axios实例
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, // 基础URL(从环境变量读取)
timeout: 5000 // 请求超时时间
});
// 请求拦截器(添加Token)
service.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 响应拦截器(统一处理结果)
service.interceptors.response.use(
response => {
const res = response.data;
// 假设后端返回格式:{ code: 200, data: {}, msg: '' }
if (res.code !== 200) {
ElMessage.error(res.msg || '请求失败');
return Promise.reject(res);
}
return res.data;
},
error => {
ElMessage.error(error.message || '网络错误');
return Promise.reject(error);
}
);
export default service;
8.3 Axios 使用总结
- 核心 API:get/post/put/delete/request
- 配置项:baseURL、timeout、headers、params(GET 参数)、data(POST 参数)
- 拦截器:请求拦截(添加公共参数、Token)、响应拦截(统一错误处理、数据格式化)
- 错误处理:网络错误、超时错误、后端错误码处理
8.4 跨域的解决
8.4.1 开发环境跨域(Vue CLI 代理)
在 vue.config.js 中配置:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000', // 后端接口地址
changeOrigin: true, // 开启跨域
pathRewrite: { '^/api': '' } // 去除URL中的/api前缀
}
}
}
};
8.4.2 生产环境跨域
- 后端配置 CORS(推荐):
// Node.js示例(Express)
const cors = require('cors');
app.use(cors({
origin: 'http://your-domain.com', // 允许的前端域名
credentials: true // 允许携带Cookie
}));
- 反向代理(Nginx):
server {
listen 80;
server_name your-domain.com;
location /api {
proxy_pass http://localhost:3000; // 后端接口地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
九、课堂实操项目
9.1 综合项目案例:Vue 电商商品列表页
9.1.1 项目需求
- 展示商品列表(分页、搜索、筛选)
- 商品详情查看(路由跳转)
- 加入购物车(组件通信)
- 购物车数量统计(Pinia 状态管理)
9.1.2 项目结构
src/
├── api/
│ ├── request.js # Axios封装
│ └── goods.js # 商品相关接口
├── components/
│ ├── GoodsItem.vue # 商品项组件
│ ├── GoodsList.vue # 商品列表组件
│ ├── SearchBar.vue # 搜索组件
│ └── Cart.vue # 购物车组件
├── views/
│ ├── Home.vue # 首页(商品列表)
│ └── GoodsDetail.vue # 商品详情页
├── router/ # 路由配置
├── stores/ # Pinia状态管理(购物车)
└── App.vue
9.1.3 核心功能实现
- 商品列表接口请求(api/goods.js):
import request from './request';
// 获取商品列表
export function getGoodsList(params) {
return request({
url: '/goods/list',
method: 'get',
params
});
}
// 获取商品详情
export function getGoodsDetail(id) {
return request({
url: `/goods/${id}`,
method: 'get'
});
}
- 购物车状态管理(stores/cart.js):
import { defineStore } from 'pinia';
export const useCartStore = defineStore('cart', {
state: () => ({
cartList: []
}),
actions: {
// 添加商品到购物车
addToCart(goods) {
const existingGoods = this.cartList.find(item => item.id === goods.id);
if (existingGoods) {
existingGoods.quantity++;
} else {
this.cartList.push({ ...goods, quantity: 1 });
}
},
// 移除购物车商品
removeFromCart(id) {
this.cartList = this.cartList.filter(item => item.id !== id);
}
},
getters: {
// 购物车商品总数
totalQuantity() {
return this.cartList.reduce((sum, item) => sum + item.quantity, 0);
},
// 购物车商品总价
totalPrice() {
return this.cartList.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
}
});
- 商品列表组件(components/GoodsList.vue):
-list">
Bar @search="handleSearch" />
class="goods-grid">
v-for="goods in goodsList"
:key="goods.id"
:goods="goods"
@add-to-cart="handleAddToCart"
/>
</div>
class="pagination">
</div>
>
import { ref, onMounted } from 'vue';
import { getGoodsList } from '@/api/goods';
import GoodsItem from './GoodsItem.vue';
import SearchBar from './SearchBar.vue';
import { useCartStore } from '@/stores/cart';
const cartStore = useCartStore();
const goodsList = ref([]);
const searchParams = ref({
keyword: '',
page: 1,
pageSize: 10
});
// 初始化加载商品列表
onMounted(() => {
fetchGoodsList();
});
// 获取商品列表
const fetchGoodsList = async () => {
const data = await getGoodsList(searchParams.value);
goodsList.value = data.list;
};
// 搜索商品
const handleSearch = (keyword) => {
searchParams.value.keyword = keyword;
searchParams.value.page = 1;
fetchGoodsList();
};
// 添加到购物车
const handleAddToCart = (goods) => {
cartStore.addToCart(goods);
};
9.1.4 项目效果截图(示例)
- 商品列表页:展示商品图片、名称、价格、加入购物车按钮
- 商品详情页:展示商品详细信息、规格选择、加入购物车
- 购物车组件:展示已添加商品、数量修改、删除、总价计算
9.1.5 项目素材准备
- 商品图片:可使用 Mock 图片服务(如https://picsum.photos/)
- 接口数据:可使用 Mock.js 模拟或 JSON Server 搭建本地接口
- UI 组件:可使用 Element Plus 快速构建界面