跳到主要内容

内置的组合函数

Vue 3 的最新版本(截至 2026 年) 中,useAttrsuseSlotsuseModeluseTemplateRefuseId 都是 组合式 API(Composition API)函数,用于在 <script setup>setup() 函数中访问组件上下文或执行特定功能。

下面分别介绍它们的用途,并附上简洁实用的示例:


1. useAttrs()

获取传递给组件但未被 defineProps 声明的所有属性(包括 class、style、事件监听器等)。

📌 场景:透传属性到内部元素

<!-- MyButton.vue -->
<script setup lang="ts">
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

<template>
<!-- 将所有未声明的属性绑定到 button 上 -->
<button v-bind="attrs">Click me</button>
</template>

父组件使用:

<MyButton class="btn-primary" @click="handleClick" data-id="123" />

class@clickdata-id 都会透传到 <button>


2. useSlots()

获取插槽内容(slot objects),用于判断插槽是否存在或动态渲染。

📌 场景:条件渲染插槽

<!-- Card.vue -->
<script setup lang="ts">
import { useSlots } from 'vue'

const slots = useSlots()
</script>

<template>
<div class="card">
<header v-if="slots.header">
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
</div>
</template>

父组件:

<Card>
<template #header>标题</template>
内容
</Card>

3. useModel()(Vue 3.4+)

用于在组合式 API 中实现 双向绑定,是 defineModel 的底层实现。替代传统的 v-model + emit 模式。

📌 场景:自定义输入组件支持 v-model

<!-- CustomInput.vue -->
<script setup lang="ts">
import { useModel } from 'vue'

// 绑定 v-model 的值(默认 prop 名为 modelValue)
const model = useModel('modelValue')

// 也可指定 prop 名和事件名
// const foo = useModel('foo', { set: (val) => val.trim() })
</script>

<template>
<input
:value="model"
@input="model = ($event.target as HTMLInputElement).value"
/>
</template>

父组件:

<CustomInput v-model="message" />

✅ 优势:无需手动写 defineEmitsdefineProps,自动同步。


4. useTemplateRef()(Vue 3.5+)

<script setup> 中安全地引用模板中的 DOM 元素或子组件实例,替代 ref() + onMounted 的繁琐写法。

📌 场景:聚焦输入框

<script setup lang="ts">
import { useTemplateRef, onMounted } from 'vue'

const inputRef = useTemplateRef<HTMLInputElement>('inputEl')

onMounted(() => {
inputRef.value?.focus()
})
</script>

<template>
<input ref="inputEl" placeholder="Auto focus" />
</template>

⚠️ 注意:useTemplateRef 接收的是 ref 属性的字符串名(如 'inputEl'),返回响应式引用。


5. useId()(Vue 3.5+)

生成 唯一 ID,适用于无障碍(a11y)场景,如 label for="id"input id="id" 配对。

📌 场景:无障碍表单控件

<!-- LabeledInput.vue -->
<script setup lang="ts">
import { useId } from 'vue'

const id = useId() // 每个组件实例有唯一 ID
</script>

<template>
<div>
<label :for="id">用户名</label>
<input :id="id" type="text" />
</div>
</template>

✅ 解决多个相同组件实例时 ID 冲突问题。


总结对比

函数用途Vue 版本要求
useAttrs()获取未声明的属性≥3.0
useSlots()访问插槽内容≥3.0
useModel()双向绑定(替代 emit)≥3.4
useTemplateRef()安全引用模板 ref≥3.5
useId()生成唯一 ID(a11y)≥3.5

这些 API 极大提升了 Vue 3 组件的 灵活性、可维护性与无障碍支持。建议在新项目中优先使用。