filter-grid.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <template>
  2. <el-container class="container">
  3. <el-header height="36px" style="line-height:36px;" v-if="filter || action">
  4. <slot name="filter" v-if="filter">
  5. <div class="filter-box">
  6. <el-input placeholder="请输入内容" class="input-with-select" :clearable="true" size="mini" v-model="filterData.value">
  7. <el-select slot="prepend" placeholder="请选择" width="110" v-model="filterData.name">
  8. <el-option v-for="(item, index) in filterFields" :label="item.label" :value="item.name" :key="'filter' + index"></el-option>
  9. </el-select>
  10. <el-button slot="append" icon="el-icon-search" @click="query"></el-button>
  11. </el-input>
  12. </div>
  13. </slot>
  14. <slot name="action" v-if="action">
  15. <el-button icon="el-icon-plus" type="primary" size="mini" v-if="!readonly" @click="$emit('add-new')">添加</el-button>
  16. </slot>
  17. </el-header>
  18. <el-main class="table-area">
  19. <lite-grid :data="data" :meta="meta" :options="options" :readonly="readonly" :operation="operation" @oper="handleOper">
  20. <template slot="pre">
  21. <slot name="pre"> </slot>
  22. </template>
  23. <slot> </slot>
  24. <template slot="oper">
  25. <slot name="oper"> </slot>
  26. </template>
  27. <template slot="ext">
  28. <slot name="ext"> </slot>
  29. </template>
  30. <template slot="post">
  31. <slot name="post"> </slot>
  32. </template>
  33. </lite-grid>
  34. </el-main>
  35. <el-footer height="36px" v-if="paging">
  36. <el-pagination
  37. background
  38. @size-change="handleSizeChange"
  39. @current-change="handleCurrentChange"
  40. :current-page="page"
  41. :page-sizes="[10, 20, 50, 100, 200]"
  42. :page-size="size"
  43. :total="total"
  44. layout="total, sizes, prev, pager, next, jumper"
  45. ></el-pagination>
  46. </el-footer>
  47. </el-container>
  48. </template>
  49. <script>
  50. import { FieldMeta } from './meta-util';
  51. import LiteGrid from './lite-grid';
  52. export default {
  53. name: 'filter-grid',
  54. components: {
  55. LiteGrid,
  56. },
  57. props: {
  58. meta: { type: Array, required: true },
  59. readonly: Boolean /* 是否显示操作列 */,
  60. filter: { type: Boolean, default: false } /* 是否显示查询 */,
  61. action: { type: Boolean, default: false } /* 是否显操作按钮 */,
  62. paging: { type: Boolean, default: false } /* 是否显示分页 */,
  63. options: {
  64. type: Object,
  65. default: () => ({ size: 'mini' }),
  66. } /* 表格扩展属性 */,
  67. operation: Array,
  68. data: Array,
  69. total: { type: Number, default: 0 } /* 总数据条数 */,
  70. pageSize: { type: Number, default: 10 },
  71. },
  72. data() {
  73. return {
  74. page: 1,
  75. size: this.pageSize,
  76. filterData: {
  77. name: '',
  78. value: '',
  79. },
  80. };
  81. },
  82. methods: {
  83. async query() {
  84. let filter = { [this.filterData.name]: this.filterData.value };
  85. if (this.filterData.name == undefined || this.filterData.value == undefined || this.filterData.value == '') {
  86. filter = undefined;
  87. }
  88. this.$emit('query', {
  89. filter,
  90. paging: { page: this.page, size: this.size },
  91. });
  92. },
  93. handleSizeChange(val) {
  94. console.log(`每页 ${val} 条`);
  95. this.size = val;
  96. if (this.total === 0) return;
  97. const pages = Math.floor((this.total + val) / val);
  98. if (pages < this.page) this.page = pages;
  99. this.query();
  100. },
  101. handleCurrentChange(val) {
  102. console.log(`当前页: ${val}`);
  103. this.page = val;
  104. this.query();
  105. },
  106. async handleOper({ event, data }) {
  107. this.$emit(event, data);
  108. },
  109. resetPage() {
  110. this.page = 1;
  111. },
  112. },
  113. computed: {
  114. filterFields() {
  115. return this.meta
  116. .map(FieldMeta)
  117. .filter(p => p.slots.filter)
  118. .sort((a, b) => b.order - a.order)
  119. .map(p => p.field);
  120. },
  121. },
  122. };
  123. </script>
  124. <style lang="less" scoped>
  125. .container {
  126. width: 100%;
  127. height: 100%;
  128. }
  129. .el-table {
  130. height: 100%;
  131. overflow: auto;
  132. }
  133. .filter-box {
  134. width: 280px;
  135. display: inline-block;
  136. margin-right: 20px;
  137. .el-select {
  138. width: 100px;
  139. }
  140. }
  141. .el-main {
  142. padding: 10px;
  143. }
  144. // .table-area {
  145. // padding: 0;
  146. // }
  147. </style>