# ByPageSearch 页面搜索组件

基于 ByForm 的页面级搜索组件,提供搜索表单、数据双向绑定、展开收起、自定义插槽等功能。

注意:本组件基于 ByForm 实现,支持 ByForm 的所有功能。如需了解更多高级配置和功能,请参考 ByForm 组件文档

# 基础用法

<template>
  <by-page-search
    v-model="searchQuery"
    :search-form-config="searchConfig"
    @submit="handleSearch"
    @reset="handleReset"
  />
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        formItems: [
          {
            field: 'keyword',
            type: 'input',
            label: '关键字',
            placeholder: '请输入关键字'
          },
          {
            field: 'status',
            type: 'select',
            label: '状态',
            placeholder: '请选择状态',
            options: [
              { label: '全部', value: '' },
              { label: '启用', value: 1 },
              { label: '禁用', value: 0 }
            ]
          },
          {
            field: 'createTime',
            type: 'datepicker',
            label: '创建时间',
            otherOptions: {
              type: 'daterange'
            }
          },
          {
            type: 'formButtons',
            otherOptions: {
              submitText: '搜索',
              resetText: '重置'
            }
          }
        ]
      }
    }
  },
  methods: {
    handleSearch(formData) {
      console.log('搜索参数:', formData)
      // 执行搜索逻辑
    },
    handleReset() {
      console.log('重置搜索')
      // 执行重置逻辑
    }
  }
}
</script>

# 高级功能

# 1. 展开收起功能

支持配置展开收起功能,当表单项较多时可以隐藏部分字段,提升用户体验。

<template>
  <by-page-search
    v-model="searchQuery"
    :search-form-config="searchConfig"
    @submit="handleSearch"
    @reset="handleReset"
  />
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        flexible: {
          foldField: ['keyword6', 'keyword7'], // 需要折叠的字段
          unfold: false // 默认是否展开
        },
        isFlexible: true, // 是否显示展开收起按钮
        formItems: [
          {
            field: 'keyword',
            type: 'input',
            label: '关键字',
            placeholder: '请输入关键字'
          },
          {
            field: 'keyword6',
            type: 'input',
            label: '项目6',
            placeholder: '请输入项目6'
          },
          {
            field: 'keyword7',
            type: 'input',
            label: '项目7',
            placeholder: '请输入项目7'
          },
          {
            type: 'formButtons'
          }
        ]
      }
    }
  }
}
</script>

特性:

  • 自动检测需要折叠的字段,当 foldField 中的字段存在于 formItems 中时显示展开收起按钮
  • 支持默认展开状态配置
  • 展开收起状态会保持到组件销毁

# 2. 自定义插槽

支持通过插槽自定义表单项内容,满足复杂的业务需求。

<template>
  <by-page-search v-model="searchQuery" :search-form-config="searchConfig" @submit="handleSearch" @reset="handleReset">
    <!-- 自定义表单项 -->
    <template #customField>
      <el-button @click="handleCustomAction">自定义操作</el-button>
    </template>

    <!-- 头部插槽 -->
    <template #header>
      <div class="search-header">
        <h3>用户搜索</h3>
      </div>
    </template>

    <!-- 底部插槽 -->
    <template #footer>
      <div class="search-footer">
        <el-button @click="handleExport">导出数据</el-button>
      </div>
    </template>
  </by-page-search>
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        formItems: [
          {
            field: 'keyword',
            type: 'input',
            label: '关键字'
          },
          {
            field: 'customField',
            type: 'custom', // 自定义类型
            label: '自定义操作'
          },
          {
            type: 'formButtons'
          }
        ]
      }
    }
  },
  methods: {
    handleCustomAction() {
      console.log('自定义操作')
    },
    handleExport() {
      console.log('导出数据')
    }
  }
}
</script>

特性:

  • 支持通过 type: 'custom' 定义自定义表单项
  • 提供 headerfooter 插槽用于添加头部和底部内容
  • 自定义插槽名称与 field 属性对应

# 3. 表单验证

支持完整的表单验证功能,包括必填验证、自定义验证规则等。

<template>
  <by-page-search
    v-model="searchQuery"
    :search-form-config="searchConfig"
    @submit="handleSearch"
    @reset="handleReset"
  />
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        rules: {
          keyword: [{ required: true, message: '请输入关键字', trigger: 'blur' }],
          email: [
            { required: true, message: '请输入邮箱', trigger: 'blur' },
            { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
          ]
        },
        formItems: [
          {
            field: 'keyword',
            type: 'input',
            label: '关键字',
            placeholder: '请输入关键字'
          },
          {
            field: 'email',
            type: 'input',
            label: '邮箱',
            placeholder: '请输入邮箱'
          },
          {
            type: 'formButtons'
          }
        ]
      }
    }
  }
}
</script>

特性:

  • 支持 Element UI 的所有验证规则
  • 支持单个字段验证和全局验证
  • 验证失败时会阻止表单提交

# 4. 响应式布局

支持响应式布局配置,适配不同屏幕尺寸。

<template>
  <by-page-search
    v-model="searchQuery"
    :search-form-config="searchConfig"
    @submit="handleSearch"
    @reset="handleReset"
  />
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        colLayout: {
          xl: 4, // >1920px 4个
          lg: 6, // >1200px 6个
          md: 8, // >992px 8个
          sm: 12, // >768px 12个
          xs: 24 // <768px 24个
        },
        formItems: [
          {
            field: 'keyword',
            type: 'input',
            label: '关键字',
            placeholder: '请输入关键字'
          },
          {
            field: 'status',
            type: 'select',
            label: '状态',
            placeholder: '请选择状态',
            options: [
              { label: '启用', value: 1 },
              { label: '禁用', value: 0 }
            ]
          },
          {
            type: 'formButtons'
          }
        ]
      }
    }
  }
}
</script>

特性:

  • 支持 Element UI 的栅格系统
  • 可全局配置或单个字段配置布局
  • 自动适配不同屏幕尺寸

# 完整示例

结合表格和分页的完整页面搜索示例:

<template>
  <div class="page-container">
    <!-- 搜索区域 -->
    <by-page-search
      v-model="searchQuery"
      :search-form-config="searchConfig"
      @submit="handleSearch"
      @reset="handleReset"
    />

    <!-- 数据表格 -->
    <by-table :grid-options="gridOptions" style="margin-top: 20px;" />

    <!-- 分页 -->
    <by-pager
      :total="total"
      :current-page="currentPage"
      :page-size="pageSize"
      @current-change="handlePageChange"
      @size-change="handleSizeChange"
      style="margin-top: 20px; text-align: right;"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      total: 0,
      currentPage: 1,
      pageSize: 10,

      // 搜索表单配置
      searchConfig: {
        labelWidth: '80px',
        flexible: {
          foldField: ['email', 'createTime'],
          unfold: false
        },
        isFlexible: true,
        formItems: [
          {
            field: 'name',
            type: 'input',
            label: '用户名',
            placeholder: '请输入用户名'
          },
          {
            field: 'status',
            type: 'select',
            label: '状态',
            placeholder: '请选择状态',
            options: [
              { label: '启用', value: 1 },
              { label: '禁用', value: 0 }
            ]
          },
          {
            field: 'dateRange',
            type: 'customDatePicker',
            label: '创建时间'
          },
          {
            field: 'email',
            type: 'input',
            label: '邮箱',
            placeholder: '请输入邮箱'
          },
          {
            field: 'createTime',
            type: 'datepicker',
            label: '注册时间',
            otherOptions: {
              type: 'daterange'
            }
          },
          {
            type: 'formButtons',
            otherOptions: {
              submitText: '搜索',
              resetText: '重置'
            }
          }
        ]
      },

      // 表格配置
      gridOptions: {
        columns: [
          { field: 'id', title: 'ID', width: 80 },
          { field: 'name', title: '用户名' },
          { field: 'email', title: '邮箱' },
          { field: 'status', title: '状态', formatter: this.formatStatus },
          { field: 'createTime', title: '创建时间' }
        ],
        data: []
      }
    }
  },

  mounted() {
    this.loadData()
  },

  methods: {
    // 搜索
    handleSearch(formData) {
      this.currentPage = 1
      this.loadData()
    },

    // 重置
    handleReset() {
      this.searchQuery = {}
      this.currentPage = 1
      this.loadData()
    },

    // 分页改变
    handlePageChange(page) {
      this.currentPage = page
      this.loadData()
    },

    // 每页条数改变
    handleSizeChange(size) {
      this.pageSize = size
      this.currentPage = 1
      this.loadData()
    },

    // 加载数据
    async loadData() {
      try {
        const params = {
          ...this.searchQuery,
          page: this.currentPage,
          pageSize: this.pageSize
        }

        const { data } = await this.$http.get('/api/users', { params })
        this.gridOptions.data = data.list
        this.total = data.total
      } catch (error) {
        this.$message.error('数据加载失败')
        console.error(error)
      }
    },

    // 格式化状态
    formatStatus(row) {
      return row.status === 1 ? '启用' : '禁用'
    }
  }
}
</script>

<style scoped>
.page-container {
  padding: 20px;
}
</style>

# API

# Props

参数 说明 类型 默认值
value/v-model 搜索表单数据 object {}
search-form-config 搜索表单配置 object {}

# Events

事件名 说明 参数
submit 点击搜索按钮时触发 (formData)
reset 点击重置按钮时触发
change 表单数据改变时触发 (event)
input 表单数据双向绑定 (formData)
batch-query-focus 批量查询聚焦时触发

# Slots

插槽名 说明 参数
header 搜索区域头部
footer 搜索区域底部
[field] 自定义表单项

# search-form-config 配置

参数 说明 类型 默认值
formItems 表单字段配置数组 array []
labelWidth 表单标签宽度 string '100px'
inline 是否行内表单 boolean false
flexible 展开收起配置 object
isFlexible 是否显示展开按钮 boolean true
colLayout 响应式布局配置 object
rules 表单验证规则 object {}
elSize 组件尺寸 string 'mini'

# flexible 配置

参数 说明 类型 默认值
foldField 需要折叠的字段 array []
unfold 默认是否展开 boolean false

# formItems 字段配置

参数 说明 类型 默认值
field 字段名 string
type 字段类型 string
label 标签文本 string
placeholder 占位符文本 string
options 选项数据 array []
otherOptions 其他配置选项 object {}
isHidden 是否隐藏 boolean false
colLayout 单个字段布局 object
rules 单个字段验证 array []

# 支持的字段类型

类型 说明 示例
input 输入框 文本输入
password 密码输入框 密码输入
select 选择器 下拉选择
commonSelector 通用选择器 多功能选择器
batchQuerySelector 批量查询选择器 批量查询选择器
datepicker 日期选择器 日期选择
cascader 级联选择器 级联选择
switch 开关 开关控件
radioGroup 单选框组 单选按钮
checkboxGroup 多选框组 多选按钮
text 文本显示 纯文本
pairNumberInput 双数字输入框 范围输入
customDatePicker 自定义日期选择器 日期范围
custom 自定义组件 插槽内容
search 搜索按钮 单个搜索按钮
formButtons 表单按钮组 搜索+重置按钮

# 注意事项

  1. 字段名唯一性formItems 中的 field 必须唯一,否则会导致数据绑定冲突
  2. 展开收起逻辑:只有当 flexible.foldField 中的字段存在于 formItems 中时,才会显示展开收起按钮
  3. 自定义插槽:使用 type: 'custom' 时,插槽名称必须与 field 属性一致
  4. 数据初始化:建议在 mounted 生命周期中初始化表单数据,确保组件正常工作
  5. 验证规则:表单验证规则支持全局配置和单个字段配置,单个字段的验证规则优先级更高

# 高级示例

# 使用通用选择器

通用选择器(commonSelector)是一个功能强大的选择器组件,支持多种选择模式和交互效果,适用于复杂的选择场景。

<template>
  <by-page-search v-model="searchQuery" :search-form-config="searchConfig" @submit="handleSearch" />
</template>

<script>
export default {
  data() {
    return {
      searchQuery: {},
      searchConfig: {
        formItems: [
          {
            field: 'department',
            type: 'commonSelector',
            label: '部门',
            placeholder: '请选择部门',
            selectorType: 'select', // 可选值:select、enhancedSelect、checkbox、border
            multiple: true, // 是否多选
            options: [
              { id: 1, name: '研发部', initial: 'Y', status: 1 },
              { id: 2, name: '市场部', initial: 'S', status: 1 },
              { id: 3, name: '财务部', initial: 'C', status: 1 }
            ]
          },
          {
            field: 'user',
            type: 'commonSelector',
            label: '用户',
            placeholder: '请选择用户',
            selectorType: 'checkbox', // 展开式选择器
            multiple: false, // 单选
            loadOptions: () => {
              // 异步加载数据
              return new Promise(resolve => {
                setTimeout(() => {
                  resolve([
                    { id: 1, name: '张三', initial: 'Z', status: 1 },
                    { id: 2, name: '李四', initial: 'L', status: 1 },
                    { id: 3, name: '王五', initial: 'W', status: 0 }
                  ])
                }, 1000)
              })
            },
            otherOptions: {
              showSearchBar: true, // 显示搜索栏
              pagination: true, // 启用分页
              pageSize: 50, // 每页显示数量
              needShowLoading: true // 显示加载状态
            }
          },
          {
            type: 'formButtons'
          }
        ]
      }
    }
  },
  methods: {
    handleSearch(formData) {
      console.log('搜索参数:', formData)
      // 执行搜索逻辑
    }
  }
}
</script>

commonSelector 配置选项:

参数 说明 类型 默认值
selectorType 选择器类型(select/enhancedSelect/checkbox/border) string 'select'
multiple 是否多选 boolean false
options 选项数据 array []
loadOptions 异步加载数据的函数 function null
otherOptions.showSearchBar 是否显示搜索栏 boolean false
otherOptions.pagination 是否启用分页 boolean false
otherOptions.pageSize 每页显示数量 number 50
otherOptions.needShowLoading 是否显示加载状态 boolean false

selectorType: 'enhancedSelect' 时,支持以下附加配置(透传到 ByCommonSelector):

参数 说明 类型 默认值
enhancedAllOptions 全量选项(用于默认值回显与对象映射) array []
enhancedTitleKey 标题字段名 string 'name'
enhancedDescriptionKey 描述字段名 string 'mobile'
enhancedDisabledKey 置灰字段名(0 置灰) string 'status'
enhancedDescriptionDisplay 是否展示描述 boolean true
enhancedCollapseTags 多选是否折叠标签 boolean false
enhancedDisabledCanSelect 置灰项是否仍可选 boolean false

可监听 enhanced-search 事件以执行远程搜索:

<by-page-search
  v-model="searchQuery"
  :search-form-config="{
    formItems: [
      {
        field: 'user',
        type: 'commonSelector',
        label: '用户',
        selectorType: 'enhancedSelect',
        placeholder: '请输入用户名,手机号搜索',
        options: enhancedSearchResults,
        enhancedAllOptions: allUsers,
        enhancedTitleKey: 'name',
        enhancedDescriptionKey: 'mobile'
      }
    ]
  }"
  @enhanced-search="({ query, item }) => fetchUsers(query, item)"
/>

注意:通用选择器(commonSelector)基于 ByCommonSelector 组件实现,更多高级配置请参考 ByCommonSelector 文档。 批量查询选择器(batchQuerySelector)基于 ByBatchQuerySelector 组件实现,更多高级配置请参考 ByBatchQuerySelector 文档。 自定义日期选择器(customDateSelector)基于 ByCustomDateSelector 组件实现,更多高级配置请参考 ByCustomDateSelector 文档

最后更新时间: 8/9/2025, 3:46:46 PM