为什么写这篇:2018 年是 Vue 2 的成熟期,vue-cli 3.0 正式发布(基于 Webpack 4 + 零配置)。Element UI 已经成为中后台标配,Vuex + Vue Router 也走过了"磨合期"。即使 Vue 3 已发布,理解 Vue 2 仍是企业级项目维护的"基本功"——大量老项目还在跑 Vue 2。
适用读者:完全没接触过 Vue 的同学;从 React / Angular 转过来的前端;想系统整理 Vue 2 知识的中级工程师。
前置知识:HTML / CSS / JavaScript 基础。
目录
- 环境准备:Node.js 与 vue-cli
- vue create:手动选择项目特性
- 项目目录结构
- 装 Element UI / less / ESLint
- Vue 核心:声明式渲染
- 指令速查表
- 自定义组件
- 生命周期
- 计算属性 vs 方法 vs 侦听器
- 组件模块系统
- Vue.config.js 配置
1. 环境准备:Node.js 与 vue-cli
1.1 Node.js
从 nodejs.org 下载 LTS 版本(写作时是 22.x,回看 2018 是 10.x)。安装后:
npm 升级到最新(Node 自带的 npm 不一定最新):
1.2 装 yarn(可选,但推荐)
1
2
| npm install -g yarn
yarn -v
|
1.3 装 vue-cli
1
2
3
4
5
| npm install -g @vue/cli
# 或
yarn global add @vue/cli
vue -V # @vue/cli 5.0.x
|
环境变量(Windows):把 C:\Users\<user>\AppData\Local\Yarn\bin 加到 PATH。
1.4 升级 vue-cli
1
2
3
| npm update -g @vue/cli
# 或
yarn global upgrade --latest @vue/cli
|
1.5 装 native 编译工具
一些 npm 包(node-sass、node-gyp)需要 C++ 编译器。Windows 上装 windows-build-tools:
1
2
| npm install -g node-gyp
npm install --global --production windows-build-tools
|
清理缓存:
1
| npm cache clean --force
|
2. vue create:手动选择项目特性
vue create 会进入交互式选择:
1
2
3
4
5
6
7
8
9
10
11
12
| ? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Use class-style component syntax? No
? Use Babel alongside TypeScript? Yes
? Use history mode for router? (Requires proper server setup for index fallback) Yes
? Pick a CSS pre-processor: Sass/SCSS (with dart-sass)
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Pick a unit testing solution: Jest
? Pick an E2E testing solution: Cypress
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N) n
|
各项含义:
| 特性 | 用途 | 推荐 |
|---|
| Babel | 把 ES2015+ 转 ES5,老浏览器兼容 | ✅ 必选 |
| TypeScript | JS 超集,类型检查 | ✅ 大型项目必选 |
| PWA | 渐进式 Web 应用(Service Worker、离线) | ⭕ 按需 |
| Router | vue-router 路由 | ✅ SPA 必选 |
| Vuex | 状态管理 | ✅ 中大型项目必选 |
| CSS Pre-processors | SCSS / Less / Stylus | ⭕ 按团队 |
| Linter / Formatter | ESLint 代码规范 | ✅ 必选 |
| Unit Testing | 单元测试(Jest / Mocha) | ⭕ 大型项目 |
| E2E Testing | 端到端测试(Cypress / Nightwatch) | ⭕ 大型项目 |
跑完后 cd 进去:
1
2
| cd vue-pro
yarn serve # 或 npm run serve
|
可视化配置:vue ui 打开 http://localhost:8000,可以用 GUI 装插件、跑构建。
3. 项目目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| vue-pro/
├── public/ # 不参与 webpack 构建的静态资源
│ ├── favicon.ico
│ └── index.html # HTML 模板
├── src/
│ ├── assets/ # 会被 webpack 处理的静态资源
│ ├── components/ # 公共组件
│ │ └── HelloWorld.vue
│ ├── views/ # 路由页面组件
│ ├── router/ # vue-router 配置
│ │ └── index.ts
│ ├── store/ # Vuex 状态
│ │ └── index.ts
│ ├── App.vue # 根组件
│ ├── main.ts # 入口文件
│ └── shims-vue.d.ts # 让 TS 识别 .vue 文件
├── tests/ # 单元测试
├── .browserslistrc # 浏览器兼容目标
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── package.json
├── README.md
├── tsconfig.json
└── vue.config.js # 可选,手写时配置 Webpack
|
4. 装 Element UI / less / ESLint
4.1 Element UI(Vue 2 时代中后台标配)
1
2
| vue add element
# 自动选按需引入、主题色
|
4.2 less / less-loader
1
2
3
| yarn add less less-loader --dev
# 或
npm install less less-loader --save-dev
|
使用:
1
2
3
4
5
| <style scoped lang="less">
.read-the-docs {
color: #888;
}
</style>
|
4.3 ESLint
1
2
3
4
5
6
| yarn add --dev eslint
# 或
npm install --save-dev eslint
# 初始化
eslint --init
|
卸载:
5. Vue 核心:声明式渲染
1
2
3
| <div id="app">
{{ message }}
</div>
|
1
2
3
4
5
6
| var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
|
核心思想:用 {{ }}(Mustache 语法)把 data 里的变量渲染到 HTML。data 一变,DOM 自动更新——这是 Vue(和 React、Angular)“响应式"的本质。
6. 指令速查表
| 指令 | 简写 | 作用 | 示例 |
|---|
v-bind:href | :href | 绑定 HTML 属性 | <a :href="url"> |
v-if | | 条件渲染(销毁/重建 DOM) | <p v-if="ok">YES</p> |
v-else-if / v-else | | 配合 v-if | |
v-show | | 条件渲染(仅切换 display) | <p v-show="ok"> |
v-for | | 列表循环 | <li v-for="(item, i) in arr" :key="i"> |
v-on:click | @click | 事件绑定 | <button @click="fn"> |
v-model | | 表单双向绑定 | <input v-model="name"> |
v-once | | 只渲染一次 | <span v-once>{{ msg }}</span> |
v-html | | 输出真正的 HTML | <div v-html="rawHtml"> |
v-slot | # | 插槽(具名插槽) | <Comp #header> |
v-if vs v-show:
v-if 真假切换时会销毁/重建 DOM 节点——切换开销大v-show 仅切 display: none —— 初次渲染开销大,切换开销小- 频繁切换用
v-show,条件很少变用 v-if
v-for 必带 :key:
1
| <li v-for="item in items" :key="item.id">{{ item.text }}</li>
|
key 帮助 Vue 高效复用 DOM。永远不要用 index 当 key(除非列表完全静态)。
6.1 模板表达式
1
2
3
4
5
6
7
8
| {{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
<!-- ❌ 不行:不能写语句 -->
{{ var a = 1 }}
{{ if (ok) { return message } }}
|
7. 自定义组件
1
2
3
4
5
6
| // 全局注册
Vue.component('todo-item', {
template: '<li>这是个待办项</li>'
})
var app = new Vue({ /* ... */ })
|
1
| <todo-item></todo-item>
|
现代写法:用 .vue 单文件组件(包含 template / script / style 三段),更清晰。
8. 生命周期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| beforeCreate ─┐
│ 初始化 events & lifecycle
created ─┤ 注入(provide / inject)
│
beforeMount ─┤ 模板编译
mounted ─┘ DOM 已挂载 ✅
│
beforeUpdate ─┐ 数据变化 → 重新渲染前
updated ─┤ 重新渲染后
│
activated ─┐ <keep-alive> 专属
deactivated ─┘
│
beforeDestroy ─┐ 组件销毁前
destroyed ─┘ 组件销毁后
|
最常用的两个:
created:组件创建完,data 已初始化,DOM 还没渲染。常用于发请求拿初始数据mounted:DOM 已挂载完成。可以操作 DOM、初始化第三方库
9. 计算属性 vs 方法 vs 侦听器
9.1 计算属性(computed)
1
2
3
4
5
6
7
8
9
| var vm = new Vue({
el: '#example',
data: { message: 'Hello' },
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
|
特性:基于依赖缓存——message 不变就返回上次的计算结果,多次访问不重复算。
9.2 方法(methods)
1
2
3
4
5
| methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
|
特性:每次调用都重算。不缓存。
9.3 侦听器(watch)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
|
特性:监听某个 data 变化后触发副作用(如发请求)。用 computed 能搞定的别用 watch。
9.4 选型原则
| 场景 | 选 |
|---|
| 模板里需要派生数据 | computed |
| 事件回调 / 交互 | methods |
| data 变化要发请求 / 调 API | watch |
10. 组件模块系统
1
2
3
4
5
6
7
| import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: { ComponentA, ComponentC },
// ...
}
|
现代项目用 import { ref, computed } from 'vue'(Composition API,Vue 3)或 import { mapState, mapGetters } from 'vuex'(Vuex 4)组织逻辑。
11. Vue.config.js 配置
从 Vue CLI 3.0 开始,Webpack 的配置文件从 webpack.config.js 变成了 vue.config.js,需要手工创建。
最小配置:
1
2
3
4
5
6
7
8
9
10
| // vue.config.js
module.exports = {
publicPath: './', // 部署到子目录时配
outputDir: 'dist',
productionSourceMap: false,
devServer: {
port: 8080,
open: true
}
}
|
完整配置(参考 Vue CLI 文档)涉及几十项,本文不展开。
小结
Vue 2 入门核心要点:
- 环境:Node LTS +
@vue/cli 全局 - 项目初始化:
vue create + 手动选 Babel/TS/Router/Vuex/Linter - 核心概念:声明式渲染 + 指令 + 组件
- 数据流:data → computed(派生)→ methods(动作)→ watch(副作用)
- 生命周期:created(发请求)、mounted(操作 DOM)
- 配置:vue.config.js(Webpack 5 升级后建议用 Vite 6+ 替代)
下一步:学 Vue 3 的 Composition API、<script setup>、Pinia(替代 Vuex)、Vite 7。Vue 2 已于 2023-12-31 EOL,新项目都应直接上 Vue 3。
参考资料