# 查询列表
此例请全屏查看
<template>
<div>
<el-dialog :visible="visible" @close="visible=false" fullscreen>
<wl-search-list
:columns="columns"
:form-items="formItems"
@get-table-data="getTableData"
v-model="formData"
ref="plSearchList"
>
<template #test-form-item="{form,item}">
<el-form-item label="测试slot" prop="testValue">
<el-cascader
style="width:100%"
v-model="form.testValue"
:options="options"
clearable
@change="handleChange"></el-cascader>
</el-form-item>
</template>
<template #name="{row}">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ row.name }}</p>
<p>住址: {{ row.address }}</p>
<div class="name-wrapper" slot="reference">
<el-tag size="medium">{{ row.name }}</el-tag>
</div>
</el-popover>
</template>
</wl-search-list>
</el-dialog>
<el-alert type="warning" :closable="false" center>此例请全屏查看</el-alert>
<el-button @click="visible=true">全屏展示</el-button>
</div>
</template>
<script>
import axios from 'axios'
import { filterObject } from '../util'
const jobDict = {
designer: '设计',
programmer: '程序员',
testers: '测试',
product: '产品'
}
const sexDict = {
0: '女',
1: '男'
}
export default {
name: 'search-list-demo-01',
data() {
return {
formData: {
id: '',
name: '',
birth: '',
sex: '',
job: '',
testValue: []
},
visible: false
}
},
methods: {
async getTableData({ currentPage, pageSize, sex, ...val }, done) {
console.log(val)
let res = await axios.post('/search-table', filterObject({
...val,
currentPage,
pageSize,
sex: sex ? parseInt(sex) : '',
testValue: undefined
}))
if (res.status === 200) {
res = res.data
console.log(res)
done({
data: res.list,
total: res.total
})
}
},
async deleteData(row) {
let res = await axios.post('/delete-user', { id: row.id })
if (res.status === 200) {
this.$message.success('删除成功')
this.$refs.plSearchList.search()
}
},
handleChange() {
}
},
computed: {
columns() {
return [
{ prop: 'index', label: '序号', type: 'index' },
{ prop: 'id', label: 'id' },
{ slotName: 'name', label: '姓名', attrs: { width: 100 } },
{ prop: 'address', label: '地址', attrs: { minWidth: 140 } },
{ prop: 'birth', label: '生日', formatter: 'date' },
{ prop: 'job', label: '职位', dict: jobDict, options: jobDict },
{
prop: 'sex',
label: '性别',
tagMap: {
1: { text: '男', type: 'primary' },
0: { text: '女', type: 'success' }
}
},
{
actions: [
{
action: 'del',
text: '删除',
btnConfig: { type: 'danger' },
confirm: ({ row, col, index }) => {
this.deleteData(row)
}
},
{
text: '查看',
onClick: ({ row, col, index }) => {
this.$message.success(JSON.stringify(row))
}
},
{
text: '编辑',
onClick: ({ row, col, index }) => {
}
}
],
label: '操作', attrs: { minWidth: 180 }
}
]
},
formItems() {
return [
{ comp: 'input', prop: 'id', label: 'id' },
{ comp: 'input', prop: 'name', label: '姓名' },
{ comp: 'date', prop: 'birth', label: '生日' },
{ comp: 'select', prop: 'job', label: '职位', options: jobDict },
{ comp: 'select', prop: 'sex', label: '性别', options: sexDict },
{ slotName: 'test-form-item', prop: 'test', label: '测试slot' }
]
},
options() {
return [
{
value: 'zhinan', label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{ value: 'yizhi', label: '一致' },
{ value: 'fankui', label: '反馈' },
{ value: 'xiaolv', label: '效率' },
{ value: 'kekong', label: '可控' }
]
},
{
value: 'daohang',
label: '导航',
children: [
{ value: 'cexiangdaohang', label: '侧向导航' },
{ value: 'dingbudaohang', label: '顶部导航' }
]
}
]
},
{
value: 'zujian',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{ value: 'layout', label: 'Layout 布局' },
{ value: 'color', label: 'Color 色彩' },
{ value: 'typography', label: 'Typography 字体' },
{ value: 'icon', label: 'Icon 图标' },
{ value: 'button', label: 'Button 按钮' }
]
},
{
value: 'form',
label: 'Form',
children: [
{ value: 'radio', label: 'Radio 单选框' },
{ value: 'checkbox', label: 'Checkbox 多选框' },
{ value: 'input', label: 'Input 输入框' },
{ value: 'input-number', label: 'InputNumber 计数器' },
{ value: 'select', label: 'Select 选择器' },
{ value: 'cascader', label: 'Cascader 级联选择器' },
{ value: 'switch', label: 'Switch 开关' },
{ value: 'slider', label: 'Slider 滑块' },
{ value: 'time-picker', label: 'TimePicker 时间选择器' },
{ value: 'date-picker', label: 'DatePicker 日期选择器' },
{ value: 'datetime-picker', label: 'DateTimePicker 日期时间选择器' },
{ value: 'upload', label: 'Upload 上传' },
{ value: 'rate', label: 'Rate 评分' },
{ value: 'form', label: 'Form 表单' }
]
},
{
value: 'data',
label: 'Data',
children: [
{ value: 'table', label: 'Table 表格' },
{ value: 'tag', label: 'Tag 标签' },
{ value: 'progress', label: 'Progress 进度条' },
{ value: 'tree', label: 'Tree 树形控件' },
{ value: 'pagination', label: 'Pagination 分页' },
{ value: 'badge', label: 'Badge 标记' }
]
},
{
value: 'notice',
label: 'Notice',
children: [
{ value: 'alert', label: 'Alert 警告' },
{ value: 'loading', label: 'Loading 加载' },
{ value: 'message', label: 'Message 消息提示' },
{ value: 'message-box', label: 'MessageBox 弹框' },
{ value: 'notification', label: 'Notification 通知' }
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{ value: 'menu', label: 'NavMenu 导航菜单' },
{ value: 'tabs', label: 'Tabs 标签页' },
{ value: 'breadcrumb', label: 'Breadcrumb 面包屑' },
{ value: 'dropdown', label: 'Dropdown 下拉菜单' },
{ value: 'steps', label: 'Steps 步骤条' }
]
},
{
value: 'others',
label: 'Others',
children: [
{ value: 'dialog', label: 'Dialog 对话框' },
{ value: 'tooltip', label: 'Tooltip 文字提示' },
{ value: 'popover', label: 'Popover 弹出框' },
{ value: 'card', label: 'Card 卡片' },
{ value: 'carousel', label: 'Carousel 走马灯' },
{ value: 'collapse', label: 'Collapse 折叠面板' }
]
}
]
},
{
value: 'ziyuan',
label: '资源',
children: [
{ value: 'axure', label: 'Axure Components' },
{ value: 'sketch', label: 'Sketch Templates' },
{ value: 'jiaohu', label: '组件交互文档' }
]
}
]
}
}
}
</script>
<style scoped>
</style>
显示代码
提示
wl-search-list
由el-form
,el-table
,el-pagnation
三个组件组合而成,使得写业务的时候告别重复的查询表格,直接配置相关的项即可.对于不能使用简单的字段描述的表格项和表单项,可配置slotName,在模板中使用slot则可以写出任意组合的组件了,如本例中,form中的测试slot
项,table中姓名
一列,使用的slot.
# 虚拟滚动
有些场景需要大数据不分页,原本的el-table
在数据为1000条以上的时候就很卡了,本组件封装了虚拟滚动,10000条以上的数据也不卡
此例请全屏查看
<template>
<div>
<el-dialog :visible="visible" @close="visible=false" fullscreen>
<wl-search-list
:columns="columns"
:form-items="formItems"
:show-pager="false"
@get-table-data="getTableData"
v-model="formData"
ref="plSearchList"
:table-config="{virtualScroll:true}"
>
</wl-search-list>
</el-dialog>
<el-alert type="warning" :closable="false" center>此例请全屏查看</el-alert>
<el-button @click="visible=true">全屏展示</el-button>
</div>
</template>
<script>
import axios from 'axios'
import { filterObject } from '../util'
const jobDict = {
designer: '设计',
programmer: '程序员',
testers: '测试',
product: '产品'
}
const sexDict = {
0: '女',
1: '男'
}
export default {
name: 'search-list-demo-02',
data () {
return {
formData: {
id: '',
name: '',
birth: '',
sex: '',
job: '',
testValue: []
},
visible: false
}
},
methods: {
async getTableData ({ sex, ...val }, done) {
let list = []
for (let i = 0; i < 10000; i++) {
list.push({
id: i,
address: `地址${i}`,
fixedRight: i
})
}
done({
data: list,
total: 100
})
},
async deleteData (row) {
let res = await axios.post('/delete-user', { id: row.id })
if (res.status === 200) {
this.$message.success('删除成功')
this.$refs.plSearchList.search()
}
},
handleChange () {
}
},
computed: {
columns () {
return [
{ prop: 'id', label: 'id' },
{ prop: 'address', label: '地址', attrs: { minWidth: 140 } },
{ prop: 'birth', label: '生日', formatter: 'date' },
{ prop: 'job', label: '职位', dict: jobDict, options: jobDict },
{
prop: 'sex',
label: '性别',
tagMap: {
1: { text: '男', type: 'primary' },
0: { text: '女', type: 'success' }
}
},
{
label: '固定右边列', prop: 'fixedRight', attrs: { minWidth: 180, fixed: 'right' }
}
]
},
formItems () {
return [
{ comp: 'input', prop: 'id', label: 'id' },
{ comp: 'input', prop: 'name', label: '姓名' },
{ comp: 'date', prop: 'birth', label: '生日' },
{ comp: 'select', prop: 'job', label: '职位', options: jobDict },
{ comp: 'select', prop: 'sex', label: '性别', options: sexDict }
]
}
}
}
</script>
<style scoped>
</style>
显示代码
# 特色功能
- 表单查询项使用响应式布局,目前内置4个响应点:
x>=1900 | 1200<=x<1900 | 992<=x<1200 | x<992 |
---|---|---|---|
四列 | 三列 | 两列 | 一列 |
- 表单查询项添加收起展开功能,体验友好
- 自动高度,在全屏条件下,可设置各种分页模式,均为table内部滚动条,固定了表头
- 查询分页等功能大大简化
- 内置序号列,自动根据分页设置序号列
警告
此例由于用到mock数据,受限于codepen单html模式,此例在线运行功能不可用,请点击全屏展示按钮查看效果