ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vuetify 3 v-chip-group 组件完全指南:选择型 Chip 分组的实现原理与实战

Vuetify 3 v-chip-group 组件完全指南:选择型 Chip 分组的实现原理与实战 Vuetify 3 v-chip-group 组件完全指南选择型 Chip 分组的实现原理与实战【免费下载链接】vuetify Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetifyv-chip-group是 Vuetify 3 中用于将多个v-chip组合为单选 / 多选分组的容器组件它把v-chip的展示能力与v-item-group式的分组选择状态管理结合在一起常用于筛选面板、分类选择、商品规格尺码/颜色等场景。本文以官方文档 chip-groups.md 为骨架结合仓库内VChipGroup源码与全部官方示例讲解其基础用法、核心 Props、实战案例以及底层的分组状态实现原理读完即可在实际项目中熟练使用并自行定制样式。v-chip-group 是什么v-chip-groupChip group 组件为v-chip组件提供了分组groupable能力用于创建使用 Chip 进行选项选择的交互分组。正如官方文档所述它supercharges thev-chipcomponent by providing groupable functionality即让原本只是展示性标签的 Chip 具备可选中、可关联v-model的选项语义。典型应用场景包括复杂列表 / 数据集的筛选条件选择例如筛选结果、房价区间、设施清单商品详情页的规格选择尺码、颜色、材质分类订阅、主题选择等单项或多项选择界面。默认情况下v-chip-group内的 Chip 超出容器宽度时向右横向溢出并支持滑动浏览也可以通过column属性切换为纯纵向换行column only模式。在组件体系上v-chip-group与 chips 组件文档、slide-groups 组件文档、item-groups 组件文档 关系密切它继承自VSlideGroup滑动容器能力同时内部复用VItemGroup同源的useGroup分组状态组合式函数。基础用法Usage最简单的用法是把若干v-chip直接放进v-chip-grouptemplate div v-chip-group v-chipChip 1/v-chip v-chipChip 2/v-chip v-chipChip 3/v-chip /v-chip-group /div /template官方示例 usage.vue 还演示了filter属性对分组外观的影响给v-chip-group加上filter后选中的 Chip 会以选中即显示对勾图标的替代视觉风格呈现向用户明确传达已选中状态。这个基础用法非常适合为更复杂的功能提供筛选选项入口。提示Chip 在分组内默认未指定value时使用其在组内的索引index作为值指定了value则使用该值详见后文Product card一节与源码解析部分。API 一览v-chip-group是 Chip group 场景下的主组件其完整 API包含所有 Props、Slots、事件由仓库的 api-generator 依据源码自动生成见 api-generator 的生成逻辑。以下是其核心 Props 概览均来自源码 VChipGroup.tsx 中的makeVChipGroupProps定义| Prop | 类型 | 默认值 | 说明 | | - | - | - | - | |modelValue|unknown|undefined| 当前选中的值支持v-model双向绑定 | |multiple|boolean|false| 是否允许多选 | |mandatory|boolean \| force|false| 是否必须始终有一个值被选中force会在挂载时强制选中第一个可用项 | |max|number|undefined| 多选时允许选中的最大数量 | |column|boolean|false| 是否切换为纵向换行模式column only | |filter|boolean|false| 选中项是否显示过滤对勾图标 | |baseColor|string|undefined| 未选中 Chip 的基础颜色 | |selectedClass|string|v-chip--selected| 选中项的附加 class | |valueComparator|Function|deepEqual| 判断值是否相等的比较函数 | |variant|string|tonal| 应用到内部 Chip 的变体样式 | |disabled|boolean|false| 禁用整个分组 | |direction、nextIcon、prevIcon、showArrows、scrollToActive等 | — | — | 继承自VSlideGroup的滑动控制属性其中scrollToActive默认被设为false |事件方面组件声明了update:modelValueVChipGroup.tsx与v-model配合完成双向绑定。默认插槽还会向下暴露isSelected、select、next、prev、selected等分组操作见同文件 VChipGroup.tsx可用于自定义内容插槽。核心 Props 实战Column让 Chip 换行排列默认的v-chip-group是单行横向滑动内容多时会向右溢出。加上column属性后分组内的 Chip 会自动换行wrap形成多行布局适用于标签云、话题列表等需要完整展示所有选项的场景template v-sheet classmx-auto elevation3 max-width300 roundedxl v-sheet classpa-3 bg-primary text-right roundedt-xl v-btn iconmdi-content-save-cog-outline/v-btn v-btn classms-2 iconmdi-check-bold/v-btn /v-sheet div classpa-4 v-chip-group selected-classtext-primary column v-chip v-fortag in tags :keytag{{ tag }}/v-chip /v-chip-group /div /v-sheet /template script setup const tags [ Work, Home Improvement, Vacation, Food, Drawers, Shopping, Art, Tech, Creative Writing, ] /script完整示例见 prop-column.vue。示例同时演示了selected-class的用法选中项会追加text-primary类使选中标签以主题色高亮。从样式源码 VChipGroup.sass 可以看到 column 模式的实现本质.v-chip-group--column .v-slide-group__content white-space: normal flex-wrap: wrap max-width: 100%即通过把滑动内容容器改为flex-wrap: wrap并恢复white-space: normal实现换行未开启 column 时容器使用overflow-x: autoVChipGroup.sass保持横向滚动能力。Filter为选中项增加反馈图标filter属性让选中的 Chip 呈现带对勾图标的替代视觉风格向用户传递更直观的选中反馈。下面的酒店筛选示例结合column、multiple与v-model构造了一个设施 街区的多选筛选面板template v-card classmx-auto max-width400 v-toolbar colordeep-purple-accent-4 v-btn iconmdi-close/v-btn v-toolbar-titleFilter results/v-toolbar-title /v-toolbar v-card-text h2 classtext-title-large mt-0 mb-2Choose amenities/h2 v-chip-group v-modelamenities column multiple v-chip textElevator variantoutlined filter/v-chip v-chip textWasher / Dryer variantoutlined filter/v-chip v-chip textFireplace variantoutlined filter/v-chip !-- ... -- /v-chip-group /v-card-text v-card-text h2 classtext-title-large mt-0 mb-2Choose neighborhoods/h2 v-chip-group v-modelneighborhoods column multiple v-chip textSnowy Rock Place variantoutlined filter/v-chip v-chip textHoneylane Circle variantoutlined filter/v-chip !-- ... -- /v-chip-group /v-card-text /v-card /template script setup import { shallowRef } from vue const amenities shallowRef([1, 4]) const neighborhoods shallowRef([1]) /script完整示例见 prop-filter.vue。注意这里v-model初始值使用索引[1, 4]因为 Chip 未显式指定value与源码中未提供 value 时以索引作为值的行为一致。在组件内部filter会被VChipGroup通过provideDefaults传递给每一个VChipVChipGroup.tsx而VChip端只有处于分组中且开启 filter时才渲染过滤图标源码 VChip.tsx 中的hasFilter判断与v-chip--filter类这正是filter生效的底层链路。Mandatory始终保有一个选中值mandatory属性保证分组任何时候都至少有一个值被选中用户无法取消最后一项的选择非常适合必须二选一/必选的场景template v-sheet classpy-4 px-1 v-chip-group selected-classtext-primary mandatory v-chip v-fortag in tags :keytag :texttag/v-chip /v-chip-group /v-sheet /template完整示例见 prop-mandatory.vue。底层行为可在分组状态源码 group.ts 的select方法中确认单选模式下若mandatory为真且当前项已选中会直接return拒绝取消多选模式下mandatory且当前是唯一选中项时同样拒绝移除。若传入mandatoryforce还会在组件挂载时通过forceMandatoryValue自动选中第一个未禁用的项group.ts。Multiple多选模式multiple属性允许同时选中多个 Chiptemplate v-sheet classpy-4 px-1 v-chip-group selected-classtext-primary multiple v-chip v-fortag in tags :keytag :texttag/v-chip /v-chip-group /v-sheet /template完整示例见 prop-multiple.vue。在多选状态下v-model对应的是数组。多选配合mandatory、max时select方法会依次做三类拦截group.ts若目标项已禁用且尝试选中直接忽略mandatory为真且当前是唯一选中项时禁止取消已设置max且当前选中数已达到上限时禁止继续添加。此外max与valueComparator的配合意味着如果值是比较复杂的对象你可以传入自定义比较函数来控制相同值的判定默认使用deepEqual。进阶实战MiscProduct card为 Chip 显式指定 valuev-chip可以携带一个显式value该值会被传递给外层v-chip-group作为其modelValue。当不想用 Chip 的索引作为值时这种方式非常有用。以下商品卡片用尺码分组实现选尺寸template v-card classmx-auto max-width400 v-card-title classd-flex h2 classtext-headline-large my-0Shirt Blouse/h2 v-spacer/v-spacer span classtext-title-large$44.50/span /v-card-title v-card-text Our blouses are available in 8 colors. You can custom order a built-in arch support for any of the models. /v-card-text v-divider classmx-4/v-divider v-card-text span classsubheadingSelect size/span v-chip-group v-modelselection selected-classv-chip--selected v-chip--variant-tonal text-deep-purple-accent-4 variantoutlined mandatory v-chip v-forsize in sizes :keysize :textsize :valuesize/v-chip /v-chip-group /v-card-text v-card-actions v-btn colordeep-purple-accent-4 textAdd to Cart variantflat block/v-btn /v-card-actions /v-card /template script setup import { ref } from vue const sizes [04, 06, 08, 10, 12, 14] const selection ref(08) /script完整示例见 misc-product-card.vue。这里每个尺码 Chip 的value是字符串因此v-model的初始值也使用字符串08。该行为的源码依据在 group.ts 的register方法中注册子项时如果value未定义会自动把该项的索引写入value并标记useIndexAsValue true反之则保留显式value。getIds/getValuesgroup.ts再通过deepEqual在值与内部 id之间互相转换从而让v-model既能存索引、也能存任意显式值。Toothbrush card用 Chip group 替代单选控件Chip group 允许创建与 item group 或 radio 控件功能相同但视觉风格不同的自定义界面。下面的牙刷卡片即用 Chip group 实现了单选刷毛硬度template v-card classmx-auto max-width400 v-card-title classd-flex h2 classtext-headline-large my-0Toothbrush/h2 v-spacer/v-spacer span classtext-title-large$4.99/span /v-card-title v-card-text Our company takes pride in making handmade brushes. Our toothbrushes are available in 4 different bristel types, from extra soft to hard. /v-card-text v-divider classmx-4/v-divider v-card-text span classsubheadingSelect type/span v-chip-group v-modelselection selected-classv-chip--selected v-chip--variant-flat variantoutlined mandatory v-chip textExtra Soft/v-chip v-chip textSoft/v-chip v-chip textMedium/v-chip v-chip textHard/v-chip /v-chip-group /v-card-text v-card-actions v-btn colorsecondary textAdd to Cart variantflat block/v-btn /v-card-actions /v-card /template script setup import { shallowRef } from vue const selection shallowRef(2) /script完整示例见 misc-toothbrush-card.vue。由于 Chip 没有显式valueselection初始值2对应的是第 3 个 Chip索引从 0 开始。选中的 Chip 会叠加v-chip--selected v-chip--variant-flat类呈现扁平高亮外观。Reddit style categories用工具类 emoji 打造话题选择结合 Vuetify 的工具类utility classes与 emoji可以轻松做出 Reddit 风格的分类选择器template v-sheet classmx-auto max-width400 roundedxl border div classpa-4 div classtext-title-largeWhat are you into?/div div classtext-body-largeSelect topics to continue/div v-responsive classoverflow-y-auto max-height280 v-chip-group classmt-3 column v-chip v-fortopic in topics :keytopic :texttopic :valuetopic /v-chip /v-chip-group /v-responsive /div v-divider/v-divider div classpa-2 v-btn colororange-darken-1 roundedt-0 b-xl sizex-large textContinue variantflat block /v-btn /div /v-sheet /template script setup const topics [ Advice, Animals, Anime, Art Design, Beauty, Business, Books, Damn That\s Interesting, Hobbies, Gaming, Movies, Music, TV, Food, Funny, Health Lifestyle, School, News, Nature, Photography, Sports, ] /script完整示例见 misc-reddit-categories.vue。该示例利用column换行 v-responsive限高滚动 value直接使用话题字符串展示了一种轻量的话题订阅界面。源码解析VChipGroup 是如何工作的组件组合结构从 VChipGroup.tsx 的渲染逻辑可以看到VChipGroup本质上是对VSlideGroup的一层封装它把自身筛选后的 props 透传给VSlideGroup并在其上追加v-chip-group及条件类v-chip-group--column。组件导出通过 index.ts 完成。分组状态管理useGroupVChipGroup通过useGroup(props, VChipGroupSymbol)VChipGroup.tsx建立分组上下文注入键为Symbol.for(vuetify:v-chip-group)。该组合式函数group.ts负责注册/注销子项register收集子 Chip 的 id、value、disabled并在未提供 value 时用索引兜底选中/取消select统一处理单选/多选、mandatory、max、disabled等边界逻辑前述已有详述键盘/步进导航next/prev通过step(offset)在选项间移动并自动跳过禁用项group.ts值映射getIds/getValues完成外部 modelValue ↔ 内部项 id的双向换算默认比较器deepEqual支持任意值类型。默认值传递provideDefaults在setup中VChipGroup通过provideDefaults把baseColor、color、disabled、filter、variant统一注入给内部所有VChipVChipGroup.tsx。这意味着你可以在v-chip-group上设置variant默认tonal、color等属性无需逐个 Chip 重复配置filter属性也经由这条链路生效由VChip决定何时渲染对勾图标。样式与 Sass 变量样式定义在 VChipGroup.sass 中可定制的 Sass 变量位于 _variables.scss// VChipGroup $chip-group-selected-opacity: var(--v-activated-opacity) !default; $chip-group-padding: 4px 0 !default; $chip-group-margin: 4px 8px 4px 0 !default;$chip-group-selected-opacity选中态 Chip 遮罩层的透明度默认引用主题的--v-activated-opacity源码中作用于.v-chip--selected:not(.v-chip--disabled) .v-chip__overlayVChipGroup.sass$chip-group-padding/$chip-group-margin分组容器内边距与 Chip 间距。样式还内置了forced-colors无障碍适配VChipGroup.sass在高对比度模式下自动调整选中态颜色保证可访问性。小结v-chip-group是 Vuetify 3 中实现Chip 选择分组的标准方案它继承VSlideGroup获得横向滑动能力复用useGroup获得完整的分组状态管理再通过provideDefaults把filter、variant、color等统一传递给内部 Chip。熟练掌握column、filter、mandatory、multiple四个核心 Props并结合显式value与v-model的使用即可覆盖从简单筛选到商品规格选择、话题订阅等绝大多数实战场景。如需进一步查阅可阅读 VChipGroup.tsx、分组逻辑 group.ts、样式 VChipGroup.sass以及全部官方示例位于 examples/v-chip-group 目录。【免费下载链接】vuetify Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表