Skip to content

Vue 3 API 指南

本文档按照 API 重要程度由高到低排序,详细介绍 Vue 3 中的核心 API,包括其作用、区别和使用场景。

一、核心 Composition API

1. setup()

作用:Composition API 的入口函数,用于在组件中使用 Composition API。

使用场景

  • 替代 Options API 中的 data、methods、computed 等选项
  • 组织相关逻辑代码,提高代码可读性和可维护性
  • 实现逻辑复用

示例

vue
<template>
  <div>{{ count }}</div>
  <button @click="increment">Increment</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const increment = () => {
      count.value++
    }
    return { count, increment }
  }
}
</script>

2. ref()

作用:创建响应式的引用类型数据。

区别

  • 与 reactive() 相比,ref() 可以处理基本类型数据
  • ref() 创建的数据需要通过 .value 访问和修改
  • 在模板中使用时,Vue 会自动解包,无需 .value

使用场景

  • 管理基本类型的响应式数据
  • 在组合函数中返回响应式数据
  • 作为 props 或 emits 的默认值

示例

javascript
import { ref } from 'vue'

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

3. reactive()

作用:创建响应式的对象类型数据。

区别

  • 只能处理对象类型数据
  • 直接访问和修改属性,无需 .value
  • 解构后会失去响应性

使用场景

  • 管理复杂的对象类型数据
  • 当需要同时响应多个相关属性时

示例

javascript
import { reactive } from 'vue'

const state = reactive({
  count: 0,
  name: 'Vue 3'
})

console.log(state.count) // 0
state.count++
console.log(state.count) // 1

4. computed()

作用:创建计算属性,根据依赖自动缓存结果。

使用场景

  • 基于响应式数据计算派生值
  • 避免在模板中进行复杂计算
  • 提高性能,避免重复计算

示例

javascript
import { ref, computed } from 'vue'

const count = ref(0)
const doubleCount = computed(() => count.value * 2)

console.log(doubleCount.value) // 0
count.value++
console.log(doubleCount.value) // 2

5. watch()

作用:监听响应式数据的变化并执行副作用。

区别

  • 与 watchEffect() 相比,watch() 可以:
    • 明确指定要监听的数据源
    • 获取变化前后的值
    • 控制触发时机(immediate、deep)

使用场景

  • 当需要在数据变化时执行异步操作
  • 当需要基于变化前后的值进行逻辑处理
  • 当需要深度监听对象或数组的变化

示例

javascript
import { ref, watch } from 'vue'

const count = ref(0)

watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`)
})

count.value++ // 输出: Count changed from 0 to 1

6. watchEffect()

作用:自动追踪响应式依赖并执行副作用。

区别

  • 与 watch() 相比,watchEffect() 会:
    • 自动追踪所有依赖
    • 立即执行一次
    • 无法获取变化前后的值

使用场景

  • 当需要根据多个响应式数据的变化执行副作用
  • 当副作用的依赖关系比较复杂
  • 当不需要获取变化前后的值

示例

javascript
import { ref, watchEffect } from 'vue'

const count = ref(0)
const name = ref('Vue')

watchEffect(() => {
  console.log(`Count: ${count.value}, Name: ${name.value}`)
})

count.value++ // 输出: Count: 1, Name: Vue
name.value = 'Vue 3' // 输出: Count: 1, Name: Vue 3

7. onMounted() / onUpdated() / onUnmounted()

作用:生命周期钩子函数,用于在组件不同阶段执行逻辑。

使用场景

  • onMounted:组件挂载后执行,如初始化数据、绑定事件等
  • onUpdated:组件更新后执行,如 DOM 操作、第三方库更新等
  • onUnmounted:组件卸载前执行,如清理定时器、取消事件监听等

示例

javascript
import { onMounted, onUnmounted } from 'vue'

export default {
  setup() {
    let timer

    onMounted(() => {
      timer = setInterval(() => {
        console.log('Tick')
      }, 1000)
    })

    onUnmounted(() => {
      clearInterval(timer)
    })
  }
}

二、响应式系统 API

1. readonly()

作用:创建只读的响应式对象。

使用场景

  • 保护数据不被修改
  • 传递数据给子组件时防止意外修改
  • 实现不可变数据模式

示例

javascript
import { reactive, readonly } from 'vue'

const state = reactive({ count: 0 })
const readOnlyState = readonly(state)

readOnlyState.count++ // 警告:无法修改只读对象

2. shallowRef() / shallowReactive()

作用:创建浅响应式数据,只响应顶层属性的变化。

使用场景

  • 当不需要深度响应式时,提高性能
  • 当处理大型对象或数组时
  • 当对象的深层结构不需要响应式时

示例

javascript
import { shallowRef, shallowReactive } from 'vue'

const shallowObj = shallowReactive({
  deep: { nested: 1 }
})

shallowObj.deep.nested = 2 // 不会触发响应式更新

3. toRef() / toRefs()

作用:将响应式对象的属性转换为 ref。

使用场景

  • 当需要解构响应式对象的属性时保持响应性
  • 当需要将对象属性作为 ref 传递给其他函数时

示例

javascript
import { reactive, toRef, toRefs } from 'vue'

const state = reactive({ count: 0, name: 'Vue' })

const countRef = toRef(state, 'count')
const { name } = toRefs(state)

countRef.value++ // 会触发响应式更新
name.value = 'Vue 3' // 会触发响应式更新

4. isRef() / isReactive() / isReadonly()

作用:判断数据的响应式类型。

使用场景

  • 在组合函数中检查参数类型
  • 实现通用逻辑时进行类型判断
  • 调试时检查响应式状态

示例

javascript
import { ref, reactive, readonly, isRef, isReactive, isReadonly } from 'vue'

const count = ref(0)
const state = reactive({ count: 0 })
const readOnlyState = readonly(state)

console.log(isRef(count)) // true
console.log(isReactive(state)) // true
console.log(isReadonly(readOnlyState)) // true

三、组件 API

1. defineComponent()

作用:定义 Vue 组件,提供类型推导支持。

使用场景

  • 在 TypeScript 项目中定义组件
  • 获得更好的类型提示和代码补全

示例

typescript
import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    message: String
  },
  setup(props) {
    return {
      // 这里可以获得 props 的类型提示
    }
  }
})

2. defineProps() / defineEmits()

作用:在 <script setup> 中定义组件的 props 和 emits。

使用场景

  • <script setup> 语法中使用
  • 获得更好的类型推导
  • 简化组件定义

示例

vue
<script setup>
import { defineProps, defineEmits } from 'vue'

const props = defineProps({
  message: String
})

const emit = defineEmits(['update:message'])

function updateMessage(newMessage) {
  emit('update:message', newMessage)
}
</script>

3. useSlots() / useAttrs()

作用:在 Composition API 中访问组件的 slots 和 attrs。

使用场景

  • 当需要在 setup() 中操作 slots 时
  • 当需要在 setup() 中访问非 props 的属性时

示例

javascript
import { useSlots, useAttrs } from 'vue'

export default {
  setup() {
    const slots = useSlots()
    const attrs = useAttrs()

    console.log(slots.default)
    console.log(attrs.class)

    return {}
  }
}

四、工具 API

1. nextTick()

作用:在下次 DOM 更新后执行回调函数。

使用场景

  • 当需要在 DOM 更新后操作元素
  • 当需要获取更新后的 DOM 状态
  • 当需要在数据变化后执行 DOM 相关的操作

示例

javascript
import { ref, nextTick } from 'vue'

const count = ref(0)

async function increment() {
  count.value++
  // DOM 还未更新
  await nextTick()
  // DOM 已更新,可以操作元素
  console.log(document.getElementById('count').textContent)
}

2. provide() / inject()

作用:实现组件间的依赖注入。

使用场景

  • 当需要在组件树中传递数据,而不想通过 props 逐层传递
  • 当需要在深层嵌套的组件中共享状态
  • 当需要实现插件或库的功能

示例

javascript
// 父组件
import { provide } from 'vue'

export default {
  setup() {
    provide('theme', 'dark')
  }
}

// 子组件
import { inject } from 'vue'

export default {
  setup() {
    const theme = inject('theme', 'light') // 第二个参数是默认值
    return { theme }
  }
}

3. h()

作用:创建 VNode(虚拟 DOM 节点)。

使用场景

  • 当需要动态创建组件时
  • 当需要在渲染函数中使用
  • 当需要实现高阶组件时

示例

javascript
import { h } from 'vue'

// 创建一个 div 元素
const vnode = h('div', { class: 'container' }, [
  h('h1', 'Hello Vue 3'),
  h('p', 'Welcome to the Vue 3 world')
])

4. resolveComponent() / resolveDirective()

作用:解析组件或指令。

使用场景

  • 在渲染函数中动态使用组件
  • 在运行时解析组件名称

示例

javascript
import { h, resolveComponent } from 'vue'

export default {
  setup() {
    const MyComponent = resolveComponent('MyComponent')
    return () => h(MyComponent)
  }
}

五、其他 API

1. markRaw()

作用:标记一个对象,使其永远不会被转换为响应式对象。

使用场景

  • 当需要处理大型第三方库对象时
  • 当需要提高性能,避免不必要的响应式转换
  • 当对象不需要响应式时

示例

javascript
import { markRaw, reactive } from 'vue'

const rawObj = { count: 0 }
const markedObj = markRaw(rawObj)
const reactiveObj = reactive(markedObj)

console.log(reactiveObj === markedObj) // true,说明没有被转换为响应式

2. customRef()

作用:创建自定义的 ref 类型。

使用场景

  • 当需要自定义响应式行为时
  • 当需要实现防抖或节流等功能时
  • 当需要控制依赖追踪和触发更新的时机时

示例

javascript
import { customRef } from 'vue'

function useDebouncedRef(value, delay = 300) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}

// 使用
const searchQuery = useDebouncedRef('')

3. effectScope()

作用:创建一个 effect 作用域,可以手动控制其中的响应式副作用的生命周期。

使用场景

  • 当需要在组件之外使用响应式系统时
  • 当需要手动管理响应式副作用的清理
  • 当需要创建可复用的响应式逻辑时

示例

javascript
import { effectScope, ref, watch } from 'vue'

const scope = effectScope()

scope.run(() => {
  const count = ref(0)

  watch(count, newValue => {
    console.log(`Count: ${newValue}`)
  })

  count.value++ // 输出: Count: 1
})

// 清理所有副作用
scope.stop()

// 之后的修改不会触发 watch
count.value++ // 不会输出

总结

Vue 3 的 API 设计更加灵活和强大,特别是 Composition API 的引入,使得代码组织更加清晰,逻辑复用更加方便。根据不同的使用场景,选择合适的 API 可以提高开发效率和代码质量。

重要程度排序

  1. 核心 Composition API:setup(), ref(), reactive(), computed(), watch(), watchEffect(), 生命周期钩子
  2. 响应式系统 API:readonly(), shallowRef(), shallowReactive(), toRef(), toRefs(), 响应式判断函数
  3. 组件 API:defineComponent(), defineProps(), defineEmits(), useSlots(), useAttrs()
  4. 工具 API:nextTick(), provide(), inject(), h()
  5. 其他 API:markRaw(), customRef(), effectScope()

通过合理使用这些 API,可以构建出更加健壮、可维护的 Vue 3 应用。

基于 VitePress 的本地知识库