vue 1.0->2.0变更

Vue 2.0 是 Vue.js 发展史上的重大里程碑式更新,它引入了 Virtual DOM、重写了渲染系统、优化了组件架构,不仅带来了2-4倍的性能提升,还为后续的 3.0 版本打下了坚实基础。

本文整理了 Vue 1.x 到 2.x 的核心变更、语法对比、迁移建议,帮你快速理解差异,顺利完成项目升级。


一、核心架构变更:最底层的变化

1. 引入 Virtual DOM(虚拟 DOM)

这是 Vue 2.0 最大的架构变化!

  • Vue 1.x:基于 DOM 依赖追踪,直接操作真实 DOM,性能在大型列表渲染时受限;
  • Vue 2.x:引入 Virtual DOM 层,通过对比虚拟节点差异最小化 DOM 操作,性能提升 2-4 倍,同时支持服务端渲染(SSR)。

2. 支持渲染函数(Render Function)

Vue 2.0 新增了 render 函数选项,允许用 JavaScript 直接描述 UI,比模板更灵活:

1
2
3
4
5
6
7
8
9
// Vue 2.x 渲染函数示例
new Vue({
render(h) {
return h('div', { class: 'container' }, [
h('h1', 'Hello Vue 2.0'),
h('p', '这是用渲染函数写的内容')
]);
}
});

二、模板语法变更:最容易踩坑的地方

1. 插值与指令通用变化

  • 移除了部分简写:不再支持 {{{ }}} 三括号插值(统一用 v-html);
  • 过滤器限制:过滤器只能在插值 {{ }}v-bind 中使用,不能在 v-forv-if 等指令中使用

2. v-for 语法变更(重要!顺序反了)

这是最容易踩坑的变更:索引和项的顺序颠倒了

1
2
3
4
5
6
7
8
9
<!-- Vue 1.x:(index, item) -->
<ul>
<li v-for="(index, item) in items">{{ index }} - {{ item }}</li>
</ul>

<!-- Vue 2.x:(item, index),和数组方法保持一致 -->
<ul>
<li v-for="(item, index) in items">{{ index }} - {{ item }}</li>
</ul>

另外,v-for 现在必须加 key(推荐),用于高效更新 DOM:

1
<li v-for="item in items" :key="item.id">{{ item.name }}</li>

3. v-ifv-for 优先级变更

  • Vue 1.xv-for 优先级高于 v-if,会先循环再判断;
  • Vue 2.xv-if 优先级高于 v-for,会先判断再循环。

    建议:尽量避免在同一元素上同时用 v-ifv-for,可以用计算属性先过滤数据。

4. v-model 变更

  • **自定义组件的 v-model**:不再默认使用 value prop 和 input 事件,可通过 model 选项自定义:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Vue 2.x 自定义组件 v-model
    Vue.component('my-checkbox', {
    model: {
    prop: 'checked',
    event: 'change'
    },
    props: ['checked'],
    template: '<input type="checkbox" :checked="checked" @change="$emit(\'change\', $event.target.checked)">'
    });

5. v-elv-ref 被移除

统一用 ref 属性替代,通过 $refs 访问:

1
2
3
4
5
6
7
<!-- Vue 1.x -->
<div v-el:my-div></div>
// 访问:this.$els.myDiv

<!-- Vue 2.x -->
<div ref="myDiv"></div>
// 访问:this.$refs.myDiv

三、组件系统变更:更清晰、更强大

1. 组件定义方式变更

  • Vue.extend 仍可用,但推荐用对象字面量
  • 组件选项更严格props 必须显式声明,不能直接用 this.xxx 访问未声明的 prop。

2. Props 验证增强

Vue 2.x 的 props 验证更规范,支持类型、必填、默认值、自定义验证:

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 2.x Props 验证
Vue.component('my-component', {
props: {
// 基础类型检查
propA: Number,
// 多种类型
propB: [String, Number],
// 必填字符串
propC: {
type: String,
required: true
},
// 带默认值的数字
propD: {
type: Number,
default: 100
},
// 自定义验证函数
propE: {
validator(value) {
return value > 0;
}
}
}
});

3. 自定义事件变更

  • 移除了 .sync 修饰符(2.0 初期移除,2.3.0+ 重新引入,但用法不同);
  • 移除了 $dispatch$broadcast:不再推荐用事件冒泡/广播,改用Vuex(状态管理)或事件总线new Vue() 作为中央事件总线)。

事件总线替代方案

1
2
3
4
5
6
7
8
9
10
// 1. 创建事件总线
const EventBus = new Vue();

// 2. 发送事件
EventBus.$emit('user-updated', userData);

// 3. 监听事件
EventBus.$on('user-updated', (data) => {
console.log('收到用户更新:', data);
});

4. Slot 插槽系统重写(重要新特性)

Vue 2.0 的插槽系统更强大,新增了作用域插槽

(1)普通插槽语法变更

1
2
3
4
5
6
7
8
9
10
11
<!-- Vue 1.x -->
<my-component>
<div slot="header">这是头部</div>
<div slot="footer">这是底部</div>
</my-component>

<!-- Vue 2.x(2.6.0+ 推荐 v-slot) -->
<my-component>
<template v-slot:header>这是头部</template>
<template v-slot:footer>这是底部</template>
</my-component>

(2)作用域插槽(新特性)

允许子组件向插槽传递数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 子组件:my-list -->
<template>
<ul>
<li v-for="item in items" :key="item.id">
<!-- 向插槽传递 item -->
<slot :item="item"></slot>
</li>
</ul>
</template>

<!-- 父组件使用 -->
<my-list :items="users">
<template v-slot="{ item }">
<span>{{ item.name }} - {{ item.age }}</span>
</template>
</my-list>

四、生命周期钩子变更:对比与替换

Vue 2.0 调整了部分生命周期钩子,使其更符合 Virtual DOM 的渲染流程:

Vue 1.x Vue 2.x 说明
beforeCreate beforeCreate 保留,实例初始化前调用
created created 保留,实例创建完成后调用
beforeCompile beforeMount 替换,挂载前调用
compiled mounted 替换,挂载完成后调用
ready mounted 替换,不再有 ready,用 mounted 替代
- beforeUpdate 新增,数据更新前调用
- updated 新增,数据更新后调用
beforeDestroy beforeDestroy 保留,销毁前调用
destroyed destroyed 保留,销毁完成后调用
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
// Vue 2.x 生命周期示例
new Vue({
beforeCreate() {
console.log('实例初始化前');
},
created() {
console.log('实例创建完成,可访问 data、methods');
},
beforeMount() {
console.log('挂载前,DOM 未生成');
},
mounted() {
console.log('挂载完成,DOM 已生成');
},
beforeUpdate() {
console.log('数据更新前');
},
updated() {
console.log('数据更新后');
},
beforeDestroy() {
console.log('销毁前');
},
destroyed() {
console.log('销毁完成');
}
});

五、API 变更:常用方法的调整

1. $set$delete

  • Vue 1.xVue.set / vm.$set 用于响应式添加属性;
  • Vue 2.x:用法不变,但更推荐用 Vue.setvm.$set 解决数组索引/对象属性的响应式问题:
    1
    2
    3
    4
    5
    // Vue 2.x 响应式修改数组
    this.$set(this.items, index, newValue);

    // 响应式添加对象属性
    this.$set(this.user, 'age', 25);

2. 数组变异方法

Vue 2.x 仍保留了 7 个数组变异方法(pushpopshiftunshiftsplicesortreverse),直接调用会触发视图更新,但直接用索引修改数组不会触发更新,必须用 $set

3. 过渡系统重写

Vue 2.0 完全重写了过渡系统,用 <transition><transition-group> 组件替代了 1.x 的 transition 属性:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- Vue 1.x -->
<div v-if="show" transition="fade"></div>

<!-- Vue 2.x -->
<transition name="fade">
<div v-if="show"></div>
</transition>

<!-- 列表过渡 -->
<transition-group name="list">
<div v-for="item in items" :key="item.id"></div>
</transition-group>

对应的 CSS 类名也有变化:

  • 1.x:fade-enterfade-leave
  • 2.x:fade-enterfade-enter-activefade-leavefade-leave-active

六、迁移建议:顺利升级的步骤

  1. 使用官方迁移工具:Vue 提供了 vue-migration-helper 工具,自动扫描代码并提示变更:
    1
    2
    npm install -g vue-migration-helper
    vue-migration-helper src/
  2. 先看官方迁移指南:完整的官方迁移文档:https://v2.vuejs.org/v2/guide/migration.html
  3. 逐步升级
    • 先升级 Vue 核心库到 2.x;
    • 修复模板语法(尤其是 v-for 顺序、v-el/v-ref);
    • 替换生命周期钩子;
    • 重构组件通信(移除 $dispatch/$broadcast,引入 Vuex 或事件总线);
    • 重写过渡效果。
  4. 推荐使用单文件组件(SFC):Vue 2.x 对单文件组件支持更好,配合 webpack/vite 开发体验更佳。

七、总结

Vue 1.x 到 2.x 的变更虽然大,但核心思想(响应式、组件化)是一致的。2.0 的 Virtual DOM、作用域插槽、更清晰的生命周期,不仅提升了性能,还让代码结构更规范,为后续的 3.0 版本(Composition API)打下了基础。


vue 1.0->2.0变更
https://cszy.top/2017-03-21 vue-1-0-2-0变更/
作者
csorz
发布于
2017年3月21日
许可协议