Skip to content

全局Api

version

暴露当前所使用的 Vue 版本。

类型 string

示例

js
import { version } from 'vue'

console.log(version)

nextTick()

等待下一次 DOM 更新刷新的工具方法。

类型

ts
function nextTick(callback?: () => void): Promise<void>

详细信息

当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。

nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。

示例

vue
<script setup>
import { ref, nextTick } from 'vue'

const count = ref(0)

async function increment() {
  count.value++

  // DOM 还未更新
  console.log(document.getElementById('counter').textContent) // 0

  await nextTick()
  // DOM 此时已经更新
  console.log(document.getElementById('counter').textContent) // 1
}
</script>

<template>
  <button id="counter" @click="increment">{{ count }}</button>
</template>

defineComponent()

在定义 Vue 组件时提供类型推导的辅助函数。

类型

ts
// 选项语法
function defineComponent(
  component: ComponentOptions
): ComponentConstructor

// 函数语法 (需要 3.3+)
function defineComponent(
  setup: ComponentOptions['setup'],
  extraOptions?: ComponentOptions
): () => any

为了便于阅读,对类型进行了简化。

详细信息

第一个参数是一个组件选项对象。返回值将是该选项对象本身,因为该函数实际上在运行时没有任何操作,仅用于提供类型推导。

注意返回值的类型有一点特别:它会是一个构造函数类型,它的实例类型是根据选项推断出的组件实例类型。这是为了能让该返回值在 TSX 中用作标签时提供类型推导支持。

你可以像这样从 defineComponent() 的返回类型中提取出一个组件的实例类型 (与其选项中的 this 的类型等价):

ts

ts
const Foo = defineComponent(/* ... */)

type FooInstance = InstanceType<typeof Foo>

函数签名

  • 仅在 3.3+ 中支持

defineComponent() 还有一种备用签名,旨在与组合式 API 和渲染函数或 JSX 一起使用。

与传递选项对象不同的是,它需要传入一个函数。这个函数的工作方式与组合式 API 的 setup() 函数相同:它接收 props 和 setup 上下文。返回值应该是一个渲染函数——支持 h() 和 JSX:

js
import { ref, h } from 'vue'

const Comp = defineComponent(
  (props) => {
    // 就像在 <script setup> 中一样使用组合式 API
    const count = ref(0)

    return () => {
      // 渲染函数或 JSX
      return h('div', count.value)
    }
  },
  // 其他选项,例如声明 props 和 emits。
  {
    props: {
      /* ... */
    }
  }
)

此签名的主要用例是使用 TypeScript (特别是使用 TSX),因为它支持泛型:

tsx
const Comp = defineComponent(
  <T extends string | number>(props: { msg: T; list: T[] }) => {
    // 就像在 <script setup> 中一样使用组合式 API
    const count = ref(0)

    return () => {
      // 渲染函数或 JSX
      return <div>{count.value}</div>
    }
  },
  // 目前仍然需要手动声明运行时的 props
  {
    props: ['msg', 'list']
  }
)

在将来,我们计划提供一个 Babel 插件,自动推断并注入运行时 props (就像在单文件组件中的 defineProps 一样),以便省略运行时 props 的声明。

webpack Treeshaking 的注意事项

因为 defineComponent() 是一个函数调用,所以它可能被某些构建工具认为会产生副作用,如 webpack。即使一个组件从未被使用,也有可能不被 tree-shake。

为了告诉 webpack 这个函数调用可以被安全地 tree-shake,我们可以在函数调用之前添加一个 /*#__PURE__*/ 形式的注释:

js
export default /*#__PURE__*/ defineComponent(/* ... */)

请注意,如果你的项目中使用的是 Vite,就不需要这么做,因为 Rollup (Vite 底层使用的生产环境打包工具) 可以智能地确定 defineComponent() 实际上并没有副作用,所以无需手动注释。

参考指南 - 配合 TypeScript 使用 Vue

defineAsyncComponent()

定义一个异步组件,它在运行时是懒加载的。参数可以是一个异步加载函数,或是对加载行为进行更具体定制的一个选项对象。

类型

ts
function defineAsyncComponent(
  source: AsyncComponentLoader | AsyncComponentOptions
): Component

type AsyncComponentLoader = () => Promise<Component>

interface AsyncComponentOptions {
  loader: AsyncComponentLoader
  loadingComponent?: Component
  errorComponent?: Component
  delay?: number
  timeout?: number
  suspensible?: boolean
  onError?: (
    error: Error,
    retry: () => void,
    fail: () => void,
    attempts: number
  ) => any
}

参考指南 - 异步组件

MIT Licensed