前提
vue3.0的正式发布已有些时日,应该已经有很多人跃跃欲试,从各个维度来上手vue3.0。也许是尝试vue3.0的小项目、也许是浏览分析3.0的文章,甚至很快的出现了关于vue3.0的面试八股文:"vue2.0和vue3.0区别是什么?"
我看了很多vue2.0与vue3.0对比的文章,有的说得很浅,短短几行就概括了区别所在“速度快、体积小、易维护”,让我感觉学会了,但又没完全学会;有的也说得很深,“我们一起从源码分析一下,3.0对比2.0到底有哪些变化”,让我顿时有了清晰的自我认知——我真的好菜。
从自我感觉无法参透vue3.0,到进一步发散思维,思考我是不是太菜了、应该换个行业、开始卖早餐会不会起不来······不过就是几个小时。
在我思考人生的间隙,很突然,脑子里突然出现了尤大大的脸。
我感觉自己就像西游记里被观音点醒的白龙(马)。
介绍
其实vue3.0和vue2.0整体具有一致性,毕竟是升级,不是全部推翻重来,所以很多2.0所具备的功能部分,在3.0里是延续的。3.0对比2.0添加了全新的部分,也有了删减,但也不乏一些“细小的更改”,可能是一个名字,也可能是一个写法的变化。
所以,我决定从文档出发,一点一滴的横向对比vue2.0和vue3.0。计划分成三部分,分别为:基础对比、组件对比、可复用部分对比。
希望能通过文章,让大家能清晰的看出2.0与3.0之间的相同与区别。
(对比差异部分,使用2️⃣3️⃣分别表示vue2.0与vue3.0)
vue 基础部分对比
(对比差异部分,使用2️⃣3️⃣分别表示vue2.0与vue3.0)
vue的介绍
vue的简介
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
渐进式框架:只关注图层,可以自底向上逐层应用(自认为,即可以简单的在html文件内应用vue,也可以完整的使用vue框架进行高级使用)
vue的特点
1、声明式渲染:在js中更新状态,却不用触碰DOM,只需关注逻辑层。
2、响应式:数据与DOM关联,数据变化页面上对应DOM同时变化。
3、组件化构建:在vue里,基本上每个应用都可以抽象为组件树,方便管理和复用。
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
安装方法
1、CDN包引入:在html里引用js,直接写单文件页面,方便学习。
2、下载js并自行托管:通过 <script> 标签引入。
3、npm方式:
2️⃣`$ npm install vue`
3️⃣`$ npm install vue@next`
4、vue-cli构建项目。3️⃣备注:应该使用 Vue CLI v4.5。
5、3️⃣新增:Vite方式。vite是web开发构建工具,能快速构建vue项目。
实例
创建实例
2️⃣`var vm = new Vue({})`
3️⃣
const app = Vue.createApp({})
或
import { createApp } from 'vue'
const app = createApp({})
vue3.0引入 createApp 这个全局API,会返回一个应用实例,这样原来Vue.xxx的api,基本上能用app.xxx来使用。
数据
1、分析:需要包裹在data内的数据才具备向响应性。
2、使用:
2️⃣data 为对象/返回对象的函数。
3️⃣data 仅能为返回对象的函数。 以$data形式存储在实例中,且合并多个mixin时,data只是浅层次的合并。
方法
methods 包含所需方法的对象。主动绑定了this,始终指向组件实例。
生命周期
1、beforeCreate
2、created
3、beforeMount
4、mounted
5、beforeUpdate
6、updated
7、2️⃣beforeDestroy=>3️⃣beforeUnmount
8、2️⃣destroyed=>3️⃣unmounted
9、activated(被 keep-alive 缓存的组件激活时调用)
10、deactivated(被 keep-alive 缓存的组件失活时调用)
模板语法
基础指令
-
{{msg}},可绑定js表达式。可配合 v-once 可一次性插值。
-
v-text,相当于 {{msg}}。
-
v-html
-
数据绑定 (缩写 :)
1、用法:
v-bind:xxx="dataName"2、若绑定值为null/undefined/false,该属性甚至不会被包含在渲染出来的元素中。
3、绑定顺序决定合并顺序:
2️⃣单独属性和绑定属性同时存在时,单独属性覆盖绑定属性。
<!-- 模板 --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- 结果 --> <div id="red"></div>3️⃣根据绑定的顺序决定如何被合并,后绑定覆盖前绑定。
<!-- 模板 --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- 结果 --> <div id="blue"></div> <!-- 模板 --> <div v-bind="{ id: 'blue' }" id="red"></div> <!-- 结果 --> <div id="red"></div>
动态指令
方括号[js表达式],js表达式要得到一个字符串,否则为null(就会被移除绑定)。
<a v-on:[eventName]="doSomething"> ... </a> 也可用缩写@[eventName]
<a v-bind:[attributeName]="url"> ... </a> 也可用缩写:[attributeName]
计算属性和侦听器
计算属性 computed
分析
1、简介:
计算属性适用于包含响应式数据的复杂逻辑处理,依赖于已有的property,所以当数据变化时,对应的计算属性也会更新。
2、特点:
1)适合响应式数据的复杂逻辑处理。
2)计算结果缓存。
计算属性与方法进行对比
1、这和用一个方法进行复杂计算,对应位置调用方法得到一样的结果。
2、计算属性有缓存效果,若对应依赖没有改变,多次访问计算属性会立刻返回缓存的计算结果。
3、每次触发方法,方法都会再次执行函数。
使用
声明计算属性,用作property,通过函数的方式,处理复杂的逻辑,通过return暴露计算结果。
1、一般使用:
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
2、默认只有getter,但也可以用setter:
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
3️⃣vue3.0 添加了组合式API内的计算属性写法,等到组合式API内容再拓展。
侦听器 watch
适用场景
观察和响应 Vue 实例上的数据变动,适用于数据变化时,执行异步操作,如重新请求。
使用
1、通过函数的方式,监听响应式数据。
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
if (newQuestion.indexOf('?') > -1) {
this.getAnswer()
}
}
}
2、使用实例方法的方式:vm.$watch( source, callback, [options] ),其中的 source ,可以为顶层的data、props或computed,更复杂的用函数代替。
侦听器的可选选项
1、deep:true【深度监听】
2️⃣适用于监听对象内部变化,数组的变更不用此选项。
3️⃣适用于监听对象内部变化,也适用于监听数组的变更。(侦听数组,数组只有被替换才会触发回调,其他情况下如果也需要触发,需要使用 deep:true)
2、immediate:true【立即触发回调】
3、3️⃣vue3.0 新增 flush:'pre'/'post'/ 'sync'【侦听的不同刷新时机】
1)pre:渲染前被调用,默认值
2)post:推迟到渲染之后调用
3)sync:一旦值发生了变化,回调将被同步调用
计算属性与侦听属性的对比
1、计算属性适用于复杂逻辑,可依赖多个已有属性。
2、侦听属性适用于观察变化,进而进一步执行其他行为,如访问API。
Class 与 Style的绑定
Class 的绑定
1、使用::class="xxx",xxx可为:字符串/对象/数组/对象的计算属性/三元表达式/数组内的对象。
2、备注:
1)使用组件时,父组件在子组件的使用处添加了class,渲染时class会被添加到该子组件的根元素上(子组件的最外层)
2)3️⃣由于3.0允许组件存在多个根元素,若组件有多个根元素,可在需要接收的根元素上使用 :class="$attrs.class" ,规定哪个根元素接收对应class。
Style 的绑定
1、使用 :style="xxx",xxx可为:对象属性/完整样式对象/计算属性/数组。
条件渲染
v-if/v-else-if/v-else
-
特点:
1、是插入/移除元素,切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
2、具有惰性,直到第一次条件为真才渲染条件块。
-
关于唯一标识符key:
2️⃣如果不使用key,但使用了相同的元素,在切换时不会重新渲染,会直接复用。如果想表示两个元素完全独立不想要复用,则可添加具有唯一值的key,这样每次切换时,都会被重新渲染。
3️⃣vue自动生成唯一的key,key不再必须。
v-show
始终渲染,区别仅为切换css的display,只是展示与否的区别。
v-if与v-show对比
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
列表渲染 v-for
-
作用:把数组/对象/整数遍历为一组元素,可通过v-bind将item传入组件。
-
特点:就地更新。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素。
-
使用:
v-for="item in/of items"1、items源数组可为:数组/对象/整数/计算属性。
1)数组:(item,index) 2)对象:(value,name,index),按 Object.keys() 的结果遍历。 3)整数:相当于重复对应次数。 4)计算属性:可针对源数组进行处理后遍历。2、关于key:便于追踪每个节点的身份,从而重用和重新排序现有元素。
template标签
2️⃣作为包裹元素,不渲染,常常配合条件渲染或列表渲染进行使用。
3️⃣当配合条件渲染/列表渲染使用时,仍为包裹元素不进行渲染,但不作为特殊指令的标记使用时,会被视为普通元素,并进行渲染。
v-if 与 v-for 的优先级
不建议同时使用。
2️⃣v-for 具有比 v-if 更高的优先级,若一起使用在同元素,相当于每个item都v-if。
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
相当于
<li v-for="todo in todos">
<span v-if="!todo.isComplete">{{ todo }}</span>
</li>
3️⃣v-if具有比v-for更高的优先级,即v-if无权限访问v-for内的变量。
//错误
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
事件处理 v-on
监听事件
v-on:xxx(缩写@)
1、可直接写简单事件逻辑,如 v-on:click="counter += 1"
2、可接收需要调用的方法名,如需访问原始DOM,在调用时可传入$event,对应位置即可event访问。
3、3️⃣vue3.0 新增多事件处理器,@click="one($event), two($event)"
事件修饰符
v-on.修饰符="xxx"
2️⃣具有native修饰符,可将原生 DOM 监听器添加到子组件的根元素中,可以使用 .native 修饰符。
3️⃣vue3.0 删除了native修饰符。vue3.0添加了emits选项,可定义组件可触发的事件。
按键修饰符
v-on:KeyboardEvent.key="xxx"
2️⃣允许使用按键码作为修饰符。
3️⃣不再支持使用数字 (即键码) 作为 v-on 修饰符。
表单输入绑定 v-model
-
作用:在表单类元素中,创建双向数据绑定。
-
本质:语法糖。相当于监听用户的输入事件,获取到了变化,并主动触发事件进行值的更新。
<input v-model="searchText"> 相当于 <input v-bind:value="searchText" v-on:input="searchText = $event.target.value" > -
适用场景:表单类
<input>、<textarea> 及 <select> -
修饰符:
1、.lazy。本来每次input都同步,如果用了这个,就变成change事件后才同步。
2、.number。相当于parseFloat(),输入字符串转为有效的数字。
3、.trim。自动过滤用户输入的首尾空白字符。
结尾
以上为vue文档中的基础部分。
包含了vue2.0与vue3.0共同点,其中还用显眼的2️⃣与3️⃣,分别标注了vue2.0与vue3.0的增删改的内容。
接下来计划,以相同的vue2.0与3.0文档横向对比方式,对比组件组件、可复用部分等内容。
如果能让很小一部分的读者有收获,就能让我感觉自己棒棒啦。
传送门
vue2.0与vue3.0 基础部分 对比:根据文档横向对比vue2.0与vue3.0(一)
vue2.0与vue3.0 组件部分 对比:根据文档横向对比vue2.0与vue3.0(二)
vue2.0与vue3.0 可复用&组合 对比:根据文档横向对比vue2.0与vue3.0(三)
vue2.0与vue3.0 零碎部分 对比:根据文档横向对比vue2.0与vue3.0(四)