news 2026/10/3 8:19:13

FaSearchBar 可折叠搜索栏:Fantastic Admin 列表页筛选区的折叠容器组件实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FaSearchBar 可折叠搜索栏:Fantastic Admin 列表页筛选区的折叠容器组件实战指南
  • 前端
  • AI 技能

【免费下载链接】basic

⭐⭐⭐⭐⭐ 面向 AI 编程的管理系统框架,兼容PC、移动端。AI-oriented management system framework, compatible with PC and mobile device.

项目地址:https://gitcode.com/GitHub_Trending/ba/basic
点击查看免费下载

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 定义如下:

属性类型默认值说明
showTogglebooleantrue是否显示折叠按钮
backgroundbooleanfalse是否显示背景色
foldbooleanfalse折叠状态(支持 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 事件

事件名参数说明
togglevalue: 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>

几个值得注意的实现细节:

  1. 容器定位:外层div使用relative定位,折叠按钮通过absolute+bottom-0 left-0+translate-y-1/2实现"骑跨"在容器底边线的半隐藏效果,视觉上更紧凑。
  2. 按钮样式:内置按钮复用主题的bg-secondary背景与text-xs字号,并使用组件库自带的 Icon 渲染图标——折叠时显示i-ep:caret-bottom(向下箭头,提示可展开),展开时显示i-ep:caret-top(向上箭头,提示可收起)。
  3. 内边距联动:仅当showToggle为true时容器才保留py-4垂直内边距,为骑跨按钮预留空间;隐藏按钮后容器将不再多占用这部分高度。
  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 的注意事项与源码实现,归纳如下使用要点:

  1. 折叠内容需自行控制:fold为true时组件并不会自动隐藏任何内容,必须在插槽内依据fold值(如v-show="!fold")控制次要字段的显示逻辑,折叠行为才能生效。
  2. 折叠按钮位置:默认情况下折叠按钮渲染在容器底部中央,以"骑跨"式半遮挡样式呈现;若要调整位置或样式,请使用show-toggle="false"配合自定义触发按钮。
  3. 双向绑定:fold支持v-model双向绑定,既可在父组件读取当前折叠状态,也可通过外部变量控制初始展开/收起。
  4. 默认值出入:README 标注fold默认值为false,但当前源码defineModel的默认值为true(默认折叠);如需页面初始展开,务必显式绑定v-model:fold="false"。
  5. 与 v-show 搭配而非 v-if:折叠字段建议使用v-show,避免字段切换时表单组件被销毁重建导致焦点丢失、校验状态重置等副作用。
  6. 表单联动:查询/重置按钮通常与表单绑定;重置时除了清空reactive表单数据外,如需要可同时恢复折叠状态(将fold置回初始值)。
  7. 栅格自适应:示例中统一采用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.

项目地址:https://gitcode.com/GitHub_Trending/ba/basic
点击查看免费下载
上一篇:Task 模板引擎完全指南:用 Go text/template 打造动态 Taskfile
下一篇:Omarchy 安装脚本架构指南:从 ISO 编排到目标端幂等配置

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 8:17:27

agno Agent 输入输出实用指南:6 个机制控制它说什么、怎么说

agno Agent 输入输出实用指南&#xff1a;6 个机制控制它说什么、怎么说 【免费下载链接】agno Build, run, and manage agent platforms. 项目地址: https://gitcode.com/GitHub_Trending/ag/agno agno 是一个用 Python 构建、运行和管理 Agent 平台的框架。实际用起来…

作者头像 李华
网站建设 2026/10/3 8:15:11

Mac 窗口管理只按一个键:Loop 分屏快捷键完整指南

Mac 窗口管理只按一个键&#xff1a;Loop 分屏快捷键完整指南 【免费下载链接】Loop Window management made elegant. 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop Loop 是一款开源的 Mac 窗口管理工具&#xff1a;按下默认触发键 fn 加方向键&#xff0c;…

作者头像 李华