初探 vue3

550 阅读2分钟

1.效率与体积

  • 与vue2.x相比,mount提升50%,内存占用小120%;官方宣称有1.3到2倍的性能提升。

  • 核心代码 + Compostion API: 13.5KB, 最小11.75KB。

  • vue3所有的Runtime为22.5kb;Vue2是32KB;

    vue.js和vue.runtime.js 的区别和使用方法

2.变化

  • 使用TS重新编写。
  • 按需编译。
  • 按需加载:默认加载基础的Virtual DOM,响应式算法;对于不常用的功能,则按需加载;eg:v-model,Transtvion。
  • 新增组合API。
  • 新增Fragment(碎片),Teleport(全局),Suspense(组件里面异步加载其他组件)。

3.Compiler原理

  • 作用:vue-template-compiler作用是可以将Vue单文件组件(SFC)中的template部分编译成render函数;注意,这部分编译是在浏览器中进行的,所以Vue3中对Compiler的优化提高了js处理速度,减少了内存的占用。

  • vue提供了在线工具,输入template内容可以得到编译之后的结果。

    vue2地址: template-explorer

    vue3地址: template-explorer

  • 优化

    • 动态节点标记

      eg:Hello World!是一个静态节点;{{msg}} 是一个动态节点,则会有标记:1 /* TEXT */

        <div>Hello World!</div>
        <div>{{msg}}</div>
    
    
    import { createVNode as _createVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock(_Fragment, null, [
        _createVNode("div", null, "Hello World!"),
        _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
      ], 64 /* STABLE_FRAGMENT */))
    }
    
    // Check the console for the AST
    }
    
    • hoistStatic
        <div>Hello World!</div>
        <div>{{msg}}</div>
    

    未开启hoistStatic之前

    import { createVNode as _createVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock(_Fragment, null, [
        _createVNode("div", null, "Hello World!"),
        _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
      ], 64 /* STABLE_FRAGMENT */))
    }
        
    

    开启hoistStatic,抽离分离静态节点。

    import { createVNode as _createVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    
    const _hoisted_1 = /*#__PURE__*/_createVNode("div", null, "Hello World!", -1 /* HOISTED */)
    
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock(_Fragment, null, [
        _hoisted_1,
        _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
      ], 64 /* STABLE_FRAGMENT */))
    }
    

    开启hoistStatic,合并多个大量得静态节点为字符串(连续>=10静态节点)。

    import { createVNode as _createVNode, toDisplayString as _toDisplayString, createStaticVNode as _createStaticVNode, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    
    const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World!</div><div>Hello World3333!</div><div>Hello World!</div>", 10)
    
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock(_Fragment, null, [
        _hoisted_1,
        _createVNode("div", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
      ], 64 /* STABLE_FRAGMENT */))
    }
    
    • cacheHandlers

      对组件绑定的事件进行缓存,不会每次都创建新的,使用cache中的;减少内存的占用。

    import { toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"
    
    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", {
        onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.handle && _ctx.handle(...args)))
      }, _toDisplayString(_ctx.msg), 1 /* TEXT */))
    }
    

旧项目的升级

  • 90%以上的逻辑可以复用vue2。
  • vue3 废弃了 beforeCreate,create 生命周期钩子函数,vue3需写在setup()函数内。
  • vue3不推荐使用mixin,需改写为新的组合式API。