vue2重点

系统、详细地梳理Vue2的核心重点知识,覆盖从基础语法到进阶应用的全流程,清晰呈现Vue2的核心体系和高频考点,方便巩固学习和实际开发。

一、Vue2核心基础

1. Vue2核心特性

  • MVVM架构:Model(数据)→ ViewModel(Vue实例)→ View(视图),数据驱动视图,双向绑定,无需手动操作DOM。
  • 渐进式框架:按需使用核心功能(仅渲染/加路由/加状态管理),不强制全套使用。
  • 虚拟DOM:减少真实DOM操作,提升渲染性能。
  • 指令系统:内置指令简化DOM操作,支持自定义指令。
  • 组件化:复用UI和逻辑,降低代码耦合度。

2. 项目创建与入口

Vue2主流用Vue CLI创建,也支持CDN快速入门:

1
2
3
4
5
6
7
8
# 安装Vue CLI(适配Vue2,需Node.js 8.9+)
npm install -g @vue/cli@4
# 创建项目
vue create my-vue2-project
# 选择Vue2版本
# 启动项目
cd my-vue2-project
npm run serve

CDN快速测试(新手入门)

1
2
3
4
5
6
7
8
9
10
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
<div id="app">{{ message }}</div>
<script>
new Vue({
el: '#app', // 挂载节点
data: {
message: 'Hello Vue2!'
}
})
</script>

入口文件(main.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 关闭生产环境提示
Vue.config.productionTip = false

// 创建Vue实例(核心)
new Vue({
el: '#app', // 等价于$mount('#app')
router, // 注入路由
store, // 注入Vuex
render: h => h(App) // 渲染根组件
})

3. 模板语法(Vue2核心)

Vue2模板语法是视图渲染的基础,分插值、指令、绑定三类:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
<template>
<!-- 1. 文本插值({{}}) -->
<div>{{ message }}</div>
<!-- 表达式插值(仅单个表达式) -->
<div>{{ count + 1 }}</div>
<div>{{ isShow ? '显示' : '隐藏' }}</div>

<!-- 2. 原始HTML(慎用,防XSS) -->
<div v-html="htmlContent"></div>

<!-- 3. 核心指令 -->
<img :src="imgUrl"> <!-- v-bind缩写,单向绑定属性 -->
<button @click="handleClick">点击</button> <!-- v-on缩写,绑定事件 -->
<input v-model="username"> <!-- 双向绑定表单 -->
<div v-if="isShow">条件渲染</div> <!-- 销毁/创建DOM -->
<div v-show="isShow">条件显示</div> <!-- 切换display:none -->
<li v-for="item in list" :key="item.id">{{ item.name }}</li> <!-- 列表渲染(必加key) -->
</template>
<script>
export default {
data() {
return {
message: 'Vue2模板',
count: 0,
isShow: true,
htmlContent: '<h1>原始HTML</h1>',
imgUrl: 'https://vuejs.org/images/logo.png',
username: '',
list: [{ id: 1, name: 'Vue2' }, { id: 2, name: 'Vue3' }]
}
},
methods: {
handleClick() {
console.log('点击事件')
}
}
}
</script>

v-model修饰符(高频)

1
2
3
<input v-model.trim="username"> <!-- 去除首尾空格 -->
<input v-model.number="age"> <!-- 转为数字 -->
<input v-model.lazy="content"> <!-- 失焦后更新(默认input事件) -->

二、核心:Options API(选项式API)

Vue2的核心组织方式,通过不同选项划分功能,是必须掌握的核心:

1. 核心选项详解

(1)data:响应式数据
  • 组件中必须是函数(返回对象),避免多个实例共享数据。
  • 基于Object.defineProperty实现响应式,存在局限性(需重点掌握)。
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
26
27
28
<script>
export default {
data() {
return {
count: 0,
list: [1,2,3],
user: { name: '张三' }
}
},
mounted() {
// ✅ 数组响应式更新(推荐变异方法)
this.list.push(4)
this.list.splice(0, 1)

// ❌ 数组非响应式操作(下标赋值/改长度)
this.list[0] = 100 // 无响应
this.list.length = 0 // 无响应
// 解决:Vue.set
Vue.set(this.list, 0, 100)

// ❌ 对象新增属性无响应
this.user.age = 20 // 无响应
// 解决:Vue.set 或 批量更新
Vue.set(this.user, 'age', 20)
this.user = { ...this.user, age: 20 }
}
}
</script>
(2)methods:方法
  • 定义组件方法,this指向Vue实例(禁止用箭头函数,会丢失this)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<button @click="increment">+1</button>
</template>
<script>
export default {
data() { return { count: 0 } },
methods: {
increment() {
this.count++
this.logCount() // 调用其他方法
},
logCount() {
console.log(this.count)
}
// ❌ 错误示例:箭头函数导致this指向错误
// increment: () => { this.count++ }
}
}
</script>
(3)computed:计算属性
  • 基于响应式数据派生,有缓存(依赖不变则不重新计算),替代复杂模板表达式。
  • 支持getter/setter(默认仅getter)。
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
26
27
28
29
30
31
32
<template>
<div>{{ doubleCount }}</div>
<input v-model="fullName">
</template>
<script>
export default {
data() {
return {
count: 0,
firstName: '张',
lastName: '三'
}
},
computed: {
// 只读计算属性
doubleCount() {
return this.count * 2
},
// 可读写计算属性
fullName: {
get() {
return this.firstName + this.lastName
},
set(val) {
const [first, last] = val.split('')
this.firstName = first
this.lastName = last
}
}
}
}
</script>
(4)watch:侦听器
  • 监听响应式数据变化,执行副作用(请求、DOM操作),支持深度监听、立即执行。
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
26
27
28
<script>
export default {
data() {
return {
count: 0,
user: { name: '张三', age: 20 }
}
},
watch: {
// 基础类型监听
count(newVal, oldVal) {
console.log(`count从${oldVal}变到${newVal}`)
},
// 对象深度监听
user: {
handler(newVal) {
console.log('user变化:', newVal)
},
deep: true, // 深度监听
immediate: true // 首次加载立即执行
},
// 监听对象单个属性
'user.name'(newName) {
console.log('姓名变化:', newName)
}
}
}
</script>

2. 生命周期钩子(核心)

Vue2生命周期分4个阶段、8个核心钩子,是控制组件生命周期的关键:

钩子函数 执行时机 常用操作
beforeCreate 实例创建前,数据/方法未初始化 无(无法访问data、methods)
created 实例创建后,数据/方法已初始化 异步请求(无需等待DOM)、初始化数据
beforeMount 挂载前,模板已编译 无(DOM未生成)
mounted 挂载后,DOM已渲染 DOM操作、初始化第三方插件(如echarts)
beforeUpdate 数据更新,DOM更新前 读取更新前的DOM状态
updated DOM更新后 操作更新后的DOM(避免修改数据,防止死循环)
beforeDestroy 组件销毁前 清理定时器、取消事件监听、销毁第三方插件
destroyed 组件销毁后 无(组件已销毁)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
export default {
data() { return { timer: null } },
created() {
console.log('实例创建完成,可访问data')
},
mounted() {
// 启动定时器
this.timer = setInterval(() => console.log('运行中'), 1000)
},
beforeDestroy() {
// 销毁前清理副作用(核心)
clearInterval(this.timer)
}
}
</script>

三、组件核心知识

1. 组件注册

  • 全局注册:所有组件可用(适合通用组件,如按钮)。
  • 局部注册:仅当前组件可用(适合业务组件,减少体积)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 全局注册(main.js)
import Vue from 'vue'
import MyButton from './components/MyButton.vue'
Vue.component('MyButton', MyButton)

// 局部注册(组件内)
<template>
<MyButton />
</template>
<script>
import MyButton from './MyButton.vue'
export default {
components: { MyButton } // 局部注册
}
</script>

2. 组件通信(Vue2核心重点)

方式 适用场景 实现要点
props / $emit 父子通信(最常用) props父传子(单向),$emit子传父(事件)
$parent / $children 父子直接访问 $parent访问父实例,$children访问子实例数组
$refs 父访问子DOM/方法 子组件加ref,通过this.$refs.xxx访问
eventBus 任意组件(小型项目) 新建Vue实例作为总线,$on监听/$emit触发
provide / inject 跨层级(祖孙) 父provide提供,子孙inject注入
Vuex 全局状态(大型项目) 统一管理共享数据

(1)props / $emit(基础)

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
26
27
28
29
30
31
32
33
34
35
36
37
38
// 父组件
<template>
<Child :msg="parentMsg" @msg-change="handleChange" />
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() { return { parentMsg: '父消息' } },
methods: {
handleChange(newMsg) {
this.parentMsg = newMsg
}
}
}
</script>

// 子组件
<template>
<div>{{ msg }}</div>
<button @click="sendMsg">发消息</button>
</template>
<script>
export default {
props: { // props验证(推荐)
msg: {
type: String,
required: true,
default: '默认值'
}
},
methods: {
sendMsg() {
this.$emit('msg-change', '子消息') // 触发父组件事件
}
}
}
</script>

(2)eventBus(任意组件通信)

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
26
27
28
29
30
31
32
// bus.js(新建文件)
import Vue from 'vue'
export default new Vue()

// 组件A(发送)
<script>
import bus from './bus.js'
export default {
methods: {
send() {
bus.$emit('data-change', { name: '张三' })
}
}
}
</script>

// 组件B(接收)
<script>
import bus from './bus.js'
export default {
mounted() {
// 监听事件
this.listener = bus.$on('data-change', (data) => {
console.log('接收:', data)
})
},
beforeDestroy() {
// 销毁监听(防内存泄漏)
bus.$off('data-change', this.listener)
}
}
</script>

3. 插槽(Slots)

用于组件内容分发,分默认插槽、具名插槽、作用域插槽:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 子组件
<template>
<div>
<slot>默认内容</slot> <!-- 默认插槽 -->
<slot name="header"></slot> <!-- 具名插槽 -->
<slot name="item" :data="list"></slot> <!-- 作用域插槽 -->
</div>
</template>
<script>
export default { data() { return { list: [1,2,3] } } }
</script>

// 父组件
<template>
<Child>
<div>默认插槽内容</div>
<template v-slot:header> <!-- 具名插槽(Vue2.6+) -->
<h1>头部</h1>
</template>
<template v-slot:item="slotProps"> <!-- 作用域插槽 -->
<div>{{ slotProps.data }}</div>
</template>
</Child>
</template>

四、响应式原理(底层核心)

Vue2响应式基于Object.defineProperty实现,是面试高频考点:

  1. 初始化:遍历data所有属性,用Object.defineProperty重定义getter/setter
  2. 依赖收集:访问属性触发getter,将当前Watcher(视图更新函数)收集到Dep(依赖容器)。
  3. 派发更新:修改属性触发setter,通知Dep中的Watcher执行更新,重新渲染视图。

核心局限性

  • 无法监听数组下标赋值、修改长度(如this.list[0] = 100)。
  • 无法监听对象新增/删除属性(如this.user.age = 20)。
  • 解决方案:Vue.set(target, key, value) 或数组变异方法(push/splice等)。

五、状态管理:Vuex 3(Vue2官方)

用于管理全局共享状态,核心5个概念:

1. 核心配置

1
npm install vuex@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
26
27
28
29
30
31
32
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
state: { count: 0 }, // 全局状态(类似data)
mutations: { // 修改state的唯一方式(同步)
INCREMENT(state, payload) {
state.count += payload || 1
}
},
actions: { // 处理异步(触发mutation)
incrementAsync({ commit }, payload) {
setTimeout(() => commit('INCREMENT', payload), 1000)
}
},
getters: { // 派生状态(类似computed)
doubleCount: state => state.count * 2
},
modules: { // 模块化(大型项目)
user: {
namespaced: true, // 命名空间(避免冲突)
state: { name: '张三' },
mutations: {
UPDATE_NAME(state, name) {
state.name = name
}
}
}
}
})

2. 组件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
computed: {
...mapState(['count']), // 映射state
...mapGetters(['doubleCount']) // 映射getters
},
methods: {
...mapMutations(['INCREMENT']), // 映射mutation
...mapActions(['incrementAsync']), // 映射action
updateName() {
this.$store.commit('user/UPDATE_NAME', '李四') // 模块化调用
}
},
mounted() {
this.INCREMENT(2)
this.incrementAsync(3)
}
}
</script>

六、路由:Vue Router 3(Vue2适配)

1. 核心配置

1
npm install vue-router@3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home.vue'

Vue.use(Router)

export default new Router({
mode: 'history', // 去掉URL中的#(需后端配置)
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user/:id', // 动态路由参数
name: 'User',
component: () => import('@/views/User.vue') // 懒加载
},
{ path: '*', component: () => import('@/views/404.vue') } // 404
]
})

2. 路由使用与守卫

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
26
<template>
<router-link to="/">首页</router-link> <!-- 声明式导航 -->
<router-link :to="{ name: 'User', params: { id: 1 } }">用户</router-link>
<router-view /> <!-- 路由出口 -->
</template>
<script>
export default {
mounted() {
// 编程式导航
this.$router.push('/user/2')
// 获取路由参数
console.log(this.$route.params.id)

// 路由守卫(全局)
this.$router.beforeEach((to, from, next) => {
// 登录验证
const isLogin = localStorage.getItem('token')
if (to.path === '/admin' && !isLogin) {
next('/login')
} else {
next()
}
})
}
}
</script>

七、Vue2常见优化

  1. v-for加唯一key:避免用index,提升列表更新性能。
  2. v-for与v-if分离:将v-if提至父节点,避免无效遍历。
  3. 计算属性缓存:替代复杂模板表达式,减少重复计算。
  4. 异步组件:拆分大型组件,按需加载,降低首屏体积。
  5. 防抖节流:处理高频事件(如输入框搜索、滚动)。
  6. 清理副作用:定时器、事件监听需在beforeDestroy销毁。

总结

  1. 核心架构:Vue2基于Options API组织代码,data(响应式)、computed(缓存)、watch(侦听)、methods(方法)是基础,需掌握各选项的用法和区别。
  2. 响应式:基于Object.defineProperty实现,需掌握其局限性(数组/对象操作)及解决方案(Vue.set)。
  3. 组件通信props/$emit是基础,eventBus适合小型项目,Vuex适合大型项目全局状态管理。
  4. 生态核心:Vuex 3管理全局状态,Vue Router 3处理路由,需掌握核心配置和使用方式。
  5. 生命周期mounted用于DOM操作,beforeDestroy用于清理副作用,是组件开发的关键节点。

vue2重点
http://example.com/20260201-vue2重点/
作者
csorz
发布于
2026年2月1日
许可协议