当前位置:   article > 正文

vue + element 实现的可配置的数据搜索组件

vue + element 实现的可配置的数据搜索组件

vue + element 实现的可配置的数据搜索组件(搜索框 + table展示 + 分页控制)

说明:

在管理系统中,涉及到很多根据查询条件,查出数据,然后使用表格展示的页面。

对于这种复用性极强的page,提供一个公共的组件是很必要的(样式统一、高效开发)。

主要切分为3个组件。

1、Filter 功能:搜索条件,搜索按钮

2、Table 功能:展示数据,列表内实现一些操作如:查看、编辑等

3、Pagination 功能:分页,控制页面大小,页面数

调用方式:

  1. <template lang="pug">
  2. FilterTable(
  3. :list="list"
  4. :filters="filters"
  5. :tableList="tableList"
  6. :pageNum="pageNum"
  7. :pageSize="pageSize"
  8. :total="total"
  9. @listenHandleClickFilterButton="handleClickFilterButton"
  10. @listenHandleClickTableColumnHref="handleClickTableColumnHref"
  11. @listenHandleChangePaginationSize="handleChangePaginationSize"
  12. @listenHandleChangePaginationNum="handleChangePaginationNum"
  13. )
  14. </template>
  15. import FilterTable from '@/components/common/c-filter-table'
  16. import list from './list'
  17. export default {
  18. components: {
  19. FilterTable
  20. },
  21. created() {},
  22. data() {
  23. return {
  24. pageNum: 1,
  25. pageSize: 20,
  26. total: 0,
  27. tableList: [],
  28. list,
  29. filters: list.filterList.reduce((obj, item) => {
  30. if (item.type !== 'button') {
  31. obj[item.key] = ''
  32. }
  33. return obj
  34. }, {}),
  35. }
  36. },
  37. methods: {
  38. handleClickFilterButton(buttonKey) {
  39. if (buttonKey === 'search') {
  40. this.handleClickSearch()
  41. }
  42. if (buttonKey === 'reset') {
  43. this.handleClickReset()
  44. }
  45. if (buttonKey === 'export') {
  46. this.handleClickExport()
  47. }
  48. if (buttonKey === 'add') {
  49. this.handleClickAdd()
  50. }
  51. },
  52. handleClickTableColumnHref(columnKey, row) {
  53. if (columnKey === 'edit') {
  54. console.log('click column edit')
  55. }
  56. },
  57. handleChangePaginationSize(size) {
  58. this.pageNum = 1
  59. this.pageSize = size
  60. this.handleClickSearch()
  61. },
  62. handleChangePaginationNum(num) {
  63. this.pageNum = num
  64. this.handleClickSearch()
  65. },
  66. async handleClickSearch() {
  67. ...
  68. },
  69. handleClickAdd() {
  70. ...
  71. },
  72. async handleClickReset() {
  73. this.filters = list.filterList.reduce((obj, item) => {
  74. if (item.type !== 'button') {
  75. obj[item.key] = ''
  76. }
  77. return obj
  78. }, {})
  79. ...
  80. }
  81. }
  82. }
  83. 复制代码

参数说明

list:搜索框配置、表格字段配置

一个list配置如下:

  1. const list = {
  2. filterList: [
  3. {
  4. label: '座位号',
  5. key: 'id',
  6. type: 'input',
  7. span: 6
  8. },
  9. {
  10. label: '班级',
  11. key: 'class',
  12. type: 'select',
  13. options: [
  14. {
  15. key: '1',
  16. label: '一班',
  17. val: '1'
  18. },
  19. {
  20. key: '2',
  21. label: '二班',
  22. val: '2'
  23. }
  24. ],
  25. span: 6
  26. },
  27. {
  28. label: '入学日期',
  29. key: 'statPeriod',
  30. type: 'datePicker',
  31. span: 6,
  32. config: {
  33. type: 'date',
  34. placeholder: '选择日期'
  35. }
  36. },
  37. {
  38. label: '入校时长',
  39. key: 'backDate',
  40. type: 'datePicker',
  41. config: {
  42. type: 'daterange',
  43. rangeSeparator: '至',
  44. startPlaceholder: '开始日期',
  45. endPlaceholder: '结束日期'
  46. },
  47. span: 12
  48. },
  49. {
  50. label: '查询',
  51. key: 'search',
  52. type: 'button',
  53. config: {
  54. type: 'primary'
  55. },
  56. span: 2
  57. },
  58. {
  59. label: '重置',
  60. key: 'reset',
  61. type: 'button',
  62. config: {
  63. type: ''
  64. },
  65. span: 2
  66. },
  67. {
  68. label: '导出',
  69. key: 'export',
  70. type: 'button',
  71. config: {
  72. type: 'success'
  73. },
  74. span: 2
  75. }
  76. ],
  77. tableColumns: [
  78. {
  79. label: '状态',
  80. key: 'stateName'
  81. },
  82. {
  83. label: '编号',
  84. key: 'code'
  85. },
  86. {
  87. label: '姓名',
  88. key: 'name'
  89. },
  90. {
  91. label: '年龄',
  92. key: 'remark'
  93. },
  94. {
  95. label: '操作',
  96. key: 'edit',
  97. type: 'href',
  98. filter: () => '编辑'
  99. }
  100. ],
  101. 复制代码

filterList 用于配置搜索框 对应的事件处理为:listenHandleClickFilterButton

tableColumns 用于配置表格字段 对应的事件处理为:listenHandleClickTableColumnHref

tableList: 搜索结果,传入table的数据

pageNum、pageSize、total: 分页需要的数据

对应的控制分页事件为:listenHandleChangePaginationSize、listenHandleChangePaginationNum

c-filter-table完整代码:

  1. <template lang="pug">
  2. .c-table-container
  3. el-form.search-box
  4. el-row(:gutter="20")
  5. template(v-for="item in list.filterList")
  6. el-col(
  7. v-if="item.type==='button'"
  8. :span="item.span"
  9. :key="item.key")
  10. el-button(:type="item.config.type" @click="handleClickFilterButton(item.key)") {{ item.label }}
  11. el-col(
  12. v-else
  13. :span="item.span"
  14. :key="item.key")
  15. el-form-item(
  16. :label="item.label"
  17. :prop="item.key"
  18. label-width="110px")
  19. el-input(
  20. v-if="item.type==='input'"
  21. v-model="filters[item.key]")
  22. el-select(
  23. v-if="item.type==='select'"
  24. v-model="filters[item.key]")
  25. el-option(
  26. v-for="option in item.options"
  27. :key="option.key"
  28. :value="option.val"
  29. :label="option.label")
  30. el-select(
  31. v-if="item.type==='select-filterable'"
  32. v-model="filters[item.key]"
  33. filterable placeholder="请选择")
  34. el-option(
  35. v-for="option in item.options"
  36. :key="option.key"
  37. :value="option.val"
  38. :label="option.label")
  39. el-date-picker(
  40. v-if="item.type==='datePicker'"
  41. v-model="filters[item.key]"
  42. :type="item.config.type"
  43. :range-separator="item.config.rangeSeparator"
  44. :start-placeholder="item.config.startPlaceholder"
  45. :end-placeholder="item.config.endPlaceholder")
  46. el-table(:data="tableList" border)
  47. el-table-column(
  48. type="index"
  49. label="序号"
  50. align="center")
  51. el-table-column(
  52. v-for="item in list.tableColumns"
  53. :key="item.key"
  54. :label="item.label"
  55. :prop="item.key"
  56. align="center")
  57. template(slot-scope="scope")
  58. a(
  59. v-if="item.type === 'href'"
  60. class="blue"
  61. @click="handleClickTableColumnHref(item.key, scope.row)"
  62. ) {{ item.filter(scope.row) }}
  63. span(v-else) {{ item.filter ? item.filter(scope.row) : scope.row[item.key] }}
  64. el-pagination(
  65. @size-change="handleChangePaginationSize"
  66. @current-change="handleChangePaginationNum"
  67. :page-sizes="[10, 20, 50, 100]"
  68. :current-page.sync="selfPageNum"
  69. :page-size="selfPageSize"
  70. layout="total, sizes, prev, pager, next, jumper"
  71. :total="total")
  72. </template>
  73. <script>
  74. export default {
  75. props: [
  76. 'list',
  77. 'tableList',
  78. 'total',
  79. 'pageNum',
  80. 'pageSize',
  81. 'filters',
  82. 'listenHandleClickFilterButton',
  83. 'listenHandleClickTableColumnHref',
  84. 'listenHandleChangePaginationSize',
  85. 'listenHandleChangePaginationNum'
  86. ],
  87. data() {
  88. return {
  89. selfPageNum: this.pageNum,
  90. selfPageSize: this.pageSize
  91. }
  92. },
  93. methods: {
  94. handleClickFilterButton(filterKey) {
  95. this.$emit('listenHandleClickFilterButton', filterKey)
  96. },
  97. handleClickTableColumnHref(columnKey, row) {
  98. this.$emit('listenHandleClickTableColumnHref', columnKey, row)
  99. },
  100. handleChangePaginationSize(val) {
  101. this.selfPageNum = 1
  102. this.selfPageSize = val
  103. this.$emit('listenHandleChangePaginationSize', val)
  104. },
  105. handleChangePaginationNum(val) {
  106. this.selfPageNum = val
  107. this.$emit('listenHandleChangePaginationNum', val)
  108. }
  109. }
  110. }
  111. </script>
  112. <style scoped lang="scss">
  113. .el-row {
  114. margin-bottom: 20px;
  115. &:last-child {
  116. margin-bottom: 0;
  117. }
  118. }
  119. .el-col {
  120. border-radius: 4px;
  121. }
  122. .blue {
  123. color: #409eff;
  124. }
  125. .c-table-container {
  126. padding: 15px;
  127. min-height: 500px;
  128. .search-box.el-form {
  129. display: flex;
  130. flex-wrap: wrap;
  131. .el-form-item {
  132. .el-input {
  133. width: 160px;
  134. }
  135. }
  136. }
  137. .extand {
  138. .el-form-item {
  139. width: 25%;
  140. }
  141. }
  142. .el-pagination {
  143. text-align: right;
  144. padding: 10px;
  145. }
  146. }
  147. </style>
  148. 复制代码

转载于:https://juejin.im/post/5c909c995188252dac6d292b

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/103101
推荐阅读
相关标签
  

闽ICP备14008679号