el-crud-page 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.vue ADDED
@@ -0,0 +1,341 @@
1
+ <!-- crud组件 主要用于子组件的上下文传递 -->
2
+ <!--
3
+ 搜索组件配置 queryItems 可配置
4
+ 搜索及重置事件 queryTable
5
+
6
+ 切换组件配置 tabPanes 可配置
7
+ 切换参数 tabQuery
8
+
9
+ 按钮组件配置 buttons 可配置
10
+ 右侧工具条
11
+ 表格列配置 columns 可配置
12
+ 表格数据
13
+ 分页数据
14
+ -->
15
+ <template>
16
+
17
+ <div class="el-crud">
18
+ <!-- 搜索过滤插槽 -->
19
+ <slot name="query" :queryItems="queryItems" :lineClamp="queryLineClamp" :labelWidth="queryLabelWidth"
20
+ :inputWidth="queryInputWidth" :inline="queryInline">
21
+ <query-form v-show="showSearch" v-if="queryItems && queryItems.length" :queryItems="queryItems"
22
+ :lineClamp="queryLineClamp" :label-width="queryLabelWidth" :input-width="queryInputWidth" :inline="queryInline"
23
+ @queryTable="handleQuery" />
24
+ </slot>
25
+ <div class="container-main" :class="{ pt5: tabPanes.length > 0 }">
26
+ <slot name="tabQuery">
27
+ <el-tabs class="top-tab-query" v-if="tabPanes.length > 0" :value="tabQuery.tabKey"
28
+ @tab-click="handleTabClick">
29
+ <el-tab-pane :label="item.label" :name="item.name" v-for="item in tabPanes"
30
+ :key="item.name"></el-tab-pane>
31
+ </el-tabs>
32
+ </slot>
33
+ <!-- 工具条插槽 -->
34
+ <div class="flex justify-between el-crud-toolbar">
35
+ <slot name="buttons" :selections="selections">
36
+ <div>
37
+ <el-button :size="item.size" @click="handleButtonClick(item)" v-for="item in actionButtons"
38
+ :plain="item.plain" :disabled="item.disabled" :type="item.type" :icon="item.icon">{{
39
+ item.text
40
+ }}</el-button>
41
+ </div>
42
+ </slot>
43
+ <slot name="toolbar" :columns="columns" :showSearch="showSearch">
44
+ <right-toolbar :showSearch.sync="showSearch" @queryTable="refresh" :columns="columns"
45
+ :search="!!(queryItems && queryItems.length)"></right-toolbar>
46
+ </slot>
47
+ </div>
48
+ <!-- 默认插槽 并传 data -->
49
+ <slot :data="data">
50
+ <crud-table v-loading="listLoading" size="mini" @selection-change="handleSelectionChange"
51
+ :highlightCol="highlightCol" :resizable="resizable" :border="border" :columns="columns" :data="data"
52
+ @row-action="handleRowAction" @sort-change="handleSortChange"
53
+ :default-sort="defaultSort"></crud-table>
54
+ </slot>
55
+ <!-- 分页插槽 并传 total queryParams -->
56
+ <slot name="pagination" :total="total" :pagination="pagination">
57
+ <pagination v-show="total > 0" :total="total" :page.sync="pagination.pageNum"
58
+ :limit.sync="pagination.pageSize" @pagination="refresh" />
59
+ </slot>
60
+ </div>
61
+
62
+ </div>
63
+
64
+ </template>
65
+
66
+
67
+ <script>
68
+ import CrudTable from "./table.vue";
69
+ import RightToolbar from "./rightToolbar.vue";
70
+ import QueryForm from "./queryForm.vue";
71
+ import Pagination from "./pagination.vue"
72
+ import { toLine } from "./utils";
73
+
74
+ export default {
75
+ components: {
76
+ CrudTable, RightToolbar, QueryForm, Pagination
77
+ },
78
+ name: 'Crud',
79
+ provide() {
80
+ return {
81
+ crud: this
82
+ };
83
+ },
84
+ props: {
85
+ queryParamsMethod: {
86
+ type: Function
87
+ },
88
+ columns: {
89
+ type: Array,
90
+ default: () => []
91
+ },
92
+ queryItems: {
93
+ type: Array,
94
+ default: () => []
95
+ },
96
+ queryLineClamp: {
97
+ type: Number,
98
+ default: 1
99
+ },
100
+ queryLabelWidth: {
101
+ type: Number,
102
+ default: 80
103
+ },
104
+ queryInputWidth: {
105
+ type: Number,
106
+ default: 210
107
+ },
108
+ queryInline: {
109
+ type: Boolean,
110
+ default: true
111
+ },
112
+ buttons: {
113
+ type: Array | Function,
114
+ default: () => []
115
+ },
116
+ tabPanes: {
117
+ type: Array,
118
+ default: () => []
119
+ },
120
+ defaultSort: {
121
+ type: Object,
122
+ default: () => {
123
+ return {
124
+ prop: undefined,
125
+ order: undefined
126
+ }
127
+ }
128
+ },
129
+ highlightCol: {
130
+ type: Boolean,
131
+ default: false
132
+ },
133
+ resizable: {
134
+ type: Boolean,
135
+ default: false
136
+ },
137
+ border: {
138
+ type: Boolean,
139
+ default: false
140
+ }
141
+ },
142
+ watch: {
143
+ tabPanes: {
144
+ handler(val) {
145
+ if (val.length) {
146
+
147
+ this.tabQuery.tabKey = val[0].name
148
+ }
149
+ },
150
+ deep: true,
151
+ immediate: true
152
+ },
153
+ "tabQuery.tabKey": {
154
+ handler(val) {
155
+ this.$emit("tabChange", val);
156
+ },
157
+
158
+ }
159
+ },
160
+ computed: {
161
+ actionButtons() {
162
+ let buts = this.buttons;
163
+ if (typeof buts === 'function') {
164
+ return buts(this.selections);
165
+ } else if (buts?.length) {
166
+ return buts
167
+ }
168
+ return []
169
+ }
170
+ },
171
+ data() {
172
+ return {
173
+ listLoading: false,
174
+ showSearch: true,
175
+ selections: [],
176
+ data: [],
177
+ service: { // 增删改查导出
178
+ add: null,
179
+ update: null,
180
+ delete: null,
181
+ page: null,
182
+ info: null,
183
+ list: null,
184
+ export: null,
185
+ }, // 服务
186
+ queryParams: {
187
+ // pageNum: 1,
188
+ // pageSize: 10
189
+ }, // 查询参数
190
+
191
+ tabQuery: {
192
+ tabKey: undefined
193
+ }, // 参数
194
+ filterParams: {}, // 过滤参数
195
+ pagination: {
196
+ pageNum: 1,
197
+ pageSize: 10
198
+ },
199
+ orderParams: {
200
+ orderByRowName: undefined,
201
+ orderByRule: undefined
202
+ },
203
+ total: 0,
204
+
205
+ }
206
+ },
207
+ created() {
208
+ },
209
+ methods: {
210
+ handleTabClick(tab) {
211
+ this.tabQuery.tabKey = tab.name
212
+ this.refresh()
213
+ },
214
+ handleSelectionChange(e) {
215
+ this.selections = e
216
+ },
217
+ handleQuery(query) {
218
+ this.queryParams = query;
219
+ this.refresh()
220
+ },
221
+ handleButtonClick(item) {
222
+ this.$emit("action", item.action, this.selections);
223
+ },
224
+ handleRowAction(action, scope) {
225
+ this.$emit("row-action", action, scope);
226
+ if (action === 'delete' && this.service.delete) {
227
+ this.delete(scope)
228
+ }
229
+ },
230
+ handleSortChange(column) {
231
+ this.orderParams.orderByRowName = toLine(column.prop);
232
+ if (column.order == "descending") {
233
+ this.orderParams.orderByRule = "desc";
234
+ } else if (column.order == "ascending") {
235
+ this.orderParams.orderByRule = "asc";
236
+ } else {
237
+ this.orderParams.orderByRule = undefined;
238
+ this.orderParams.orderByRowName = undefined;
239
+ }
240
+ this.refresh();
241
+ },
242
+ // 服务
243
+ setService(service) {
244
+ this.service = Object.assign(this.service, service);
245
+ },
246
+ // 设置列
247
+ setColumns(columns) {
248
+ this.columns = columns;
249
+ },
250
+ // 设置数据
251
+ setData(data) {
252
+ // this.crud.data = data;
253
+ },
254
+ // 获得查询参数
255
+ async getParams() {
256
+ const defaultSort = this.defaultSort;
257
+ let orderParams = this.orderParams;
258
+
259
+ if (!orderParams?.orderByRowName && defaultSort?.prop) {
260
+ const orderByRowName = toLine(defaultSort.prop);
261
+ let orderByRule = defaultSort.order;
262
+
263
+ if (defaultSort.order == "descending") {
264
+ orderByRule = "desc";
265
+ } else if (defaultSort.order == "ascending") {
266
+ orderByRule = "asc";
267
+ }
268
+
269
+ orderParams = {
270
+ orderByRowName,
271
+ orderByRule
272
+ }
273
+ }
274
+
275
+ let params = { ...this.queryParams, ...this.pagination, ...this.tabQuery, ...orderParams }
276
+
277
+
278
+
279
+ if (this.queryParamsMethod) {
280
+ return await this.queryParamsMethod(params);
281
+ }
282
+ return params;
283
+ },
284
+ // 刷新列表数据
285
+ async refresh() {
286
+ this.listLoading = true;
287
+ try {
288
+ const queryParams = await this.getParams();
289
+ const { code, rows, total } = await this.service.page(queryParams);
290
+ if (code === 200) {
291
+ this.data = rows;
292
+ this.total = total;
293
+ }
294
+
295
+ } catch (error) {
296
+ console.log(error);
297
+ }
298
+ this.listLoading = false;
299
+ },
300
+ // 删除
301
+ async delete({ row }) {
302
+ try {
303
+ let id = row?.id;
304
+ await this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
305
+ confirmButtonText: '确定',
306
+ cancelButtonText: '取消',
307
+ type: 'warning'
308
+ })
309
+ const { code } = await this.service.delete(id);
310
+ if (code === 200) {
311
+ this.refresh();
312
+ this.$message({
313
+ type: 'success',
314
+ message: '操作成功!'
315
+ });
316
+ }
317
+ } catch (error) {
318
+ console.log(error);
319
+
320
+ }
321
+
322
+
323
+ }
324
+
325
+ }
326
+
327
+ }
328
+
329
+ </script>
330
+
331
+ <style scoped lang="scss">
332
+ .top-tab-query {
333
+ margin-bottom: 10px;
334
+
335
+ &::v-deep {
336
+ .el-tabs__header {
337
+ margin: 0;
338
+ }
339
+ }
340
+ }
341
+ </style>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <div :class="{'hidden':hidden}" class="pagination-container">
3
+ <el-pagination
4
+ :background="background"
5
+ :current-page.sync="currentPage"
6
+ :page-size.sync="pageSize"
7
+ :layout="layout"
8
+ :page-sizes="pageSizes"
9
+ :pager-count="pagerCount"
10
+ :total="total"
11
+ v-bind="$attrs"
12
+ @size-change="handleSizeChange"
13
+ @current-change="handleCurrentChange"
14
+ />
15
+ </div>
16
+ </template>
17
+
18
+ <script>
19
+ import { scrollTo } from './utils/scroll-to'
20
+
21
+ export default {
22
+ name: 'Pagination',
23
+ props: {
24
+ total: {
25
+ required: true,
26
+ type: Number
27
+ },
28
+ page: {
29
+ type: Number,
30
+ default: 1
31
+ },
32
+ limit: {
33
+ type: Number,
34
+ default: 20
35
+ },
36
+ pageSizes: {
37
+ type: Array,
38
+ default() {
39
+ return [10, 20, 30, 50]
40
+ }
41
+ },
42
+ // 移动端页码按钮的数量端默认值5
43
+ pagerCount: {
44
+ type: Number,
45
+ default: document.body.clientWidth < 992 ? 5 : 7
46
+ },
47
+ layout: {
48
+ type: String,
49
+ default: 'total, sizes, prev, pager, next, jumper'
50
+ },
51
+ background: {
52
+ type: Boolean,
53
+ default: true
54
+ },
55
+ autoScroll: {
56
+ type: Boolean,
57
+ default: true
58
+ },
59
+ hidden: {
60
+ type: Boolean,
61
+ default: false
62
+ }
63
+ },
64
+ data() {
65
+ return {
66
+ };
67
+ },
68
+ computed: {
69
+ currentPage: {
70
+ get() {
71
+ return this.page
72
+ },
73
+ set(val) {
74
+ this.$emit('update:page', val)
75
+ }
76
+ },
77
+ pageSize: {
78
+ get() {
79
+ return this.limit
80
+ },
81
+ set(val) {
82
+ this.$emit('update:limit', val)
83
+ }
84
+ }
85
+ },
86
+ methods: {
87
+ handleSizeChange(val) {
88
+ if (this.currentPage * val > this.total) {
89
+ this.currentPage = 1
90
+ }
91
+ this.$emit('pagination', { page: this.currentPage, limit: val })
92
+ if (this.autoScroll) {
93
+ scrollTo(0, 800)
94
+ }
95
+ },
96
+ handleCurrentChange(val) {
97
+ this.$emit('pagination', { page: val, limit: this.pageSize })
98
+ if (this.autoScroll) {
99
+ scrollTo(0, 800)
100
+ }
101
+ }
102
+ }
103
+ }
104
+ </script>
105
+
106
+ <style scoped>
107
+ .pagination-container {
108
+ background: #fff;
109
+ padding: 32px 16px;
110
+ }
111
+ .pagination-container.hidden {
112
+ display: none;
113
+ }
114
+ </style>