Vuetify 组件尺寸与密度(Size Density)完全指南
Vuetify 组件尺寸与密度Size Density完全指南【免费下载链接】vuetify Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetify本文基于 Vuetify 官方文档《Density and sizing》展开系统讲解size与density两个核心布局属性的取值语义、适用组件、底层实现原理与组合使用技巧。读完本文你将掌握如何用size精确控制组件的宽高与字号、用density压缩垂直内边距以适配密集型界面如工具栏、数据表格并能结合源码理解这两个属性在 Vuetify 内部是如何生成 CSS 类与样式变量的。原文档与配套可运行示例位于 density-and-sizing.md。Size控制组件的宽、高与字号size属性用于增大或缩小组件整体占用的宽度和高度同时会影响font-size字号。它通常应用于按钮、Chip、图标、头像、评分等具有明显尺寸比例的组件。支持的取值size提供了一套五档的预定义标尺x-small特小small小default默认large大x-large特大从源码看这套预定义值定义在 size.ts 中const predefinedSizes [x-small, small, default, large, x-large]自定义数值尺寸值得注意的一点是size的 prop 类型是String | Number默认值为default。也就是说除了使用上述五档预设值你还可以直接传入任意数字或长度字符串将其作为组件的像素宽高v-avatar :size64/v-avatar v-avatar size6rem/v-avatar对应 size.ts 的实现逻辑if (includes(predefinedSizes, size)) { sizeClasses ${name}--size-${size} } else if (size) { sizeStyles { width: convertToUnit(size), height: convertToUnit(size), } }即命中预设值时输出形如v-btn--size-large的类名传入自定义值时则通过convertToUnit转换为 CSS 单位直接以内联样式width/height作用于组件。实操示例官方示例 size.vue 通过一个v-btn-toggle在五档尺寸间切换并同步应用到按钮、Chip、评分与头像上v-btn :sizesize classme-2 mb-2 textExport /v-btn v-chip :sizesize classme-2 mb-2 textCompleted /v-chip v-rating :sizesize labelCustomer Satisfaction length3 /v-rating v-avatar :sizesize classmb-2 me-2 imagehttps://cdn.vuetifyjs.com/docs/images/avatars/dark.png /v-avatar其中size为绑定在切换按钮上的响应式变量默认defaultconst size shallowRef(default)Density压缩垂直空间density属性用于减少组件的垂直内边距vertical padding部分组件还会同步缩小字号。对于方形或圆形组件如图标它同时会减少水平内边距。这是让密集列表、表格、工具栏等高信息量界面更紧凑的主要手段。支持的取值density提供三档密度default默认comfortable舒适compact紧凑对应的类型定义与校验逻辑位于 density.tsconst allowedDensities [null, default, comfortable, compact] as const export type Density null | default | comfortable | compact export const makeDensityProps propsFactory({ density: { type: String as PropTypeDensity, default: default, validator: (v: any) allowedDensities.includes(v), }, }, density)可以看到Vuetify 对传入值做了白名单校验validator不合法的取值会被框架拒绝。类名生成机制useDensity组合式函数会基于组件实例名与当前密度值生成一个响应式类名export function useDensity (props: DensityProps, name getCurrentInstanceName()) { const densityClasses toRef(() { return ${name}--density-${props.density} }) return { densityClasses } }因此一个v-btn在densitycompact时会得到v-btn--density-compact类Sass 样式据此调整内边距与高度。实操示例官方示例 density.vue 演示了密度对按钮、Chip、工具栏与文本输入框的影响v-btn :densitydensity classme-2 mb-2 textSubmit /v-btn v-chip :densitydensity classme-2 mb-2 textIn Progress /v-chip v-toolbar :densitydensity classmb-2 elevation1 titleDaily Reports /v-toolbar v-text-field :densitydensity labelSearch Query model-valueData tables prepend-inner-iconmdi-magnify variantsolo /v-text-field组合使用Size × Densitysize与density是两个正交的属性size决定整体尺度宽、高、字号density决定内部留白密度。二者可以自由组合一次性调整组件的整体观感例如「大尺寸 紧凑密度」可以在保持醒目字号的同时尽量减少占用的垂直空间。官方示例 density-and-size.vue 使用两个滑块分别驱动size与density并同时应用到按钮、Chip 与头像上v-btn :densitydensities[density] :sizesizes[size] classme-2 mb-2 prepend-icon$vuetify textDefault Button /v-btn对应脚本中的取值映射const size shallowRef(2) const density shallowRef(2) const densities [compact, comfortable, default] const sizes [x-small, small, default, large, x-large]这种「双滑块 组件实时预览」的模式非常适合在设计阶段快速比对不同组合的视觉密度。底层原理Sass 混入如何计算尺寸与密度从源码层面看size与density的最终效果由各组件自身的 Sass 混入mixin实现。以按钮为例VBtn/_mixins.scss 中mixin button-sizes ($map: $button-sizes, $immediate: false) { each $sizeName, $multiplier in settings.$size-scales { $size: map.get($map, font-size) math.div(2 * $multiplier, 16); $height: map.get($map, height) (settings.$size-scale * $multiplier); $selector: .v-btn--size-#{$sizeName}; #{$selector} { --v-btn-size: #{$size}; --v-btn-height: #{$height}; font-size: var(--v-btn-size); min-width: tools.roundEven($height * map.get($map, width-ratio)); padding: 0 tools.roundEven(math.div($height, map.get($map, padding-ratio))); } } }可以看到每一档size都会依据全局尺寸标尺settings.$size-scales、settings.$size-scale计算并暴露--v-btn-size、--v-btn-height两个 CSS 变量再派生font-size、min-width与水平padding。密度部分则基于高度变量做增量计算mixin button-density ($properties, $densities) { each $density, $multiplier in $densities { $value: calc(var(--v-btn-height) #{$multiplier * settings.$spacer}); .v-btn--density-#{$density} { // 将 $value 应用到 height / padding 等属性 } } }即density通过「基础高度 密度增量 × 全局 spacer」的公式得到最终高度与内边距compact对应负增量default为零增量comfortable为正增量。同样的模式也出现在 Chip见 VChip/_mixins.scss等组件中只是各自维护一套$size-scales与$densities映射。注意事项并非所有组件都有高度过渡动画官方文档明确提示——当动态切换density时不是所有组件都带有默认的「高度变化过渡」动画。这意味着在运行时切换密度可能出现高度瞬间跳变若需要平滑动画应自行添加transition样式。density的覆盖范围density主要作用于内边距与字号不改变组件的整体宽度与字体排版的水平尺度comfortable与compact之间的差异通常为几个像素的垂直留白请根据界面信息密度按需选用。自定义size的局限传入数值/长度字符串时size以等宽等高正方形方式生成内联样式适用于头像、图标、评分等方形组件对按钮等需要保持宽高比例的组件建议使用五档预设值。相关组件与继续探索size与density被大量组件以组合式函数方式复用。通过makeDensityProps/makeSizeProps的引用关系见 composables 与 size.ts可以看到支持这两个属性的组件包括但不限于VBtn、VChip、VAvatar、VRating、VTabs、VTable、VList、VInput/VTextField、VToolbar、VAlert、VCard、VPagination、VTimeline、VTreeview等具体组件实现分布在 packages/vuetify/src/components 下各自的*.tsx文件中。如果需要为某个具体组件查看可用的密度档位与尺寸标尺可直接阅读该组件目录下的_mixins.scss与variables.scss例如按钮的样式入口为 VBtn.sass。官方文档中与本节主题强相关的组件还包括按钮、Chip、列表等可在文档导航的对应组件页中找到更多组合示例。【免费下载链接】vuetify Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考