Vue3 有哪些提升

这里的主要关注点是vue3相比于vue2带来了哪些提升,具体API的使用就不再细述。

下面从vue3的几大新特性来逐个展开。

一、Composition API

Composition API,即组合式API

  • 高内聚

    聚合业务逻辑,提高代码可读性

    • vue2 通过属性选项(options,如 data、computed、methods 等)书写代码逻辑,代码逻辑点是碎片化、跳跃式的,在大型项目和复杂组件中使得维护变得困难。

    • vue3 的组合式API能够将分散的逻辑代码组合在一起,使代码逻辑更清晰易读。

      1.png
  • 低耦合

    便于代码拆分,提高复用性

    • Vue2 中的一个常用代码复用方式是 mixins 混入,mixins在一些场景下确实能很大的提升代码复用率,但同时也会带来一些副作用,比如依赖关系不清晰,mixins里定义的data和methods等在组件中使用时没有明确的引入和定义,而且可能与组件里定义的有命名冲突,有很大的维护风险。

    • 得益于组合式API,vue3里可以通过自定义hooks来实现类似mixins的复用效果,而且不会有vue2里mixins的缺点。

      扫描二维码关注公众号,回复: 13715155 查看本文章

      https://blog.csdn.net/u010059669/article/details/111688244

    2.png
  • 更简化的<script setup>语法

    https://blog.csdn.net/u010059669/article/details/119780334

    • <script setup>语法是 composition api的一个语法糖,代码编写更加简洁,已经发布正式版本,vue3.2+支持,推荐使用。

    • defineExpose :使用 <script setup> 的组件是默认关闭的,在它的父组件中通过this.$refs默认是拿不到它所绑定的数据和方法,只有通过defineExpose暴露出去的才能拿到,这个API设计能显著的解决this.$refs导致的代码耦合和维护风险问题。

      // 子组件
      <script setup>
      import {
                
                 ref } from 'vue'
      
      const a = 1
      const b = ref(2)
      const c = ref(3)
      
      defineExpose({
                
                
        a,
        b
      })
      </script>
      

二、Teleport

Teleport,即传送门。

能在不改变组件内部元素父子关系的情况下,将子元素“传送”到其他指定节点下渲染

  • 应用场景:比如弹窗组件中,多级弹窗嵌套的场景,css的z-indx不方便处理。
<template>
  <div class="container">
    <teleport to="body">
      <div class="dialog">
        ...
      </div>
    </teleport>
  </div>
</template>

三、Fragment

Fragment,即片段。

  • 在 2.x 中,由于不支持多根节点组件,当开发者意外创建多个时会发出警告。
  • 在 3.x 中,组件可以包含多个根节点。Vue3 中,组件的 template 被一层不可见的 Fragment 包裹,支持多个根节点。能够减少 dom 层级、提升渲染性能
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

四、Emits

Emits,即组件触发的自定义事件。

  • 在vue2中,组件封装时触发自定义事件给父组件,都是通过 this.$emit()触发,但是触发地点可能会遍布在组件内各个地方,没有统一管理,使用不方便。

  • vue3里,所有自定义事件都要在emits里定义,和定义props类似,而且还能对事件做自定义校验。这样在使用组件时很方便的就能知道有哪些事件可以使用。

    import {
          
           defineComponent } from 'vue';
    
    export default defineComponent({
          
          
      props: {
          
          
        isOpen: Boolean,
      },
      emits: {
          
          
        'closeModal': null,
      },
      setup(props, context) {
          
          
        const clickButton = () => {
          
          
          context.emit('closeModal');
        }
        return {
          
          
          clickButton,
        }
      },
    })
    

五、动态css

<style> 样式标签可以通过 v-bind 绑定<script>里定义的变量,来实现动态的css样式。

个人不推荐使用

  • <template>
      <div class="text">hello</div>
    </template>
    
    <script>
    export default {
            
            
      data() {
            
            
        return {
            
            
          color1: 'red'
        }
      }
    }
    </script>
    
    <style>
    .text {
            
            
      color: v-bind(color1);
    }
    </style>
    

六、Tree shaking

Tree shaking,一种按需打包的方式。

由于 es6 的模块化导入导出是静态可分析的,所以在打包的时候通过解析js代码就能明确知道哪部分代码使用了、哪部分代码没有使用,然后只对使用到的代码进行打包,这样就能实现按需打包的效果。

  • vue3 一共开放了113个API,均支持 tree shaking,可通过以下类似的方式引用:

    import {
          
           ref, reactive, h, onMounted } from "vue"
    

    没有引用的模块不会处理,这样打包速度、打包体积、以及运行速度都会有提升。

  • 不仅是vue3,相配套的vue-router4和vuex4都支持了tree-shaking。

七、VDOM

https://blog.csdn.net/summer_zhh/article/details/108080930

VDOM,即vue里的虚拟DOM。

vue3里对VDOM进行了重写,优化了Diff算法:

  • vue2在对比VDOM时,会遍历整个VDOM树,从根节点依次递归遍历到末节点,从而找出所有变化的节点进行局部更新。

  • vue3会区分静态DOM节点和动态DOM节点,对动态DOM节点做一个 PatchFlag 标记,并将动态节点与根节点绑定,这样,在数据更新对比VDOM时,会从根节点里查找 PatchFlag 标记,跳到动态节点上直接比较,不用遍历静态节点,提升渲染更新的性能。

    <template>
      <div>hello</div>
      <div>{
         
         {title}}</div>
    </template>
    
    <script>
    export default {
            
            
      data() {
            
            
        return {
            
            
          title: '标题'
        }
      }
    }
    </script>
    

八、Proxy

proxy,是es6新增的一个api,可以对对象进行数据劫持。

  • vue2里是使用Obejct.definePropery来实现数据的响应式,存在一些弊端:

    • 这个api只能传入对象的特定属性进行劫持,所以vue2里是初始化时递归遍历对象所有层级的属性,依次调用Obejct.definePropery方法来实现数据响应式,层级较深时影响性能。
    • 对象新增的属性不会劫持,不具有响应式,所以开发过程中也经常会遇到这个问题。解决方式一般是在数据定义时给属性加个默认值,或者通过this.$set()手动处理。
    • 这个api不能作用于数组,所以vue2是通过重写数组原型的几个方法来实现数据监听。
    Object.defineProperty(obj, prop, descriptor)
    
  • vue3是使用的proxy api,这个api传参是一个对象或者数组,api内部会原生实现对象属性或数组元素的数据劫持,包括对象的新增属性和数组元素都具有响应式,所以在开发使用效率和运行效率上都有很大的提升。

    new Proxy(target, handler)
    

九、createRenderer

createRenderer,是vue3新增的一个API,用来创建自定义渲染器,实现更好的跨平台应用。

import {
    
     createRenderer } from '@vue/runtime-core'

const {
    
     render, createApp } = createRenderer({
    
    
  patchProp,
  insert,
  remove,
  createElement,
  // ...
})
  • vue默认是用于浏览器端的,所以从虚拟DOM到真实的DOM的映射渲染都是基于浏览器原生BOM API实现的,vue3通过createRenderer这个API暴露了自定义渲染方式,跨平台框架就可以基于此实现虚拟DOM到其他平台DOM的映射。

  • 常见的前端跨平台方案:

    • 一种是解析原代码语法生成AST抽象语法树,然后生成相应平台的代码语法,这种方式更加通用彻底,但由于不同平台的语法功能差异,不能做到完全的转换支持,语法使用上会有很多限制。

    • 另一种就是自定义虚拟DOM到真实DOM的映射,这种方式不做语法转换,可以获得原框架全部的开发体验,京东taro的v3版本就是这种实现方式。

      • 如果原框架本身没有暴露虚拟DOM到真实DOM的映射API,要打造跨平台框架一般就选择fork一份原框架的源码,改写其中的映射逻辑来实现,老的一些框架如weex、mpvue就是fork的vue2实现的。
      • vue3通过createRenderer这个API暴露出自定义渲染方式,这样就不用改写原框架源码,能直接使用这个API实现跨平台逻辑,对原框架的版本更新也能更加及时的同步支持。

十、TS支持

TypeScript,是js的一个超集,或者说是加了一层包装,对js做了功能拓展和更严谨的代码校验。

  • vue2对ts的支持很不友好,强行使用ts需要引入很多库,使用繁琐,而且支持也不全面。
  • vue3本身就是用ts编写的,对ts可以说是全方位的支持。

十一、Vite

Vite,基于原生es模块的新型前端构建工具。

  • 相对于传统的webpack,vite有着极快的项目启动速度,以及热更新速度。
  • 和vue3是同一作者(尤雨溪),所以对vue3的支持比较好。
  • 社区插件也在不断的完善中,未来有望取代webpack。
    https://blog.csdn.net/u010059669/article/details/121808645?spm=1001.2014.3001.5501

参考文档:https://juejin.cn/post/7036774227583696933

猜你喜欢

转载自blog.csdn.net/u010059669/article/details/121806366
今日推荐