@ddwl/ddwl-ui 1.0.1

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.
Files changed (35) hide show
  1. package/.babelrc +19 -0
  2. package/README.md +92 -0
  3. package/babel.config.js +5 -0
  4. package/package.json +57 -0
  5. package/src/lib/slots/buttonGroup.vue +113 -0
  6. package/src/lib/slots/dict.vue +45 -0
  7. package/src/lib/slots/file.vue +35 -0
  8. package/src/lib/slots/icon.vue +72 -0
  9. package/src/lib/slots/index.js +11 -0
  10. package/src/main.js +59 -0
  11. package/src/packages/button/index.vue +36 -0
  12. package/src/packages/descriptions/index.vue +83 -0
  13. package/src/packages/dialog/index.vue +164 -0
  14. package/src/packages/dialog-confirm/index.vue +99 -0
  15. package/src/packages/drawer/index.vue +127 -0
  16. package/src/packages/file-preview/index.vue +277 -0
  17. package/src/packages/file-preview/static/audio.png +0 -0
  18. package/src/packages/file-preview/static/video.png +0 -0
  19. package/src/packages/filter-tree/index.vue +295 -0
  20. package/src/packages/form/index.vue +149 -0
  21. package/src/packages/form-item/index.vue +215 -0
  22. package/src/packages/import-file/index.vue +166 -0
  23. package/src/packages/menu/index.vue +66 -0
  24. package/src/packages/menu/menuItem.vue +78 -0
  25. package/src/packages/popconfirm/index.vue +39 -0
  26. package/src/packages/render/index.vue +14 -0
  27. package/src/packages/search-form/index.vue +257 -0
  28. package/src/packages/search-input/index.vue +68 -0
  29. package/src/packages/search-table/index.vue +101 -0
  30. package/src/packages/svg-icon/index.vue +43 -0
  31. package/src/packages/table/index.vue +453 -0
  32. package/src/packages/upload/index.vue +355 -0
  33. package/src/utils/index.js +77 -0
  34. package/src/utils/treeLib.js +190 -0
  35. package/vue.config.js +35 -0
@@ -0,0 +1,101 @@
1
+ <!-- 查询表格 -->
2
+ <template>
3
+ <div class="table-search-wrap">
4
+ <search-form v-model="form" :config="config.searchConfig" :search-data="searchData" v-bind="$attrs"
5
+ v-on="$listeners">
6
+ <slot />
7
+ </search-form>
8
+ <d-table ref="dTable" :request-config="requestConfig" :columns="config.columns" :data="data" v-bind="$attrs"
9
+ class="table-wrap" v-on="$listeners" />
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import { cloneDeep } from 'lodash'
15
+ import SearchForm from '../search-form/index.vue'
16
+ import DTable from '../table/index.vue'
17
+
18
+ export default {
19
+ name: 'DSearchTable',
20
+ components: { SearchForm, DTable },
21
+ props: {
22
+ config: {
23
+ type: Object,
24
+ default: () => ({
25
+ searchConfig: [],
26
+ requestConfig: {},
27
+ columns: []
28
+ })
29
+ },
30
+ data: {
31
+ type: Array,
32
+ default: () => []
33
+ }
34
+ },
35
+ data() {
36
+ return {
37
+ form: {},
38
+ complateInit: false
39
+ }
40
+ },
41
+ computed: {
42
+ requestConfig() {
43
+ const requestConfig = this.config.requestConfig
44
+ return {
45
+ ...requestConfig,
46
+ params: typeof requestConfig.params === 'function'
47
+ ? requestConfig.params(cloneDeep(this.form)) // 处理自定义参数
48
+ : {
49
+ ...this.form,
50
+ ...requestConfig.params
51
+ }
52
+ }
53
+ }
54
+ },
55
+ watch: {
56
+ config: {
57
+ handler() {
58
+ this.createFormBind()
59
+ },
60
+ deep: true,
61
+ immediate: true
62
+ }
63
+ },
64
+ created() { },
65
+ methods: {
66
+ createFormBind() {
67
+ const _form = {};
68
+ (this.config.searchConfig || []).forEach(c => {
69
+ _form[c.key] = c.defaultValue || ''
70
+ })
71
+ this.form = _form
72
+ },
73
+ search(params) {
74
+ this.$refs.dTable.search(params)
75
+ },
76
+ searchData(params = { pageNum: 1 }) {
77
+ this.$nextTick(() => {
78
+ this.search(params)
79
+ })
80
+ }
81
+ }
82
+ }
83
+ </script>
84
+ <style lang="scss" scoped>
85
+ .table-search-wrap {
86
+ height: 100%;
87
+ width: 100%;
88
+ overflow: hidden;
89
+ display: flex;
90
+ flex-direction: column;
91
+
92
+ .table-wrap {
93
+ flex: 1;
94
+ overflow: hidden;
95
+
96
+ :deep(.el-table) {
97
+ max-height: calc(100% - 52px) !important;
98
+ }
99
+ }
100
+ }
101
+ </style>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
3
+ <use :xlink:href="iconName" />
4
+ </svg>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'DSvgIcon',
10
+ props: {
11
+ icon: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ className: {
16
+ type: String,
17
+ default: ''
18
+ }
19
+ },
20
+ computed: {
21
+ iconName () {
22
+ return `#icon-${this.icon}`
23
+ },
24
+ svgClass () {
25
+ if (this.className) {
26
+ return 'svg-icon ' + this.className
27
+ } else {
28
+ return 'svg-icon'
29
+ }
30
+ }
31
+ }
32
+ }
33
+ </script>
34
+
35
+ <style lang="scss" scoped>
36
+ .svg-icon {
37
+ width: 14px;
38
+ height: 14px;
39
+ vertical-align: -0.15em;
40
+ fill: currentColor;
41
+ overflow: hidden;
42
+ }
43
+ </style>
@@ -0,0 +1,453 @@
1
+ <!-- 表格 -->
2
+ <template>
3
+ <div
4
+ :key="key"
5
+ v-loading="loading"
6
+ :class="dragable && 'drag-query-table'"
7
+ >
8
+ <el-table
9
+ ref="table"
10
+ :row-key="rowKey"
11
+ style="width: 100%"
12
+ :data="list"
13
+ :border="border"
14
+ v-bind="$attrs"
15
+ v-on="$listeners"
16
+ @select="selectChange"
17
+ @select-all="selectAllChange"
18
+ @selection-change="selectionChange"
19
+ >
20
+ <el-table-column
21
+ v-if="selection || asyncSelection"
22
+ key="selection"
23
+ type="selection"
24
+ align="center"
25
+ width="50"
26
+ />
27
+ <el-table-column
28
+ v-if="index"
29
+ key="index"
30
+ label="序号"
31
+ align="center"
32
+ width="55"
33
+ >
34
+ <template slot-scope="scope">
35
+ {{ (pageNum - 1) * pageSize + scope.$index + 1 }}
36
+ </template>
37
+ </el-table-column>
38
+ <el-table-column
39
+ v-for="column in visibleColumns"
40
+ :key="column.props"
41
+ v-bind="column"
42
+ v-on="$listeners"
43
+ >
44
+ <template slot-scope="scope">
45
+ <component
46
+ :is="column.component"
47
+ v-if="column.component"
48
+ v-bind="{ ...scope.row, ...column }"
49
+ :row="scope.row"
50
+ :index="scope.$index"
51
+ />
52
+ <column-render
53
+ v-else-if="column.render"
54
+ :scope="scope"
55
+ :render="column.render"
56
+ />
57
+ <template v-else>
58
+ {{ scope.row[column.props] }}
59
+ </template>
60
+ </template>
61
+ </el-table-column>
62
+ <el-table-column
63
+ v-if="dragable"
64
+ label=""
65
+ width="55"
66
+ align="center"
67
+ >
68
+ <svg-icon
69
+ class="table-drag-icon"
70
+ icon-class="drag"
71
+ />
72
+ </el-table-column>
73
+ </el-table>
74
+ <!-- 分页器 -->
75
+ <div
76
+ v-if="pagination"
77
+ class="d-table-footer"
78
+ >
79
+ <div>
80
+ <slot name="footer" />
81
+ </div>
82
+ <el-pagination
83
+ class="pagination"
84
+ :background="background"
85
+ :layout="layout"
86
+ :total="total"
87
+ :page-sizes="pageSizes"
88
+ :page-size="pageSize"
89
+ :current-page="pageNum"
90
+ @size-change="handleSizeChange"
91
+ @current-change="handleCurrentChange"
92
+ />
93
+ </div>
94
+ </div>
95
+ </template>
96
+
97
+ <script>
98
+ import Sortable from 'sortablejs'
99
+ import { cloneDeep } from 'lodash'
100
+ import modules from '../../lib/slots'
101
+ import ColumnRender from '../render'
102
+
103
+ export default {
104
+ name: 'DTable',
105
+ components: { ...modules, ColumnRender },
106
+ props: {
107
+ data: {
108
+ type: Array,
109
+ default: () => []
110
+ },
111
+ rowKey: {
112
+ type: String,
113
+ default: ''
114
+ },
115
+ border: {
116
+ type: Boolean,
117
+ default: true
118
+ },
119
+ // request config
120
+ requestConfig: {
121
+ type: Object,
122
+ require: false,
123
+ default: () => ({
124
+ api: () => {}, // 接口
125
+ params: {}, // 默认参数
126
+ autoRequest: true, // 是否自动请求
127
+ method: null // 自定义请求方法
128
+ })
129
+ },
130
+ layout: {
131
+ type: String,
132
+ default: 'total, sizes, prev, pager, next, jumper'
133
+ },
134
+ pageSizes: {
135
+ type: Array,
136
+ default: () => ([10, 20, 30, 50])
137
+ },
138
+ size: {
139
+ type: Number,
140
+ default: 10
141
+ },
142
+ page: {
143
+ type: Number,
144
+ default: 1
145
+ },
146
+ background: {
147
+ type: Boolean,
148
+ default: true
149
+ },
150
+ // 是否需要分页
151
+ pagination: {
152
+ default: true,
153
+ type: Boolean
154
+ },
155
+ // 是否拖拽
156
+ dragable: {
157
+ default: false,
158
+ type: Boolean
159
+ },
160
+ // 是否展示多选框
161
+ selection: {
162
+ default: false,
163
+ type: Boolean
164
+ },
165
+ // 是否跨页勾选
166
+ asyncSelection: {
167
+ default: false,
168
+ type: Boolean
169
+ },
170
+ // 默认勾选项,必须设置rowKey
171
+ defaultCheckList: {
172
+ default: () => [],
173
+ type: Array
174
+ },
175
+ // 是否展示排序列
176
+ index: {
177
+ default: false,
178
+ type: Boolean
179
+ },
180
+ // 列表项配置
181
+ columns: {
182
+ default: () => [],
183
+ type: Array
184
+ },
185
+ // 开启静态分页
186
+ staticPaging: {
187
+ default: false,
188
+ type: Boolean
189
+ }
190
+ },
191
+ data () {
192
+ return {
193
+ pageSize: 10,
194
+ pageNum: 1,
195
+ total: 0,
196
+ loading: false,
197
+ checkedList: [],
198
+ ids: [],
199
+ key: 0,
200
+ list: [],
201
+ totalList: []
202
+ }
203
+ },
204
+ computed: {
205
+ visibleColumns () {
206
+ return this.columns.filter(item => !item.hide)
207
+ }
208
+ },
209
+ watch: {
210
+ data: {
211
+ handler (val) {
212
+ if (JSON.stringify(val) === JSON.stringify(this.list)) {
213
+ return
214
+ }
215
+ this.handleRequestData(val)
216
+ if (this.dragable) {
217
+ this.$nextTick(() => {
218
+ this.initSortable()
219
+ })
220
+ }
221
+ },
222
+ deep: true,
223
+ immediate: true
224
+ },
225
+ defaultCheckList: {
226
+ handler () {
227
+ this.handleSelectionData()
228
+ },
229
+ deep: true
230
+ }
231
+ },
232
+ mounted () {
233
+ this.checkedList = this.defaultCheckList
234
+ // 如果不需要分页器,每页显示条目数设置最大
235
+ if (!this.pagination) {
236
+ this.pageSize = 9999999
237
+ }
238
+ // 注册表格拖拽
239
+ if (this.dragable) {
240
+ this.initSortable()
241
+ }
242
+ // 是否开启自动请求
243
+ if (!this.staticPaging && (this.requestConfig.autoRequest || this.requestConfig.autoRequest === undefined)) {
244
+ this.search()
245
+ }
246
+ },
247
+ methods: {
248
+ /**
249
+ * @description: 表格查询方法包装
250
+ * @param {*} param 自定义查询条件
251
+ */
252
+ async search (param = {}) {
253
+ this.loading = true
254
+ try {
255
+ if (param.pageNum) {
256
+ this.pageNum = param.pageNum
257
+ }
258
+ if (param.pageSize) {
259
+ this.pageSize = param.pageSize
260
+ }
261
+ const { total, data } = await (this.requestConfig.method || this.getData)({
262
+ pageSize: this.pageSize,
263
+ pageNum: this.pageNum,
264
+ ...this.requestConfig.params,
265
+ ...param
266
+ })
267
+ this.total = total
268
+ this.handleRequestData(data)
269
+ // eslint-disable-next-line no-empty
270
+ } catch (e) {}
271
+ this.loading = false
272
+ },
273
+ async getData (params) {
274
+ const defaultParams = typeof this.requestConfig.params === 'function' ? this.requestConfig.params() : this.requestConfig.params
275
+ const { data } = await this.requestConfig.api({ ...defaultParams, ...params })
276
+ this.total = data.total
277
+ let listData = data.list || []
278
+ if (this.requestConfig.props) {
279
+ if (this.requestConfig.props.list === null) {
280
+ listData = data
281
+ } else if (this.requestConfig.props.list) {
282
+ listData = data[this.requestConfig.props.list]
283
+ }
284
+ }
285
+ return {
286
+ total: data.total,
287
+ data: listData
288
+ }
289
+ },
290
+ /**
291
+ * @description: 处理表格接口获取的数据
292
+ */
293
+ handleRequestData (data) {
294
+ if (this.staticPaging) {
295
+ this.totalList = cloneDeep(data)
296
+ this.total = this.totalList.length
297
+ } else {
298
+ this.list = cloneDeep(data)
299
+ }
300
+
301
+ // 静态分页
302
+ if (this.staticPaging) {
303
+ this.pageNum = 1
304
+ this.calcStaticPageData()
305
+ return
306
+ }
307
+
308
+ this.$emit('loaded', this.list)
309
+
310
+ // 如果当前页码大于0且当前数据列表为空,自动返回上一页并查询
311
+ if (this.list.length === 0 && this.pageNum > 1) {
312
+ this.pageNum = this.pageNum - 1
313
+ this.search()
314
+ return
315
+ }
316
+ // 跨页勾选逻辑
317
+ if (this.asyncSelection || this.selection) {
318
+ this.key++
319
+ this.handleSelectionData()
320
+ }
321
+ },
322
+ /**
323
+ * @description: 处理表格默认勾选
324
+ */
325
+ handleSelectionData () {
326
+ this.checkedList = this.defaultCheckList
327
+ this.$refs.table && this.$refs.table.clearSelection()
328
+ if (this.checkedList.length) {
329
+ const ids = this.checkedList.map(item => item[this.rowKey])
330
+ const rows = this.list.filter(item => ids.includes(item[this.rowKey]))
331
+ this.$nextTick(() => {
332
+ rows.forEach(row => {
333
+ this.$refs.table.toggleRowSelection(row, true)
334
+ })
335
+ })
336
+ }
337
+ },
338
+ calcStaticPageData () {
339
+ const _list = JSON.parse(JSON.stringify(this.totalList))
340
+ this.list = _list.splice((this.pageNum - 1) * this.pageSize, this.pageSize)
341
+ },
342
+ handleSizeChange (val) {
343
+ this.pageSize = val
344
+ this.pageNum = 1
345
+ this.staticPaging ? this.calcStaticPageData() : this.search()
346
+ this.$emit('page-change', { size: this.pageSize, page: this.pageNum })
347
+ },
348
+ handleCurrentChange (val) {
349
+ this.pageNum = val
350
+ this.staticPaging ? this.calcStaticPageData() : this.search()
351
+ this.$emit('page-change', { size: this.pageSize, page: this.pageNum })
352
+ },
353
+ /**
354
+ * @description: 勾选改变事件
355
+ * @param {Array} list
356
+ * @return {Array}
357
+ */
358
+ selectChange (list, row) {
359
+ if (!this.asyncSelection) {
360
+ this.$emit('select-change', list)
361
+ } else {
362
+ if (list.some(i => i[this.rowKey] === row[this.rowKey])) {
363
+ this.checkedList.push(row)
364
+ } else {
365
+ this.checkedList = this.checkedList.filter(item => item[this.rowKey] !== row[this.rowKey])
366
+ }
367
+ this.$emit('select-change', cloneDeep(this.checkedList))
368
+ }
369
+ },
370
+ selectAllChange (list) {
371
+ if (!this.asyncSelection) {
372
+ this.$emit('select-change', list)
373
+ } else {
374
+ if (list.length) {
375
+ const checkedKeys = this.checkedList.map(item => item[this.rowKey])
376
+ const newData = list.filter(item => !checkedKeys.includes(item[this.rowKey]))
377
+ this.checkedList = this.checkedList.concat(newData)
378
+ } else {
379
+ const listKeys = this.list.map(item => item[this.rowKey])
380
+ this.checkedList = this.checkedList.filter(item => !listKeys.includes(item[this.rowKey]))
381
+ }
382
+ this.$emit('select-change', cloneDeep(this.checkedList))
383
+ }
384
+ },
385
+
386
+ selectionChange () {},
387
+ /**
388
+ * @description: 清空用户的选择
389
+ */
390
+ clearSelection () {
391
+ this.checkedList = []
392
+ this.$refs.table.clearSelection()
393
+ },
394
+ /**
395
+ * @description: 改变给定值的选中状态
396
+ * @param {*} value 改变选中状态的值
397
+ * @param {*} selected 是否选中
398
+ */
399
+ toggleAsyncSelection (value, selected = false) {
400
+ this.checkedList = this.checkedList.filter(item => item[this.rowKey] !== value)
401
+ const data = this.list.find(item => item[this.rowKey] === value)
402
+ if (data) {
403
+ this.$refs.table.toggleRowSelection(data, selected)
404
+ } else {
405
+ this.$emit('select-change', this.checkedList)
406
+ }
407
+ },
408
+ /**
409
+ * @description: 表格拖拽
410
+ */
411
+ initSortable () {
412
+ const el = this.$refs.table.$el.querySelector('.el-table__body-wrapper > table > tbody')
413
+ /* eslint-disable no-new */
414
+ new Sortable(el, {
415
+ handle: '.table-drag-icon',
416
+ onEnd: (evt) => {
417
+ // 拖拽后数据位置置换
418
+ const oldList = JSON.parse(JSON.stringify(this.list))
419
+ const data = oldList.splice(evt.oldIndex, 1)
420
+ oldList.splice(evt.newIndex, 0, data[0])
421
+ this.list = oldList
422
+ // this.key++
423
+ this.$nextTick(() => {
424
+ // 改变key值table重新渲染导致拖拽功能消失,需要重新初始化sorable实例
425
+ this.initSortable()
426
+ this.handleSelectionData()
427
+ this.$emit('drag-change', this.list, evt)
428
+ })
429
+ }
430
+ })
431
+ }
432
+ }
433
+ }
434
+ </script>
435
+
436
+ <style lang="scss" scoped>
437
+ .drag-query-table {
438
+ :deep(.hover-row) {
439
+ td {
440
+ background-color: #fff;
441
+ }
442
+ }
443
+ }
444
+ .table-drag-icon {
445
+ cursor: pointer;
446
+ }
447
+ .d-table-footer {
448
+ display: flex;
449
+ align-items: center;
450
+ justify-content: space-between;
451
+ margin-top: 16px;
452
+ }
453
+ </style>