@ fiscozen/ 选择
关于使用量的文件,见 故事书文档
发展
设置
- 清除仓库
- 安装依赖性 :
pnpm install - 运行 Dev 服务器 :
pnpm dev(从工作空间根)
建筑
这个 FzSelect 组件是支持两个标准选择行为(默认,当 filterable 错误)和打字头/可过滤行为(当 filterable ) (中文(简体). 它分享了相同的浮动面板,懒惰地加载,以及键盘导航模式. 默认情况下,它表现为标准选择下拉. 何时 filterable 设置为真,组件打开后显示一个可过滤的输入字段;否则,则显示所选选项标签为按钮.
关键部件 :
FzSelect.vue: 主要部件 管弦状态、过滤和导航FzSelectButton.vue: 开口按钮,在按钮和输入模式之间切换FzSelectOptionsList.vue: 含有懒惰加载支持的选项列表FzSelectLabel.vue: 有所需指标的标签部分FzSelectHelpError.vue: 帮助/错误消息组件
州管理层:
model: 所选值(字符串 QQ未定义)searchValue: 当前用于过滤的输入文本debouncedSearchValue: 跳过搜索Value版本internalFilteredOptions: 应用过滤器Fn或Fuse.js后过滤的选项visibleOptions: 被过滤选项的懒惰子集focusedIndex: 当前重点选择的索引selectableOptionsisOpen: 放下打开/关闭状态
过滤流 :
- 用户类型 +
searchValue更新 - 之后
delayTime妇女 □debouncedSearchValue更新 updateFilteredOptions()称为 − 适用filterFn或 Fuse.js 系统internalFilteredOptions更新 + 触发visibleOptions重设- 卷起懒惰的装入
visibleOptions扩展
代码组织
src/FzSelect.vue: 具有所有业务逻辑的主要组件src/types.ts: 道具和选项的类型定义src/common.ts: 共享公用事业(width计算,常数)src/utils.ts: 工具函数( 调试)src/components/: 内部列报部分FzSelectButton.vue: 按钮/输入切换器FzSelectOptionsList.vue: 选项列表渲染器FzSelectLabel.vue: 标签渲染器FzSelectHelpError.vue: 帮助/透视渲染器types.ts: 内部组件道具类型
关键概念
双模式输入
该组成部分采用双模式方法,当 filterable 事实 :
- 关闭状态:按钮显示所选选项标签(或占位符)
- 打开状态: 用于过滤的输入字段
何时 filterable 是虚假的(默认),组件作为标准选择的仅按键交互下拉.
这是处理在 FzSelectButton.vue 使用 shouldShowTheInput 计算检查的财产 filterable && isOpen。 。 。 .
过滤策略
该组件支持三种过滤模式:
-
自定义
filterFn(同步或同步): 优先于默认过滤- 打电话
debouncedSearchValue - 可以返回同步操作的承诺
- 没有种族条件保护 - 显示最后得到的结果
- 打电话
-
Fuse.js 模糊搜索: 当
filterable没错,fuzzySearch是真的,没有filterFn- 搜索在
label字段 - 处理打字和部分匹配
- 仅在输入有值时活动
- 可以通过设置禁用
fuzzySearch: false要使用简单的includes()搜索改为
- 搜索在
-
简单包括搜索: 当
filterable没错,fuzzySearch是假的,没有filterFn- 不区分大小写的使用
includes()用于子字符串匹配 - 不处理打字( 只匹配精确的子字符串)
- 仅在输入有值时活动
- 不区分大小写的使用
-
无过滤: 当
filterable错误( 默认) 或输入为空- 显示所有可用的选项
懒惰装入
为性能分批提供选项:
- 初始负载: 第一
optionsToShow(默认 25) 选项 - 滚动触发器: 当用户滚动到底部附近时装入下一批
- 缓冲 :
OPTIONS_BUFFER * OPTIONS_HEIGHT从下方触发的像素加载 - 选中选项: 超过可见范围时自动加载
带有已禁用选项的键盘导航
该组件浏览所有选项(包括禁用/只读),用于遵守WCAG:
selectableOptions: 所有可选选项(不包括标签,包括禁用/只读)focusedIndex: 索引的点selectableOptions- 导航穿行所有选项, 但禁用/ 仅读选项在不显示图像的情况下获得焦点
- Tab 导航允许为可访问性翻转已禁用的选项
在过滤器更改上重置滚动
何时 internalFilteredOptions 更改( 由于过滤或选项更新):
visibleOptions重排为第一批- 向上滚动位置
resetScrollPosition() - 防止过滤器更改后显示错误的选项
测试
运行测试
pnpm test:unit
pnpm coverage
测试结构
- 单位测试
src/__tests__/FzSelect.spec.ts - 测试命名 :
describe特性组的块,it特定案件的块 - 覆盖范围要求: > 90%
- 使用
mount从@vue/test-utils用于组件测试
测试范围
测试覆盖 :
- 制作和道具
- v- 模型绑定
- 选项过滤( Fuse.js 和自定义过滤Fn)
- 懒惰装入
- 键盘导航(包括已禁用选项)
- 重点管理
- 错误和帮助状态
- 无障碍属性
- 边框(空选项,未定义选项等)
添加特性
步骤1:更新类型
添加新道具到 src/types.ts 与联合来文文件:
/**
* Description of the prop
* @default 'defaultValue' if applicable
*/
newProp?: string
步骤2:实施逻辑
在 src/FzSelect.vue数字 :
- 采用代表制模式
- 使用信息专家模式( 将全部对象传递给助手)
- 提取重复逻辑到帮助函数
步骤 3: 更新模板
在模板部分添加新的 UI 元素 :
- 维护区域顺序 :
<script>→<template>→<style> - 使用语义 HTML 和 ARIA 属性
第4步:添加测试
新功能的写入单元测试 :
- 检测阳性和阴性病例
- 测试边缘大小写( null, 未定义, 空值)
- 测试无障碍功能
步骤5:更新文档
- 以使用示例更新 MDX
- 如果架构/日志更改, 更新 README
构建和释放
- 构建 :
pnpm build - 版本: 跟踪 semver
- 发布 :
pnpm publish(从工作空间根)
内部逻辑
Width 计算算法
这个 calculateContainerWidth() 函数在 src/common.ts数字 :
- 测量开口元素的边框矩形
- 设置最小宽度( 打开宽度, MIN WIDTH)
- 计算左右可用的空间
- 将最大宽度设置为打开宽度 + 最大( 空间左, 空间右)
这保证了下放匹配开口宽度,同时尊重取景口边界.
重点管理
打开滴入时的焦点流 :
- 若为
filterable: 焦点移动到输入字段(FzInput内部FzSelectButton(中文(简体) ) - 如果没有
filterable: 焦点移动到第一个启用的选项 - 如果选中选项: 焦点移动到所选选项( 如果启用)
关闭时的焦点流 :
- 焦点返回到打开按钮
focusedIndex重排为 - 1
过滤种族条件
何时 filterFn 快速调用 :
- 没有取消机制 - 所有通话进行
- 显示最后结果( 可覆盖先前的结果)
- 开发者处理种族条件的责任( 如请求取消)
这种设计选择将简化和开发者对自动赛跑条件处理的控制放在优先位置.
设计决定
为什么双模式输入而不是总输入?
双模式方法(关闭时的按钮,打开时的输入)提供:
- 更好的 UX: 选中的值在不过滤时清晰可见
- 空间效率:仅在需要时才出现输入
- 熟悉模式: 匹配常见的选定执行
为什么没有为过滤器Fn提供种族条件保护?
种族条件处理由开发者负责,因为:
- 不同的使用情况需要不同的策略(取消、取消、排队)
- 自动取消可以在开发者的代码中隐藏错误
- 较简单的 API: 只显示最后收到的结果
为什么通过所有选项( 包含已禁用) ?
导航所有选项( 包括禁用/ 仅读) , 用于遵守 WCAG :
- 屏幕阅读器可以宣布所有选项,包括已禁用选项
- 键盘用户可以翻转完整的上下文列表
- 禁用选项获得焦点,但没有视觉指示
- 更好的可获取性:用户理解全套选项集
为什么是第一种风格的代理模式?
使用 switch(true) 有条件样式的辅助函数 :
- 清晰地绘制出:"元件何时看起来像X
- 可维护:添加新视觉状态=添加新病例
- 自我文档:结构回答"何时看起来像X"
- 可测试: 帮助器功能可以单独测试
依赖关系
同伴依赖关系 :
vue: ^3.4.13 (中文(简体) )tailwindcss页:1
依赖性 :
@fiscozen/composables: 浮动面板定位@fiscozen/action: 选项列表渲染@fiscozen/input输入字段@fiscozen/icons图标组件@fiscozen/progress: 正在装入指标fuse.js: 模糊搜索库
依赖性:
- 标准测试和构建工具(viest, vite, typescript等)
业绩考量
- 懒惰装入: 大列表(100+项目)的自动
- 调试: 可通过配置
delayTime(默认500ms) - Fuse.js (法语): 只有在需要时才被即时处理(计算的财产)
- 滚动收听器: 附着一次,在卸载上清理
- 监视优化: 用途
immediate: true仅在需要时
已知的限制
- 无多选择单项选择
- 没有虚拟滚动: 懒惰加载批次, 但所有可见选项都在 DOM 中
- 无过滤器Fn 取消: Async filterFn 调用不会自动取消