Vue3 新特性总览

628 阅读3分钟

1、Vue3新特性总览

  • 性能

  • Tree-shaking 支持

  • Composition API

  • Fragment、Teleport、Suspense

  • 更好的 TS 支持

  • 自定义渲染API

2、Vue3关于性能方面的优化

  • 引入 tree-shaking 的技术,减少打包体积。

  • 数据劫持优化,使用Proxy代替defineProperty实现数据响应式。

  • renderTriggered生命周期。

  • 输出代码将更易于针对 JavaScript 编译器进行优化。

  • 输出代码通常会更好地进行优化。

  • 由于改进了补丁算法,将避免不必要的 parent/children 重新渲染。

3、Tree-shaking支持

tree shaking是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。

在Vue3中如果想全局的Tree-shakable,尽可能多的通过命名的方式导出API。基本示例如下。

import { nextTick, observable } from 'vue'
nextTick(() => {})
const obj = observable({})

****4、composition API

使用composition API的是为了:

  • 更好的Typescript支持。

  • 在复杂功能组件中可以实现根据特性组织代码 - 代码内聚性。

  • 组件间代码复用。

1、setup

setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。

  • 调用时机

    创建组件实例,然后初始化 props ,紧接着就调用setup 函数。从生命周期钩子的视角来看,它会在 beforeCreate 钩子之前被调用。

  • 模板中使用

    如果 setup 返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文:

    {{ count }} {{ object.foo }}

setup接受两个参数:

一个是props - 属性 (响应式对象 且 可以监听(watch))。

一个是context 上下文对象 - 用于代替以前的this方法可以访问的属性。

setup (props,context) {  
	const {attrs,slots,parent,root,emit} = context
	}

2、ref

对基本数据类型数据进行装箱操作使得成为一个响应式对象,可以跟踪数据变化。

const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1

3、reactive

  • 作用: 定义多个数据的响应式。

  • const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象。

  • 响应式转换是“深层的”:会影响对象内部所有嵌套的属性。

  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的。

    import { reactive, watchEffect } from 'vue' const state = reactive({ count: 0 }) watchEffect(() => { document.body.innerHTML = count is ${state.count} })

****4、Fragment、Teleport、Suspense

1、Fragment

在Vue3中,允许使用多个根节点组件,即(Fragment)片段。

在Vue2.x中,组件内是不允许多根组件,因此很多组件都是包裹在`div`标签中的,例如这样:

<!-- Layout.vue -->
<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

但是在3.x中,组件现在可以具有多个根节点!

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

2、Teleport

类似React中的Portal, 可以将特定的html模板传送到Dom的任何位置。

  • <teleport>向Vue核心添加组件。

  • 该组件需要一个目标元素,该元素是通过需要一个HTMLElementquerySelector字符串的prop提供的。

  • 组件将其子代移动到DOM选择器标识的元素。

  • 在虚拟DOM级别,子级仍然是子代的后代<teleport>,因此他们可以访问其祖先的注入。

    Move the #content with the portal component

    this will be moved to #endofbody.
    Pretend that it's a modal

这将导致以下行为:

  1. <teleport>-在此示例中:<div id="content"><Child />-的所有子项都将附加到<div id="endofbody">。

  2. <Child>作为这些子项之一的组件将保留<teleport>为父项的子项。

3、suspense

它们允许我们的应用程序在等待异步组件时渲染一些后备内容,可以让我们创建一个平滑的用户体验。

<template>
  <div>
    <div v-if="error">Uh oh .. {{ error }}</div>
    <Suspense>
      <template #default>
        <div>
          <Event />
          <AsyncEvent />
        </div>
      </template>
      <template #fallback> Loading.... </template>
    </Suspense>
  </div>
</template>
<script>
import { ref, onErrorCaptured, defineAsyncComponent } from "vue";
import Event from "./Event.vue";
const AsyncEvent = defineAsyncComponent(() => import("./Event.vue"));
export default {
  components: {
    Event,
    AsyncEvent,
  },
  setup() {
    const error = ref(null);
    onErrorCaptured((e) => {
      error.value = e;
      // 阻止错误继续冒泡
      return true;
    });
    return { error };
  },
};
</script>

除此之外还有一些新的特性,大家可以参考:

github.com/vuejs/rfcs/…