Vue 3 <script setup> 语法糖 中的一行解构赋值,用来从父组件透传下来的属性(attrs)中取值并设置默认值。
一、代码整体含义
js
const {
sliceNum = 1,
gutter = 100
} = useAttrs()
✅ 含义一句话版:
从父组件传给当前组件的 非 props 属性(attrs) 中,
取出
sliceNum和gutter;如果没传,就分别使用默认值
1和100。
二、useAttrs() 是什么?
✅ 定义
useAttrs() 是 Vue 3 Composition API 提供的一个函数。
js
import { useAttrs } from 'vue'
✅ 作用
- 获取父组件传递给当前组件的所有 attribute
- 包括:
- HTML 原生属性(
class,style,id) - 自定义属性(
slice-num,gutter)
- HTML 原生属性(
- 不包括 :
- 已经在
defineProps()中声明的 props
- 已经在
三、attrs 的结构示例
父组件
vue
<Child
slice-num="3"
gutter="20"
class="box"
/>
子组件中
js
const attrs = useAttrs()
console.log(attrs)
/*
{
sliceNum: "3",
gutter: "20",
class: "box"
}
*/
⚠️ 注意:
attrs 中的值永远是字符串
四、你这段代码发生了什么?
js
const {
sliceNum = 1,
gutter = 100
} = useAttrs()
等价于:
js
const attrs = useAttrs()
const sliceNum = attrs.sliceNum !== undefined
? Number(attrs.sliceNum)
: 1
const gutter = attrs.gutter !== undefined
? Number(attrs.gutter)
: 100
五、⚠️ 一个非常重要的坑(你一定要注意)
❌ 问题:attrs 的值是字符串
vue
<MyComp slice-num="3" gutter="20" />
js
sliceNum === "3" // 字符串
gutter === "20" // 字符串
如果你直接拿去做计算:
js
sliceNum * 2 // "32"(字符串拼接!)
六、✅ 正确写法(强烈推荐)
✅ 显式转换成数字
js
const attrs = useAttrs()
const sliceNum = Number(attrs.sliceNum ?? 1)
const gutter = Number(attrs.gutter ?? 100)
或:
js
const sliceNum = attrs.sliceNum ? Number(attrs.sliceNum) : 1
const gutter = attrs.gutter ? Number(attrs.gutter) : 100
七、什么时候用 useAttrs()?
✅ 适合用 attrs 的场景
| 场景 | 示例 |
|---|---|
| 透传 HTML 属性 | class, style, id |
| 包装 UI 组件 | 二次封装 Element Plus 组件 |
| 不想声明 props | 简单透传属性 |
❌ 不适合用 attrs 的场景
| 场景 | 正确做法 |
|---|---|
| 需要类型校验 | defineProps() |
| 需要默认值 | defineProps() |
| 需要响应式 | defineProps() |
八、✅ 更推荐的 Vue 3 写法(最佳实践)
✅ 用 defineProps(强烈推荐)
js
const props = defineProps({
sliceNum: {
type: Number,
default: 1
},
gutter: {
type: Number,
default: 100
}
})
✅ 优点:
- 自动类型转换
- 有类型提示
- 更安全
- 更符合 Vue 规范
九、对比总结
| 写法 | 是否推荐 | 说明 |
|---|---|---|
useAttrs() + 解构 |
⚠️ 可用 | 适合透传,需手动转换 |
defineProps() |
✅✅✅ | Vue 官方推荐 |
| 直接使用 attrs | ❌ | 不安全 |
十、一句话总结
✅ 这行代码是从 attrs 中取
sliceNum和gutter,并设置默认值⚠️ attrs 的值永远是字符串,必须手动转数字
✅ 如果是组件业务属性,优先用
defineProps()