@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,164 @@
1
+ <!-- 弹窗 -->
2
+ <template>
3
+ <el-dialog
4
+ :class="fullscreen ? 'cover-screen-dialog' : ''"
5
+ class="d-dialog"
6
+ v-bind="$attrs"
7
+ :close-on-click-modal="closeOnClickModal"
8
+ :visible.sync="visible"
9
+ :width="width"
10
+ v-on="$listeners"
11
+ @closed="closed"
12
+ >
13
+ <template slot="title">
14
+ <slot name="title" />
15
+ </template>
16
+ <slot />
17
+ <template slot="footer">
18
+ <slot name="footer" />
19
+ <div v-if="showButton" class="ar">
20
+ <el-button
21
+ type="primary"
22
+ :icon="submitBtnIcon"
23
+ :loading="loading"
24
+ @click="submit"
25
+ >
26
+ {{ submitBtnText }}
27
+ </el-button>
28
+ <el-button @click="cancel">
29
+ {{ cancelBtnText }}
30
+ </el-button>
31
+ </div>
32
+ </template>
33
+ </el-dialog>
34
+ </template>
35
+
36
+ <script>
37
+ export default {
38
+ name: 'DDialog',
39
+ components: {},
40
+ model: {
41
+ prop: 'modelValue',
42
+ event: 'change'
43
+ },
44
+ props: {
45
+ modelValue: {
46
+ type: Boolean,
47
+ default: false
48
+ },
49
+ closeOnClickModal: {
50
+ type: Boolean,
51
+ default: false
52
+ },
53
+ showButton: {
54
+ type: Boolean,
55
+ default: true
56
+ },
57
+ submitBtnText: {
58
+ type: String,
59
+ default: '确定'
60
+ },
61
+ submitBtnIcon: {
62
+ type: String,
63
+ default: ''
64
+ },
65
+ cancelBtnText: {
66
+ type: String,
67
+ default: '取消'
68
+ },
69
+ // 需要重置的表单ref
70
+ formRefs: {
71
+ type: [String, Array],
72
+ default: ''
73
+ },
74
+ width: {
75
+ type: String,
76
+ default: '70%'
77
+ },
78
+ maxWidth: {
79
+ type: String,
80
+ default: '70%'
81
+ },
82
+ // 是否高度撑满
83
+ fullscreen: {
84
+ type: Boolean,
85
+ default: false
86
+ }
87
+ },
88
+ data () {
89
+ return {
90
+ loading: false
91
+ }
92
+ },
93
+ computed: {
94
+ visible: {
95
+ get () {
96
+ return this.modelValue
97
+ },
98
+ set (value) {
99
+ this.$emit('change', value)
100
+ }
101
+ }
102
+ },
103
+ methods: {
104
+ async submit () {
105
+ // 是否需要进行表单校验
106
+ if (this.formRefs) {
107
+ // 多表单校验
108
+ if (Array.isArray(this.formRefs)) {
109
+ await Promise.all(this.formRefs.map(ref => this.$parent.$refs[ref] && this.$parent.$refs[ref].validate()))
110
+ } else {
111
+ this.$parent.$refs[this.formRefs] && (await this.$parent.$refs[this.formRefs].validate())
112
+ }
113
+ }
114
+ this.loading = true
115
+ this.$emit('submit', (status) => {
116
+ this.loading = false
117
+ if (!status) {
118
+ this.visible = false
119
+ }
120
+ })
121
+ },
122
+ cancel () {
123
+ this.$emit('cancel')
124
+ this.visible = false
125
+ },
126
+ /**
127
+ * @description: 弹窗关闭时清楚表单校验
128
+ */
129
+ closed () {
130
+ this.$emit('closed')
131
+ if (this.formRefs) {
132
+ // 多表单校验
133
+ if (Array.isArray(this.formRefs)) {
134
+ this.formRefs.forEach(ref => this.$parent.$refs[ref] && this.$parent.$refs[ref].resetFields())
135
+ } else {
136
+ this.$parent.$refs[this.formRefs] && this.$parent.$refs[this.formRefs].resetFields()
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ </script>
143
+ <style lang="scss" scoped>
144
+ .d-dialog {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ :deep(.el-dialog) {
149
+ max-height: 90vh;
150
+ display: flex;
151
+ flex-direction: column;
152
+ margin: 0 !important;
153
+ .el-dialog__body {
154
+ flex: 1;
155
+ overflow: auto;
156
+ }
157
+ }
158
+ }
159
+ .cover-screen-dialog {
160
+ :deep(.el-dialog) {
161
+ height: 90vh;
162
+ }
163
+ }
164
+ </style>
@@ -0,0 +1,99 @@
1
+ <!-- 二次确认弹窗 -->
2
+ <template>
3
+ <div class="inline">
4
+ <span
5
+ v-if="button === 'text'"
6
+ slot="reference"
7
+ :class="`${buttonType || 'primary'}-text-btn ${disabled ? 'disabled': ''}`"
8
+ @click="() => { visible = true }"
9
+ >
10
+ {{ buttonName }}
11
+ </span>
12
+ <el-button
13
+ v-else
14
+ :disabled="disabled"
15
+ :icon="buttonIcon"
16
+ :type="buttonType"
17
+ @click="() => { visible = true }"
18
+ >
19
+ {{ buttonName }}
20
+ </el-button>
21
+ <d-dialog
22
+ v-model="visible"
23
+ :title="title"
24
+ width="374px"
25
+ append-to-body
26
+ @submit="submit"
27
+ >
28
+ <div class="d-dialog-confirm-container">
29
+ <i class="el-icon-warning" />
30
+ <p class="d-dialog-confirm-content">
31
+ <slot>您确定删除该信息?</slot>
32
+ </p>
33
+ </div>
34
+ </d-dialog>
35
+ </div>
36
+ </template>
37
+
38
+ <script>
39
+ import DDialog from '../dialog'
40
+
41
+ export default {
42
+ name: 'DDialogConfirm',
43
+ components: { DDialog },
44
+ props: {
45
+ buttonName: {
46
+ default: '批量删除',
47
+ type: String
48
+ },
49
+ buttonIcon: {
50
+ default: '',
51
+ type: String
52
+ },
53
+ buttonType: {
54
+ default: '',
55
+ type: String
56
+ },
57
+ title: {
58
+ default: '提示',
59
+ type: String
60
+ },
61
+ disabled: {
62
+ default: false,
63
+ type: Boolean
64
+ },
65
+ button: {
66
+ default: 'button',
67
+ type: String
68
+ }
69
+ },
70
+ data () {
71
+ return {
72
+ visible: false
73
+ }
74
+ },
75
+ methods: {
76
+ submit (callback) {
77
+ this.$emit('submit', callback)
78
+ }
79
+ }
80
+ }
81
+ </script>
82
+
83
+ <style lang="scss" scoped>
84
+ .d-dialog-confirm-container {
85
+ display: flex;
86
+ align-items: center;
87
+ & > i {
88
+ font-size: 28px;
89
+ color: rgb(255, 153, 0);
90
+ margin-right: 8px;
91
+ }
92
+ & > div {
93
+ flex: 1;
94
+ }
95
+ .d-dialog-confirm-content {
96
+ white-space: normal;
97
+ }
98
+ }
99
+ </style>
@@ -0,0 +1,127 @@
1
+ <!-- 抽屉 -->
2
+ <template>
3
+ <el-drawer
4
+ v-bind="$attrs"
5
+ :close-on-click-modal="false"
6
+ :visible.sync="visible"
7
+ :size="width"
8
+ v-on="$listeners"
9
+ @closed="closed"
10
+ >
11
+ <template slot="title">
12
+ <slot name="title" />
13
+ </template>
14
+ <div class="flex-col hf">
15
+ <div class="flex-1">
16
+ <slot />
17
+ </div>
18
+ <div v-if="showButton" class="ar mt16">
19
+ <el-button
20
+ type="primary"
21
+ :icon="submitBtnIcon"
22
+ :loading="loading"
23
+ @click="submit"
24
+ >
25
+ {{ submitBtnText }}
26
+ </el-button>
27
+ <el-button @click="cancel">
28
+ {{ cancelBtnText }}
29
+ </el-button>
30
+ </div>
31
+ </div>
32
+ </el-drawer>
33
+ </template>
34
+
35
+ <script>
36
+ export default {
37
+ name: 'DDrawer',
38
+ components: {},
39
+ model: {
40
+ prop: 'modelValue',
41
+ event: 'change'
42
+ },
43
+ props: {
44
+ modelValue: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ showButton: {
49
+ type: Boolean,
50
+ default: true
51
+ },
52
+ submitBtnText: {
53
+ type: String,
54
+ default: '确定'
55
+ },
56
+ submitBtnIcon: {
57
+ type: String,
58
+ default: ''
59
+ },
60
+ cancelBtnText: {
61
+ type: String,
62
+ default: '取消'
63
+ },
64
+ // 需要重置的表单ref
65
+ formRefs: {
66
+ type: [String, Array],
67
+ default: ''
68
+ },
69
+ width: {
70
+ type: String,
71
+ default: '70%'
72
+ }
73
+ },
74
+ data () {
75
+ return {
76
+ loading: false
77
+ }
78
+ },
79
+ computed: {
80
+ visible: {
81
+ get () {
82
+ return this.modelValue
83
+ },
84
+ set (value) {
85
+ this.$emit('change', value)
86
+ }
87
+ }
88
+ },
89
+ methods: {
90
+ async submit () {
91
+ // 是否需要进行表单校验
92
+ if (this.formRefs) {
93
+ // 多表单校验
94
+ if (Array.isArray(this.formRefs)) {
95
+ await Promise.all(this.formRefs.map(ref => this.$parent.$refs[ref] && this.$parent.$refs[ref].validate()))
96
+ } else {
97
+ this.$parent.$refs[this.formRefs] && (await this.$parent.$refs[this.formRefs].validate())
98
+ }
99
+ }
100
+ this.loading = true
101
+ this.$emit('submit', (status) => {
102
+ this.loading = false
103
+ if (!status) {
104
+ this.visible = false
105
+ }
106
+ })
107
+ },
108
+ cancel () {
109
+ this.$emit('cancel')
110
+ this.visible = false
111
+ },
112
+ /**
113
+ * @description: 弹窗关闭时清楚表单校验
114
+ */
115
+ closed () {
116
+ if (this.formRefs) {
117
+ // 多表单校验
118
+ if (Array.isArray(this.formRefs)) {
119
+ this.formRefs.forEach(ref => this.$parent.$refs[ref] && this.$parent.$refs[ref].resetFields())
120
+ } else {
121
+ this.$parent.$refs[this.formRefs] && this.$parent.$refs[this.formRefs].resetFields()
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ </script>
@@ -0,0 +1,277 @@
1
+ <template>
2
+ <div
3
+ v-if="visible && fileArr.length"
4
+ class="container"
5
+ >
6
+ <div
7
+ id="left"
8
+ class="left"
9
+ >
10
+ <el-tabs
11
+ v-model="activeTab"
12
+ @tab-click="handleTabClick"
13
+ >
14
+ <el-tab-pane
15
+ v-for="(v, i) in fileList"
16
+ :key="i"
17
+ :label="v.name"
18
+ :name="v.type"
19
+ />
20
+ </el-tabs>
21
+ <ul class="list">
22
+ <li
23
+ v-for="(url, i) in currentFileList"
24
+ :key="i"
25
+ :class="currentFileIndex === i ? 'active_left' : ''"
26
+ @click="handleClickLeft(url, i)"
27
+ >
28
+ <el-image
29
+ style="width: 140px; height: 140px"
30
+ :src="getUrl(url)"
31
+ fit="cover"
32
+ />
33
+ </li>
34
+ </ul>
35
+ </div>
36
+ <el-image-viewer
37
+ v-show="activeTab === 'image'"
38
+ ref="viewer"
39
+ :mask-closable="false"
40
+ :append-to-body="false"
41
+ :url-list="[activeTab === 'image' ? currentFileList[currentFileIndex] : '']"
42
+ :on-close="close"
43
+ />
44
+ <div
45
+ v-show="activeTab !== 'image'"
46
+ class="box"
47
+ >
48
+ <span
49
+ class="el-image-viewer__btn el-image-viewer__close"
50
+ @click="close"
51
+ >
52
+ <i class="el-icon-close" />
53
+ </span>
54
+ <audio
55
+ v-show="activeTab === 'audio'"
56
+ controls
57
+ style="width: 60%"
58
+ >
59
+ <source :src="currentFileList[currentFileIndex]">
60
+ 您的浏览器不支持 audio 元素。
61
+ </audio>
62
+ <video
63
+ v-show="activeTab === 'video'"
64
+ controls
65
+ style="min-width: 80%;max-height: 90%"
66
+ >
67
+ <source :src="currentFileList[currentFileIndex]">
68
+ 您的浏览器不支持 HTML5 video 标签。
69
+ </video>
70
+ </div>
71
+ </div>
72
+ </template>
73
+
74
+ <script>
75
+ import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
76
+ const imgExts = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'svg']
77
+ const videoExts = ['mp4']
78
+ const audioExts = ['mp3', 'wav', 'ogg']
79
+ export default {
80
+ name: 'DFilePreview',
81
+ components: { ElImageViewer },
82
+ model: {
83
+ prop: 'value',
84
+ event: 'change'
85
+ },
86
+ props: {
87
+ value: {
88
+ type: Boolean,
89
+ default: false
90
+ },
91
+ fileArr: {
92
+ type: Array,
93
+ default: () => {
94
+ return [
95
+ { name: '图片', type: 'image', urls: [] },
96
+ { name: '视频', type: 'video', urls: [] },
97
+ { name: '音频', type: 'audio', urls: [] }
98
+ ]
99
+ }
100
+ }
101
+ },
102
+ data () {
103
+ return {
104
+ fileList: [],
105
+ currentFileIndex: 0,
106
+ activeTab: ''
107
+ }
108
+ },
109
+ computed: {
110
+ currentFileList () {
111
+ return this.fileList.find(item => item.type === this.activeTab)?.urls || []
112
+ },
113
+ visible: {
114
+ get () {
115
+ return this.value
116
+ },
117
+ set (value) {
118
+ this.removeEventFun()
119
+ this.$emit('change', value)
120
+ }
121
+ }
122
+ },
123
+ watch: {
124
+ fileArr: {
125
+ handler (val) {
126
+ if (val.length && typeof (val[0]) === 'string') {
127
+ let arr = [
128
+ { name: '图片', type: 'image', urls: [] },
129
+ { name: '视频', type: 'video', urls: [] },
130
+ { name: '音频', type: 'audio', urls: [] }
131
+ ]
132
+ val.map(url => {
133
+ if (imgExts.includes(url.substring(url.lastIndexOf('.') + 1))) {
134
+ arr[0].urls.push(url)
135
+ }
136
+ if (videoExts.includes(url.substring(url.lastIndexOf('.') + 1))) {
137
+ arr[1].urls.push(url)
138
+ }
139
+ if (audioExts.includes(url.substring(url.lastIndexOf('.') + 1))) {
140
+ arr[2].urls.push(url)
141
+ }
142
+ })
143
+ this.fileList = arr.filter(item => item.urls.length)
144
+ } else {
145
+ this.fileList = val
146
+ }
147
+ this.activeTab = this.fileList[0].type
148
+ },
149
+ immediate: true,
150
+ deep: true
151
+ }
152
+ },
153
+ mounted () {
154
+ this.addEventEventFun()
155
+ },
156
+ methods: {
157
+ deviceSupportUninstall () {
158
+ this.$refs.viewer.deviceSupportUninstall()
159
+ },
160
+ deviceSupportInstall () {
161
+ this.$refs.viewer.deviceSupportInstall()
162
+ },
163
+ addEventEventFun () {
164
+ const element = document.getElementById('left')
165
+ element.addEventListener('mouseenter', this.deviceSupportUninstall)
166
+ element.addEventListener('mouseleave', this.deviceSupportInstall)
167
+ },
168
+ removeEventFun () {
169
+ const element = document.getElementById('left')
170
+ element.removeEventListener('mouseenter', this.deviceSupportUninstall)
171
+ element.removeEventListener('mouseleave', this.deviceSupportInstall)
172
+ },
173
+ close () {
174
+ this.visible = false
175
+ },
176
+ getUrl (val) {
177
+ switch (this.activeTab) {
178
+ case 'video':
179
+ return require('./static/video.png')
180
+ case 'image':
181
+ return val
182
+ case 'audio':
183
+ return require('./static/audio.png')
184
+ default:
185
+ break
186
+ }
187
+ },
188
+ handleClickLeft (url, index) {
189
+ this.currentFileIndex = index
190
+ },
191
+ handleTabClick () {
192
+ this.currentFileIndex = 0
193
+ }
194
+ }
195
+ }
196
+ </script>
197
+
198
+ <style lang="scss" scoped>
199
+ .container {
200
+ width: 100vw;
201
+ height: 100vh;
202
+ position: fixed;
203
+ top: 0;
204
+ left: 0;
205
+ z-index: 1000;
206
+
207
+ .box {
208
+ position: fixed;
209
+ top: 0;
210
+ left: 0;
211
+ right: 0;
212
+ bottom: 0;
213
+ z-index: 1001;
214
+ padding-left: 250px;
215
+ background-color: rgba($color: #000000, $alpha: 0.5);
216
+ display: flex;
217
+ align-items: center;
218
+ justify-content: center;
219
+ }
220
+
221
+ .left {
222
+ position: fixed;
223
+ z-index: 3000;
224
+ width: 220px;
225
+ height: 100vh;
226
+ top: 0;
227
+ left: 0;
228
+ bottom: 0;
229
+ overflow: hidden;
230
+ padding: 12px 12px 12px 20px;
231
+ display: flex;
232
+ flex-direction: column;
233
+ background: #606266;
234
+
235
+ :deep(.el-tabs__nav-wrap::after) {
236
+ background-color: transparent;
237
+ }
238
+
239
+ :deep(.el-tabs__item) {
240
+ color: #fff;
241
+ }
242
+
243
+ :deep(.el-tabs__item.is-active) {
244
+ color: #5f9efd;
245
+ }
246
+
247
+ .list {
248
+ flex: 1;
249
+ overflow: auto;
250
+ text-align: center;
251
+ font-size: 0;
252
+
253
+ li {
254
+ margin-bottom: 7px;
255
+ border: 2px solid transparent;
256
+ margin-right: 2px;
257
+ }
258
+
259
+ .active_left {
260
+ border: 2px solid #5f9efd;
261
+ }
262
+
263
+ &::-webkit-scrollbar {
264
+ display: none;
265
+ }
266
+ }
267
+ }
268
+
269
+ :deep(.el-image-viewer__wrapper) {
270
+ left: calc(220px);
271
+ }
272
+
273
+ :deep(.el-icon-close) {
274
+ color: #fff;
275
+ }
276
+ }
277
+ </style>