VUE3.0有哪些新特性-细数vue2.0到3.0更改了什么?

349 阅读8分钟

vite

webpack打包会把各种各样的模块打 成静态的进bundle包, 不管代码是否用得到,都会被打进去,所有随着项目越来越大,打包文件也越来越大,越来越耗时。 vue.config.js

3.x

快速的冷启动 即时热模块更新 真正按需编译 生成环境下用rollup打包 tree-shaking摇树 vite.config.js

总结

优:1、源代码通过ES Import直接提供给浏览器,没有打包工作要做所以冷启动非常快。 2、代码是按需编译的,只有在当前页面上实际导入的代码才会编译。不用等到整个应用打包完成后 3、热模块更新(HMR)的性能与模块总数解耦。 减少不必要的重启或模块更新的时间,加快开发进度。 缺:生态圈还不够完善;浏览器原生的ES模块导入功能,不支持IE11

vite介绍

Vite是Vue的作者尤雨溪开发的Web开发构建工具,它是一个基于浏览器原生ES模块导入的开发服务器,在开发环境下,利用浏览器去解析import,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随启随用。同时不仅对Vue文件提供了支持,还支持热更新,而且热更新的速度不会随着模块增多而变慢。在生产环境下使用Rollup打包。

vite作用

使用Vite来开发Vue 3项目可以减少不必要的等待项目重启或模块更新的时间,加快开发进度。在生成环境下,依然需要对项目进行打包-rollup打包,以避免频繁的网络请求,

rollup

rollup最大的亮点就是Tree-shaking,即可以静态分析代码中的 import,并排除任何未使用的代码。这允许我们架构于现有工具和模块之上,而不会增加额外的依赖或使项目的大小膨胀。

劫持方式

2.x

Object.defineProperty( get,set,value, writable,enumerable,configurable) 是否可以直接修改value 是否可以直接遍历 属性是否可配置

3.X

ES2015的Proxy proxy api劫持整个对象 getter中去递归响应式,这样的好处是真正访问内部对象才会变成响应式,而不是无脑递归。 ES module

总结

  • 可以直接监听数组的变化,2.0是重写了数组的7个方法push,pop,shift,unshift,splice,sort,reverse
  • 可以直接监听对象了,2.0监听的是对象的属性;颗粒度过小时性能较低
  • 可以监听多种数据格式(Array,Object,Map,Set,WeakSet,WeakMap)
  • 返回的是一个新对象可以,操作新的对象达到修改;,2.0遍历对象属性在原对象上修改 缺:兼容性,放弃了ie全系包括ie11

为什么需要虚拟DOM

dom是昂贵的,昂贵的一方面在dom本身的重量,dom节点在js里的描述是个非常复杂属性很多原型很长的超级对象, 另一方面是浏览器渲染进程和js进程是独立分离的,操作dom时的通信和浏览器本身需要重绘的时耗都是很高的。 所以大家机智的搞了个轻量的vdom去模拟dom,vdom每个节点都只挂载js操作的必要属性,每次组件update时都先操作vdom,通过vdom的比对,得到一个真实dom的需要操作的集合。整个机制是在JavaScript层面计算,在完成之前并不会操作DOM,等数据稳定之后再实现精准的修改。

diff

2.X

虚拟dom全量对比(通过循环递归对所有节点进行依次对比),多层父子关系时不断地递归调用 patchVNode

3.x

生成的时候打上 PatchFlag 标记,只会更新有动态标识的,静态标识的只会被创建一次

总结

优:解决了虚拟DOM全量对比的痛处,特别是在父子多层嵌套的时候。 网传对比速度提升6倍

源码编写语言

2.x

js、flow

3.x

typescript,monorepo

总结

优:提升自身代码的可维护性

目录

2.x

src > routet > index.js static在项目根目录下

3.x

src > router.js public文件夹中

总结

router 提升了一层 静态文件复制到了public文件中

插槽

2.x

父组件会重新渲染

3.x

作用域插槽改成了函数的

总结

只会影响子组件的重新渲染

生命周期

2.x

  1. beforeCreate
  2. created
  3. beforeMount
  4. mounted
  5. beforeUpdate
  6. updated
  7. beforeDestroy
  8. destroyed

3.x

  1. onBeforeMount
  2. onMounted
  3. onBeforeMount
  4. onMounted
  5. onBeforeUpdate
  6. onUpdated
  7. onBeforeUnmount
  8. onUnmounted

总结

setup()函数替代 beforeCreate和created; 一大堆的东西放到了setup函数中

组件

2.x

option代码组合 相关业务的代码需要遵循option的配置写到特定的区域 异步组件:是通过返回 Promise 创建

3.x

组合逻辑代码函数composition API

  • setup()
  • reactive
  • ref()
  • isRef
  • torefs()
  • toRef
  • watchEffect
  • shallowReactive
  • shallowRef:
  • customRef
  • readonly
  • shallowReadonly
  • Fragments 异步组件:函数式组件-纯函数。需要通过将其包裹在新的defineAsyncComponent中

总结

解决代码耦合度,更好的代码复用. 借鉴的react的吗,是不是感觉有点化简为繁了.

Composition Api

  • setup()函数是vue3中专门新增的方法,Composition Api的入口;
  1. 在beforecreate之后,create之前执行.
  2. context:setup()的第二个参数是一个上下文对象,这个上下文对象大致包含了这些属性,
  3. 注意:在setup()函数中无法访问this
  • reactive是用来创建一个响应式对象,等价于2.x的Vue.observable

  • ref()函数用来给定的值创建一个响应式的数据对象,ref()的返回值是一个对象,这个对象上只包含一个.value属性

  • isRef用来判断某个值是否为ref创建出来的对象

  • torefs()函数可以将reactive()创建出来的响应式对象转换为普通的对象,只不过这个对象上的每个属性节点都是ref()类型的响应式数据

  • toRef为源响应式对象上的某个属性创建一个ref对象,二者内部操作的是同一个数据值,更新时二者是同步的。相当于浅拷贝一个属性

  • watchEffect:不需要指定监听属性,可以自动收集依赖,只要我们回调中引用了响应式的属性,那么这些属性变更的时候,这个回调都会执行

  1. watch可以获取到新值和旧值,而watchEffect获取不到
  2. watchEffect会在组件初始化的时候就会执行一次与computed同理,而收集到的依赖变化后,这个回调才会执行
  • shallowReactive:只处理对象最外层属性的响应式(也就是浅响应式),所以最外层属性发生改变,更新视图,其他层属性改变,视图不会更新

  • shallowRef:只处理了value的响应式,不进行对象的reactive处理.

  • customRef:创建一个自定义的ref,并对其依赖跟踪和更新触发进行显式控制.

  • readonly:深度只读数据,

  • shallowReadonly:浅只读数据

  • Fragments:允许一个组件可以有多个根节点

语法

2.x

  1. 一个组件只能一个根节点
  2. v-model 一个值 propo,updata
  3. v-for 高于 v-if 的优先级
  4. v-for嵌套v-for时效率低下
  5. this.$children 访问子组件
  6. 修饰符
  7. 自定义指令的钩子(bind,inserted,update,componentUpdated,unbind,)
  8. 动态组件is
  9. $data选项可以是Object或Function
  10. mixin$Data合并时 深合并-子相动取组件的
  11. 全局事件监听器on,on,off,$once
  12. 过滤器
  13. Vue.nextTick()
  14. render 函数会自动接收 h 函数
  15. 普通插槽和作用域插槽16.
  16. 过渡的 classv-enter,v-leave
  17. transition 应该是被子元素触发的,而不是自己切换
  18. @hook:updated="onUpdated"

3.x

  1. 支持多根节点组件
  2. v-model:title 可以 绑定多个了
  3. v-if 高于 v-for 的优先级
  4. 单个绑定获取多个 ref将 ref 绑定到一个更灵活的函数上
  5. 移除掉了
  6. 移除了.native修饰符
  7. 指令钩子和组件钩子统一了
  8. 动态组件改成了 v-is指令
  9. 只接受Function
  10. mixinData合并,浅合并。Data合并, 浅合并。Data返回的对象相同的,不再合并子,直接用取组件的$Data
  11. 移除了on,on,off,once。庆幸的是once。庆幸的是emit还在
  12. 移除了过滤器,建议用计算属性
  13. import { nextTick } from 'vue';先引入再调用了nextTick(() => {})
  14. h 现在是全局导入的,不再作为参数自动传递了
  15. this.$slots
  16. 组件在呈现之前异步请求,Suspense允许在组件树上进一步处理等待
  17. v-enter-from,v-leave-from
  18. 修复了
  19. @vnode-updated="onUpdated"生命周期监听前缀更名

扩展

Monorepo

Monorepo 是管理项目代码的一个方式,指在一个项目仓库 (repo) 中管理多个模块/包 (package),不同于常见的每个模块建一个 repo。 大多 monorepo 即会使用 lerna 又会在 package.json 声明 workspaces。这样的话,无论你的包管理器是 npm 还是 yarn,都能发挥 monorepo 的优势;要是包管理是 yarn ,lerna 就会把依赖安装交给 yarn 处理。 git添加一个子模块:git submodule add git@github.com:xxx/xxx.git path/to/xxx 可以在 .gitmodule文件中看到当前 repo 有哪些 submodule,分别的 name, branch 等

  • 初始化 git submodule 信息 --> git submodule init

  • 更新 submodule,相当于 git pull 吧 --> git submodule update