- 前端
- AI 技能
【免费下载链接】basic
⭐⭐⭐⭐⭐ 面向 AI 编程的管理系统框架,兼容PC、移动端。AI-oriented management system framework, compatible with PC and mobile device.
FaSearchBar 是 Fantastic Admin 组件库中提供的一个可折叠搜索区域容器组件,专门用于承载列表页筛选条件、高级搜索表单与报表筛选选区。它本身不渲染任何表单项,而是通过 slot 接收表单内容,并对外暴露fold折叠状态与toggle切换方法,帮助开发者用极少的代码实现"常用条件常驻、次要条件折叠"的经典搜索区交互。本文将以 search-bar/README.md 为核心,结合组件源码与仓库内示例,完整讲解其 Props、Slots、Events 及四种实战用法,读完即可在项目中直接落地。
一、组件定位与使用场景
FaSearchBar 解决的是后台管理系统中列表页筛选区的"空间管理"问题:当筛选条件较多时,全部平铺会挤压表格可视区域,而完全隐藏又需要额外状态管理。该组件以容器 + 折叠状态的形式,把"展开/收起"这一通用交互封装为开箱即用的能力。
README 明确列出的适用场景包括:
- 列表页面筛选区:用户列表、订单列表等常规 CRUD 页面顶部的条件栏;
- 高级搜索表单:条件字段较多、需要二级展开的高级查询;
- 数据查询条件:数据分析页面的多维过滤条件;
- 报表筛选选区:报表导出前的范围与维度选择;
- 可折叠的表单区域:任意需要按需展开/收起的表单区块。
组件设计上遵循"容器不关心内容"的原则——它不内置任何输入框、下拉框,表单元素完全由使用方通过default插槽注入,因此与 FaInput、FaSelect、FaButton 等基础组件自由组合即可。
二、安装与引入
FaSearchBar 位于组件库源码目录packages/components/src/basic/search-bar/,其入口文件 index.ts 仅一行导出:
export { default as SearchBar } from './index.vue'组件库统一出口 packages/components/src/index.ts 中以FaSearchBar的名称对外暴露:
export { SearchBar as FaSearchBar } from './basic/search-bar'在仓库提供的各应用(如apps/core、apps/example等)中,组件通过 unplugin 自动导入机制按需注册,类型声明统一写入各应用的 components.d.ts,因此实际使用时无需手动 import,直接在模板中书写<FaSearchBar>即可。组件内部通过defineOptions({ name: 'BuiltInSearchBar' })声明了名称,便于 DevTools 调试与 keep-alive 场景下的组件识别。
此外,组件源码目录下的_examples/中存放了四个可运行的演示示例,并在示例应用 search_bar.vue 页面中通过@fantastic-admin/components/examples导出并渲染展示(对应路由配置见 component.example.ts),读者可以直接运行示例应用查看真实效果。
三、Props 详解
README 给出的 Props 定义如下:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
showToggle | boolean | true | 是否显示折叠按钮 |
background | boolean | false | 是否显示背景色 |
fold | boolean | false | 折叠状态(支持 v-model) |
结合 index.vue 的源码实现,逐项说明如下:
withDefaults( defineProps<{ showToggle?: boolean background?: boolean }>(), { showToggle: true, background: false, }, ) const fold = defineModel<boolean>('fold', { default: true, })showToggle:控制是否在容器底部渲染居中的折叠/展开按钮。设为false时按钮完全不渲染,此时需要使用方在 slot 内自行提供切换入口(见下文"自定义触发按钮"示例)。background:为true时为容器添加px-4 bg-secondary transition样式,即内边距与主题次级背景色,使搜索区在页面上形成独立的视觉区块。fold:折叠状态,通过defineModel实现 v-model 双向绑定。需要特别说明的是:README 表格中标注默认值为false,而当前源码实现中defineModel的默认值为true(即默认折叠收起),两者存在出入,实际行为以源码为准。若希望进入页面时默认展开,请显式传入v-model:fold="false"(仓库"默认展开"示例即采用此写法)。
四、Slots 插槽
组件仅提供一个default插槽,用于承载搜索表单内容:
| 名称 | 说明 |
|---|---|
default | 搜索表单内容,slot props:{ fold: boolean, toggle: () => void } |
源码中通过<slot :fold="fold" :toggle="toggle" />(见 index.vue)向插槽内容暴露两个关键值:
fold: boolean:当前是否处于折叠状态。使用方需要在插槽内根据该值控制次要条件字段的显隐,典型写法是v-show="!fold"。toggle: () => void:切换折叠状态的函数。当showToggle为false(隐藏内置按钮)时,可将其绑定到自定义按钮的@click上,实现完全自定义的触发入口。
五、Events 事件
| 事件名 | 参数 | 说明 |
|---|---|---|
toggle | value: boolean | 折叠状态变化时触发 |
源码中的触发逻辑位于 index.vue:
function toggle() { fold.value = !fold.value emits('toggle', fold.value) }点击按钮或调用 slot 暴露的toggle函数后,fold状态取反,同时以新的状态值触发toggle事件。该事件适合在需要监听折叠状态变化以联动其他逻辑(如统计布局高度、缓存展开偏好)的场景使用。
六、核心交互原理与渲染结构
FaSearchBar 的实现非常轻量,整个组件不到 50 行。理解其渲染结构有助于排查样式与布局问题(index.vue):
<template> <div class="relative" :class="{ 'py-4': showToggle, 'px-4 bg-secondary transition': background, }" > <slot :fold="fold" :toggle="toggle" /> <div v-if="showToggle" class="text-center w-full translate-y-1/2 bottom-0 left-0 absolute"> <button class="text-xs font-medium px-2 outline-none border-size-0 rounded bg-secondary inline-flex h-5 cursor-pointer select-none items-center" @click="toggle"> <Icon :name="fold ? 'i-ep:caret-bottom' : 'i-ep:caret-top' " /> </button> </div> </div> </template>几个值得注意的实现细节:
- 容器定位:外层
div使用relative定位,折叠按钮通过absolute+bottom-0 left-0+translate-y-1/2实现"骑跨"在容器底边线的半隐藏效果,视觉上更紧凑。 - 按钮样式:内置按钮复用主题的
bg-secondary背景与text-xs字号,并使用组件库自带的 Icon 渲染图标——折叠时显示i-ep:caret-bottom(向下箭头,提示可展开),展开时显示i-ep:caret-top(向上箭头,提示可收起)。 - 内边距联动:仅当
showToggle为true时容器才保留py-4垂直内边距,为骑跨按钮预留空间;隐藏按钮后容器将不再多占用这部分高度。 - 内容渲染策略:组件本身不做任何内容隐藏,折叠行为完全由使用方在插槽内通过
fold值配合v-show/v-if自行控制。这是该组件设计上最大的自由度所在——你可以折叠任意数量的字段,也可以自定义折叠后的过渡动画。
七、实战示例
仓库在_examples/目录提供了四个可直接运行的示例,分别覆盖基础用法、默认展开、背景样式与自定义触发按钮。下面逐一展开讲解。
7.1 基础用法:默认折叠 + 次要条件收起
_basic.vue 展示了最常见的列表筛选场景:核心条件(关键字、状态)常驻展示,次要条件(部门、角色、来源、创建人)默认折叠,通过v-show="!fold"控制显隐:
<script setup lang="ts"> // 组件实际使用时无需手动导入,框架会自动导入 import { reactive } from 'vue' import FaButton from '../../button/index.vue' import FaInput from '../../input/index.vue' import FaSelect from '../../select/index.vue' import FaSearchBar from '../index.vue' const form = reactive({ keyword: '', status: 'all', department: '', role: 'all', source: 'all', creator: '', }) const statusOptions = [ { label: '全部状态', value: 'all' }, { label: '启用', value: 'enabled' }, { label: '禁用', value: 'disabled' }, ] </script> <template> <FaSearchBar> <template #default="{ fold }"> <div class="gap-3 grid grid-cols-1 md:grid-cols-[repeat(auto-fit,minmax(350px,1fr))]"> <FaInput v-model="form.keyword" placeholder="搜索用户名" class="w-full" /> <FaSelect v-model="form.status" :options="statusOptions" class="w-full" /> <FaInput v-show="!fold" v-model="form.department" placeholder="部门" class="w-full" /> <FaSelect v-show="!fold" v-model="form.role" :options="roleOptions" class="w-full" /> <FaSelect v-show="!fold" v-model="form.source" :options="sourceOptions" class="w-full" /> <FaInput v-show="!fold" v-model="form.creator" placeholder="创建人" class="w-full" /> <div class="flex gap-2 col-end--1 justify-end"> <FaButton>查询</FaButton> <FaButton variant="outline"> 重置 </FaButton> </div> </div> </template> </FaSearchBar> </template>要点:查询/重置按钮使用col-end--1 justify-end固定在栅格最右侧;折叠按钮由组件内置渲染,无需额外代码。
7.2 默认展开:通过 v-model 控制初始状态
_expanded.vue 演示了如何使用v-model:fold控制初始展开状态——页面进入时即展示全部筛选条件:
<script setup lang="ts"> import { reactive, shallowRef } from 'vue' // ... FaButton / FaInput / FaSelect 导入省略 const form = reactive({ keyword: '', status: 'all', owner: '', priority: 'all', category: 'all', project: '', participant: '', }) const fold = shallowRef(false) </script> <template> <FaSearchBar v-model:fold="fold"> <template #default="{ fold: isFold }"> <!-- 网格布局中,次要字段统一 v-show="!isFold" --> <FaInput v-show="!isFold" v-model="form.owner" placeholder="负责人" class="w-full" /> <!-- ... 其余字段与查询/重置按钮省略 --> </template> </FaSearchBar> </template>实现要点:通过shallowRef(false)初始化折叠状态,再以v-model:fold绑定到组件。同时注意插槽解构时可对fold重命名({ fold: isFold }),避免与外部同名变量冲突。
7.3 背景样式:独立视觉区块
_background.vue 通过background属性为搜索区添加次级背景色与内边距,让筛选区域在页面上形成清晰的独立区块,适合需要与表格内容在视觉上强区分的页面:
<template> <FaSearchBar background> <template #default="{ fold }"> <!-- 公告/消息类筛选表单:关键字、类型、创建人、渠道、范围、审核人 --> <FaInput v-show="!fold" v-model="form.creator" placeholder="创建人" class="w-full" /> <FaSelect v-show="!fold" v-model="form.channel" :options="channelOptions" class="w-full" /> <!-- ... --> </template> </FaSearchBar> </template>开启后容器自动获得px-4 bg-secondary transition样式类,背景色跟随当前主题的次级色变量,深浅主题切换时无需额外适配。
7.4 自定义触发按钮:隐藏内置按钮
_custom-trigger.vue 展示show-toggle="false"的用法:隐藏底部居中按钮,改由使用方在表单区域内部(如按钮组末尾)提供自定义的"展开/收起"入口,同时利用插槽暴露的fold与toggle动态渲染文案与图标:
<template> <FaSearchBar :show-toggle="false"> <template #default="{ fold, toggle }"> <div class="gap-3 grid grid-cols-1 md:grid-cols-[repeat(auto-fit,minmax(350px,1fr))]"> <FaInput v-model="form.keyword" placeholder="搜索文章" class="w-full" /> <FaSelect v-model="form.status" :options="statusOptions" class="w-full" /> <FaInput v-show="!fold" v-model="form.tag" placeholder="标签" class="w-full" /> <!-- 其余次要字段 v-show="!fold" 省略 --> <div class="flex gap-2 col-end--1 justify-end"> <FaButton>查询</FaButton> <FaButton variant="outline">重置</FaButton> <FaButton variant="ghost" @click="toggle"> {{ fold ? '展开' : '收起' }} <FaIcon :name="fold ? 'i-lucide:chevron-down' : 'i-lucide:chevron-up'" /> </FaButton> </div> </div> </template> </FaSearchBar> </template>此模式将折叠入口融入操作按钮组,界面更整洁,也便于统一按钮的间距与视觉风格,适合筛选条件较多、不希望底部出现独立按钮的场景。
八、注意事项与最佳实践
结合 README 的注意事项与源码实现,归纳如下使用要点:
- 折叠内容需自行控制:
fold为true时组件并不会自动隐藏任何内容,必须在插槽内依据fold值(如v-show="!fold")控制次要字段的显示逻辑,折叠行为才能生效。 - 折叠按钮位置:默认情况下折叠按钮渲染在容器底部中央,以"骑跨"式半遮挡样式呈现;若要调整位置或样式,请使用
show-toggle="false"配合自定义触发按钮。 - 双向绑定:
fold支持v-model双向绑定,既可在父组件读取当前折叠状态,也可通过外部变量控制初始展开/收起。 - 默认值出入:README 标注
fold默认值为false,但当前源码defineModel的默认值为true(默认折叠);如需页面初始展开,务必显式绑定v-model:fold="false"。 - 与 v-show 搭配而非 v-if:折叠字段建议使用
v-show,避免字段切换时表单组件被销毁重建导致焦点丢失、校验状态重置等副作用。 - 表单联动:查询/重置按钮通常与表单绑定;重置时除了清空
reactive表单数据外,如需要可同时恢复折叠状态(将fold置回初始值)。 - 栅格自适应:示例中统一采用
grid grid-cols-1 md:grid-cols-[repeat(auto-fit,minmax(350px,1fr))]布局,在移动端单列展示、桌面端按宽度自动换行,与项目兼容 PC、移动端的整体定位一致。
九、总结
FaSearchBar 以极低的实现成本(不足 50 行源码)封装了列表页筛选区最通用的"折叠/展开"交互,配合fold双向绑定、showToggle与background两个布尔开关,以及向插槽暴露的fold/toggle能力,可以覆盖从极简筛选到高级搜索表单的绝大多数场景。其源码位于 packages/components/src/basic/search-bar/index.vue,四个完整可运行的示例见同目录下的_examples/文件夹,示例展示页面为 apps/example/src/views/component_example/search_bar.vue,读者可直接对照运行,将其作为列表页筛选区的标准容器组件复用。
- 前端
- AI 技能
【免费下载链接】basic
⭐⭐⭐⭐⭐ 面向 AI 编程的管理系统框架,兼容PC、移动端。AI-oriented management system framework, compatible with PC and mobile device.
相关推荐
Graylog 前端 `ExpandableList` 可折叠列表组件实战指南
Graylog 前端 ExpandableList 可折叠列表组件实战指南 导读 ExpandableList 是 Graylog Web 前端( graylo
日志分析运维观测探索 CollapseClick:优雅的可折叠列表控件
探索 CollapseClick:优雅的可折叠列表控件 项目介绍 CollapseClick 是一款强大且易于使用的 iOS 开源库,它为你的应用提供了类似 U
移动开发GDM Settings 快速入门:5分钟学会美化你的登录界面
GDM Settings 快速入门:5分钟学会美化你的登录界面 GDM Settings 是一款专为 GNOME 桌面环境设计的登录界面自定义工具,让你轻松定制
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考