文章目录
前言
自Vue3.0发布以来,看很多大佬都在评价Vue3.0,刚好公司有新的项目,于是使用3.0+Vite进行开发,不得不说确实很吊,于是在闲暇之余肝了这篇文章,这篇文章主要是对3.0一些新增特性以及API整理,介绍以及对3.0和2.0的差异进行简单的对。 希望这篇文章会对你理解3.0有些许帮助。一、Vue3.0新增特性
这部分主要对Vue3.0的新增API以及特性进行整理
1.性能方面
- 根据Vue3.0官方网站给出的数据,Vue3.0打包减少41%,初次渲染快55%,更新快133%,内存使用减少54%。相比这些数据的真实性不必言说,结合自身使用Vue3.0开发这段时间的感受来说,真的只能用一个字形容–“快”。
2.模块化打包
- Vue3.0 构建项目的index.html 中js的引入方式是这样的
<script type="module" src="/src/main.ts"></script>
- Vue2.0 构建项目的inde.html 中js的引入方式是这样
<script type="text/javascript"></script>
传统script标签的代码加载容易导致全局作用域污染,而且要维系一系列script的书写顺序,项目一大,维护起来越来越困难。ES module 通过声明式的暴露和引用模块使得各个模块之间的依赖变得明显。使得项目在维护上更加方便容易。
3.向下兼容
- Vue3.0支持大多数的2.0的特性,所以即使不太掌握3.0也可以暂时先使用2.0的语法进行过渡,这样的设计对前端开发者来说是非常友好的。
4.Teleport 组件
- Teleport组件可以把你写的组件挂载到任何你想挂载的DOM上,是很自由很独立的。 大家都知道Vue2.0中所有的组件都挂载在一个唯一的DOM节点上,但是在Vue3.0 中我们可以使用Teleport组件对自定组件进行包裹,在组件上有一个to属性,这个就是要写你需要渲染的DOM ID了,这个DOM可以创建在任何位置,只要它对应的ID是唯一的即可,比如:在index.html中可以创建一个id为modal的节点
<teleport to="#modal">
<div id="center">
<h2>自定义组件</h2>
</div>
</teleport>
<body>
<div id="app"></div>
<div id="modal"></div>
<script type="module" src="/src/main.ts"></script>
</body>
5.Suspense组件
- Suspense 组件主要针对Vue2.0 中异步组件实现,在实际的开发工作中我们有很多的业务是需要使用异步组件完成的。但是在Vue2.0中关于异步组件的实现过程是比较繁琐,判断请求状态,根据状态展示不同页面这些都是必不可少,Suspense组件的出现就是为了将这个复杂的过程简单化。下面简单举一个例子进行说明:
//img子组件
<template>
<img :src="result && result.imgUrl" />
</template>
<script lang="ts">
import axios from 'axios'
import { defineComponent } from 'vue'
export default defineComponent({
async setup() {
const rawData = await axios.get('请求地址')
return {result:rawData.data}
}
})
//父组件
import ImgBox from "./components/ImgBox.vue";
<template>
<div>
<Suspense>
<template #default>
<Img-box />
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</div>
</template>
</script>
- 提醒大家需要注意的是Suspense包裹的组件必须要返回一个为promise对象,否则是不能实现。
- #default 槽口中需要注入的是我们的组件
- #fallback 槽口中展示的就是我们异步组件,加载过程中的展示样式,当然这块我们可以利用上面说的到的 Teleport 组件创建一个全局的加载组件。
6.Composition API
二、Vue3.0与2.0的差异
这部分主要对Vue3.0与Vue2.0的差异进行比对
1.生命周期函数升级
- setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
- onBeforeMount() : 组件挂载到节点上之前执行的函数。
- onMounted() : 组件挂载完成后执行的函数。
- onBeforeUpdate(): 组件更新之前执行的函数。
- onUpdated(): 组件更新完成之后执行的函数。
- onBeforeUnmount(): 组件卸载之前执行的函数。
- onUnmounted(): 组件卸载完成后执行的函数
- onActivated(): 被包含在中的组件,会多出两个生命周期钩子函数。被激活时执行。
- onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。
- onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。
下面是一个更加直观的对比:
Vue2--------------vue3
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
errorCaptured -> onErrorCaptured
2.响应式系统升级
- 2.x的响应式是基于Object.defineProperty实现的代理,兼容主流浏览器和ie9以上的ie浏览器,能够监听数据对象的变化, 但是监听不到对象属性的增删、数组元素和长度的变化,同时会在vue初始化的时候把所有的Observer都建立好,才能观察到数据对象属性的变化。
- 针对上面的问题,3.0进行了革命性的变更,采用了ES2015的Proxy来代替Object.defineProperty,可以做到监听对象属性的增删和数组元素和长度的修改,还可以监听Map、Set、WeakSet、WeakMap,同时还实现了惰性的监听,不会在初始化的时候创建所有的Observer,而是会在用到的时候才去监听。
- 但是,美中不足就是这样修改虽然主流的浏览器都支持Proxy,ie系列却还是不兼容,所以针对ie11,vue3.0决定做单独的适配,暴露出来的api一样,但是底层实现还是Object.defineProperty,这样导致了ie11还是有2.x的问题。但是绝大部分情况下,3.0带来的好处已经能够体验到了。
3.setup 函数与data的区别
大家都知道Vue2中响应式的数据只需要定义在data函数中然后return就行,在Vue3.0 中依旧可以采用这种方式来进行,但是Vue3.0 中引入的setup函数可以完全替代之前旧版本的data、methods 等等。下面就是一个setup 函数:
<template>
<tabbarCom :active="active" />
</template>
setup(props,ctx) {
const data = reactive({
active: 0,
taskList: [],
getData: () => {
getsopList({})
.then((result: any) => {
data.taskList = result;
})
.catch((err) => {});
},
});
onMounted(() => {
data.getData();
});
const refData = toRefs(data);
return { ...refData };
},
- 首先要说的是setup 函数有两个参数,props 和context (上下文对象),props,ctx主要用来进行父子组件传值。
- reactive 函数 将解包所有深层的 refs,同时维持 ref 的响应性
- toRefs 将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的。这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开。
3.watch差异
Vue2中也有watch-监听器(侦听器),作用是用来侦测响应式数据的变化,并且可以得到newValue新值和oldValue老值。如果你熟悉Vue2一定熟悉这个函数,但在Vue3中watch有了一些细微的变化。
//2.0
watch: {
list(old, newVal) {
this.page = 1;
},
},
//3.0
import {... , watch} from "vue"
//watch 函数需要写在setup中
//overText为你要监听的变量
watch(overText, (newValue, oldValue) => {
});
//同时监听多个变量
watch([overText, overText1], (newValue, oldValue) => {
console.log(`new--->${newValue}`);
console.log(`old--->${oldValue}`);
console.log(newValue[0]); //返回的newValue也是一个数组
});
4.emit 差异
Vue2.0中emit 抛出的时候可以直接通过this.$emit 调用,但是在3.0x中我们需要先对抛出的函数在emits中进行声明,然后才能在函数中调用。案例如下:
emits: ["linkto"]
setup(props: any, ctx: any) {
const data = reactive({
linkTo: (item: any) => {
ctx.emit("linkto", item.externalUserid);
},
const refsData = toRefs(data);
return { ...refsData };
5.computed差异
//无参数
const filterMsg =computed( () => msg.value + "fdfasdf")
//有参数
const filterMsg2 =computed(() => {
return function(num) {
return msg.value + num
}
})