@v2coding/ui 0.1.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.
Files changed (49) hide show
  1. package/README.md +6 -0
  2. package/dist/v2coding-ui.esm.js +10840 -0
  3. package/dist/v2coding-ui.min.js +1 -0
  4. package/dist/v2coding-ui.ssr.js +10747 -0
  5. package/package.json +54 -0
  6. package/src/components/dialog/dialog.vue +179 -0
  7. package/src/components/drawer/drawer.vue +523 -0
  8. package/src/components/exports/index.vue +53 -0
  9. package/src/components/exports/remote-exports-dialog.vue +202 -0
  10. package/src/components/field/field.autocomplete.vue +21 -0
  11. package/src/components/field/field.calendar.vue +117 -0
  12. package/src/components/field/field.cascade.vue +233 -0
  13. package/src/components/field/field.checkbox.vue +134 -0
  14. package/src/components/field/field.color.vue +24 -0
  15. package/src/components/field/field.date.vue +145 -0
  16. package/src/components/field/field.icons.vue +123 -0
  17. package/src/components/field/field.number.vue +43 -0
  18. package/src/components/field/field.radio.vue +100 -0
  19. package/src/components/field/field.rate.vue +37 -0
  20. package/src/components/field/field.rich.vue +165 -0
  21. package/src/components/field/field.select.vue +210 -0
  22. package/src/components/field/field.slider.vue +66 -0
  23. package/src/components/field/field.switch.vue +14 -0
  24. package/src/components/field/field.text.vue +66 -0
  25. package/src/components/field/field.timepicker.vue +70 -0
  26. package/src/components/field/field.timeselect.vue +24 -0
  27. package/src/components/field/field.trigger.dialog.vue +50 -0
  28. package/src/components/field/field.trigger.popover.vue +63 -0
  29. package/src/components/field/field.upload.file.vue +241 -0
  30. package/src/components/field/field.upload.image.vue +125 -0
  31. package/src/components/field/field.upload.portrait.vue +304 -0
  32. package/src/components/fill-view/index.vue +43 -0
  33. package/src/components/form/form.dialog.vue +174 -0
  34. package/src/components/form/form.drawer.vue +246 -0
  35. package/src/components/form/form.fieldset.vue +110 -0
  36. package/src/components/form/form.item.vue +213 -0
  37. package/src/components/form/form.vue +293 -0
  38. package/src/components/head-menu/index.vue +188 -0
  39. package/src/components/head-menu/menu-item.vue +84 -0
  40. package/src/components/history/index.vue +360 -0
  41. package/src/components/icon/icon.vue +63 -0
  42. package/src/components/minimize/index.vue +342 -0
  43. package/src/components/page/page.vue +43 -0
  44. package/src/components/provider/provider.vue +15 -0
  45. package/src/components/scroll-view/scroll-view.vue +384 -0
  46. package/src/components/table/column.vue +262 -0
  47. package/src/components/table/table.pagination.vue +71 -0
  48. package/src/components/table/table.select.vue +165 -0
  49. package/src/components/table/table.vue +805 -0
@@ -0,0 +1,174 @@
1
+ <template>
2
+ <ui-dialog v-bind="$attrs" v-on="dialogListeners" :buttons="false" :visible="visible" :append-to-body="appendToBody" @open="onOpen" @opened="onOpened" @closed="onClosed" @update:visible="updateVisible">
3
+ <ui-form ref="form" :fields="fields" :label-width="labelWidth" :label-position="labelPosition" :disabled="disabled" v-loading="loading" @submit="onSubmit" @ready="onReady">
4
+ <slot></slot>
5
+ <div class="action-button" v-if="disabled !== true">
6
+ <el-button size="medium" icon="el-icon-error" @click="onCancel">{{cancelText}}</el-button>
7
+ <el-button size="medium" type="primary" icon="el-icon-success" native-type="submit" :disabled="!ready" :loading="submitting">{{confirmText}}</el-button>
8
+ </div>
9
+ </ui-form>
10
+ </ui-dialog>
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ name: 'ui-form-dialog',
16
+ inheritAttrs: false,
17
+ props: {
18
+ value: {
19
+ type: Object,
20
+ default: () => ({}),
21
+ },
22
+ visible: Boolean,
23
+ method: {
24
+ type: String,
25
+ validator: (val) => ['get', 'post'].includes(val),
26
+ default: 'post',
27
+ },
28
+ url: String,
29
+ cancelText: {
30
+ type: String,
31
+ default: '取消',
32
+ },
33
+ confirmText: {
34
+ type: String,
35
+ default: '确定',
36
+ },
37
+ cancel: {
38
+ type: Function,
39
+ default: () => void 0,
40
+ },
41
+ beforeSubmit: {
42
+ type: Function,
43
+ default: () => void 0,
44
+ },
45
+ afterSubmit: {
46
+ type: Function,
47
+ default: () => void 0,
48
+ },
49
+ fields: Array,
50
+ loading: Boolean,
51
+ appendToBody: {
52
+ type: Boolean,
53
+ default: true,
54
+ },
55
+ labelWidth: String,
56
+ labelPosition: String,
57
+ disabled: {
58
+ type: Boolean,
59
+ default: undefined,
60
+ },
61
+ },
62
+ data () {
63
+ return {
64
+ ready: false,
65
+ submitting: false,
66
+ };
67
+ },
68
+ computed: {
69
+ dialogListeners () {
70
+ // submit/ready 属于当前组件自定义事件, 非 dialog 的事件
71
+ // eslint-disable-next-line
72
+ const { submit, ready, ...listeners } = this.$listeners;
73
+ return listeners;
74
+ },
75
+ },
76
+ watch: {
77
+ visible: 'onVisibleChange',
78
+ },
79
+ methods: {
80
+ onReady () {
81
+ this.ready = true;
82
+ this.$emit('ready');
83
+ },
84
+ onCancel () {
85
+ const allow = this.cancel();
86
+ if (allow === false) {
87
+ return;
88
+ }
89
+ this.updateVisible(false);
90
+ },
91
+ updateVisible (visible) {
92
+ this.$emit('update:visible', visible);
93
+ },
94
+ async onVisibleChange(visible) {
95
+ if (!visible) {
96
+ await this.$nextTick();
97
+ this.clearValidate();
98
+ }
99
+ },
100
+ submit () {
101
+ this.$refs.form.onSubmit();
102
+ },
103
+ resetValues (values) {
104
+ if (!this.$refs.form) {
105
+ return;
106
+ }
107
+ this.$refs.form.resetValues(values);
108
+ },
109
+ clearValidate () {
110
+ if (!this.$refs.form) {
111
+ return;
112
+ }
113
+ this.$refs.form.clearValidate()
114
+ },
115
+ getValues () {
116
+ if (!this.$refs.form) {
117
+ return;
118
+ }
119
+ return this.$refs.form.getValues();
120
+ },
121
+ setValues (values) {
122
+ if (!this.$refs.form) {
123
+ return;
124
+ }
125
+ this.$refs.form.setValues(values);
126
+ },
127
+ onSubmit (formData) {
128
+ if (!this.ready) {
129
+ return;
130
+ }
131
+ this.$emit('submit', { ...formData });
132
+ const allow = this.beforeSubmit(formData);
133
+ if (typeof allow === 'boolean' && allow === false) {
134
+ return;
135
+ }
136
+ if (typeof allow === 'object') {
137
+ formData = allow;
138
+ }
139
+ if (!this.url) {
140
+ return;
141
+ }
142
+ let def;
143
+ this.submitting = true;
144
+ if (this.method === 'get') {
145
+ def = this.getWithMessage(this.url, { params: formData });
146
+ } else {
147
+ def = this.postWithMessage(this.url, formData);
148
+ }
149
+ def.then((...args) => {
150
+ this.submitting = false;
151
+ this.$emit('after-submit', ...args);
152
+ }).catch((...args) => {
153
+ this.submitting = false;
154
+ return Promise.reject(...args);
155
+ });
156
+ },
157
+ onOpen () {
158
+ },
159
+ onOpened () {
160
+ },
161
+ onClosed () {
162
+ },
163
+ },
164
+ };
165
+ </script>
166
+
167
+ <style lang="scss" scoped>
168
+ .action-button {
169
+ text-align: right;
170
+ margin: 0 -20px -20px;
171
+ padding: 10px 20px;
172
+ border-top: 1px solid #e8e8e8;
173
+ }
174
+ </style>
@@ -0,0 +1,246 @@
1
+ <template>
2
+ <ui-drawer
3
+ class-name="ui-form-drawer"
4
+ v-bind="$attrs"
5
+ v-on="drawerListeners"
6
+ :value="visible"
7
+ :width="width"
8
+ :transfer="transfer"
9
+ :mask="mask"
10
+ :inner="inner"
11
+ @on-visible-change="updateVisible"
12
+ >
13
+ <div class="ui-form-drawer-wrapper" v-loading="loading">
14
+ <ui-form ref="form" :fields="fields" :disabled="disabled" :actionButton="false" @submit="onSubmit" @ready="onReady">
15
+ <slot></slot>
16
+ </ui-form>
17
+ </div>
18
+ <div class="action-button" v-if="disabled !== true">
19
+ <el-button type="primary" icon="el-icon-success" :loading="submitting" @click="submit">{{confirmText}}</el-button>
20
+ <el-button icon="el-icon-error" @click="onCancel">{{cancelText}}</el-button>
21
+ </div>
22
+ </ui-drawer>
23
+ </template>
24
+
25
+ <script>
26
+ import UiDrawer from '../drawer/drawer';
27
+
28
+ export default {
29
+ name: 'ui-form-drawer',
30
+ inheritAttrs: false,
31
+ components: {UiDrawer},
32
+ props: {
33
+ value: {
34
+ type: Object,
35
+ default: () => ({}),
36
+ },
37
+ visible: Boolean,
38
+ // 抽屉宽度。当其值不大于 100 时以百分比显示,大于 100 时为像素
39
+ width: {
40
+ type: [String, Number],
41
+ default: 500,
42
+ },
43
+ method: {
44
+ type: String,
45
+ validator: (val) => ['get', 'post'].includes(val),
46
+ default: 'post',
47
+ },
48
+ url: String,
49
+ cancelText: {
50
+ type: String,
51
+ default: '取消',
52
+ },
53
+ confirmText: {
54
+ type: String,
55
+ default: '确定',
56
+ },
57
+ cancel: {
58
+ type: Function,
59
+ default: () => void 0,
60
+ },
61
+ beforeSubmit: {
62
+ type: Function,
63
+ default: () => void 0,
64
+ },
65
+ afterSubmit: {
66
+ type: Function,
67
+ default: () => void 0,
68
+ },
69
+ fields: Array,
70
+ loading: Boolean,
71
+ // 是否将抽屉放置于 body 内
72
+ transfer: {
73
+ type: Boolean,
74
+ default: false,
75
+ },
76
+ mask: {
77
+ type: Boolean,
78
+ default: false,
79
+ },
80
+ // 是否设置抽屉在某个元素内打开,开启此属性时,应当关闭 transfer 属性
81
+ inner: {
82
+ type: Boolean,
83
+ default: true,
84
+ },
85
+ disabled: {
86
+ type: Boolean,
87
+ default: undefined,
88
+ },
89
+ },
90
+ data() {
91
+ return {
92
+ ready: false,
93
+ submitting: false,
94
+ };
95
+ },
96
+ computed: {
97
+ drawerListeners() {
98
+ // submit/ready/input 属于当前组件自定义事件, 非 drawer 的事件
99
+ // eslint-disable-next-line
100
+ const {submit, ready, input, ...listeners} = this.$listeners;
101
+ return listeners;
102
+ },
103
+ },
104
+ watch: {
105
+ visible: 'onVisibleChange',
106
+ },
107
+ methods: {
108
+ onReady() {
109
+ this.ready = true;
110
+ this.$emit('ready');
111
+ },
112
+ onCancel() {
113
+ const allow = this.cancel();
114
+ if (allow === false) {
115
+ return;
116
+ }
117
+ this.hide();
118
+ },
119
+ show() {
120
+ this.$emit('update:visible', true);
121
+ },
122
+ hide() {
123
+ this.$emit('update:visible', false);
124
+ },
125
+ submit() {
126
+ this.$refs.form.onSubmit();
127
+ },
128
+ updateVisible(visible) {
129
+ this.$emit('update:visible', visible);
130
+ },
131
+ async onVisibleChange(visible) {
132
+ if (!visible) {
133
+ await this.$nextTick();
134
+ this.clearValidate();
135
+ }
136
+ },
137
+ resetValues(values) {
138
+ if (!this.$refs.form) {
139
+ return;
140
+ }
141
+ this.$refs.form.resetValues(values);
142
+ },
143
+ getValues() {
144
+ if (!this.$refs.form) {
145
+ return;
146
+ }
147
+ return this.$refs.form.getValues();
148
+ },
149
+ setValues(values) {
150
+ if (!this.$refs.form) {
151
+ return;
152
+ }
153
+ this.$refs.form.setValues(values);
154
+ },
155
+ clearValidate (...args) {
156
+ if (!this.$refs.form) {
157
+ return;
158
+ }
159
+ this.$refs.form.clearValidate(...args)
160
+ },
161
+ onSubmit(formData) {
162
+ // if (!this.ready) {
163
+ // return;
164
+ // }
165
+ this.$emit('submit', {...formData});
166
+ const allow = this.beforeSubmit(formData);
167
+ if (allow === false) {
168
+ return;
169
+ }
170
+ if (!this.url) {
171
+ return;
172
+ }
173
+ let def;
174
+ this.submitting = true;
175
+ if (this.method === 'get') {
176
+ def = this.getWithMessage(this.url, {params: formData});
177
+ } else {
178
+ def = this.postWithMessage(this.url, formData);
179
+ }
180
+ def.then((...args) => {
181
+ this.submitting = false;
182
+ this.$emit('after-submit', ...args);
183
+ }).catch((...args) => {
184
+ this.submitting = false;
185
+ return Promise.reject(...args);
186
+ });
187
+ },
188
+ },
189
+ };
190
+ </script>
191
+
192
+ <style lang="less">
193
+ .ui-form-drawer {
194
+ display: flex;
195
+ flex-direction: column;
196
+ padding: 0;
197
+ outline: none;
198
+
199
+ .ui-drawer-body {
200
+ flex: 1;
201
+ padding: 0;
202
+ overflow: hidden;
203
+ display: flex;
204
+ flex-direction: column;
205
+
206
+ & > .el-form {
207
+ flex: 1;
208
+ overflow: auto;
209
+ }
210
+
211
+ & > .action-button {
212
+ flex: none;
213
+ }
214
+ }
215
+
216
+ .ui-form-drawer-wrapper {
217
+ flex: 1;
218
+ overflow: hidden;
219
+
220
+ .el-form {
221
+ width: 100%;
222
+ height: 100%;
223
+ overflow: auto;
224
+ padding: 16px;
225
+ box-sizing: border-box;
226
+ }
227
+ }
228
+
229
+ .action-button {
230
+ flex: none;
231
+ padding: 16px;
232
+ border-top: 1px solid #e8eaec;
233
+ display: flex;
234
+ flex-direction: row-reverse;
235
+
236
+ button + button {
237
+ margin-right: 16px;
238
+ }
239
+ }
240
+
241
+ .action-button::after {
242
+ content: '';
243
+ clear: both;
244
+ }
245
+ }
246
+ </style>
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div class="ui-form-fieldset" :class="{toggle: hasToggle, collapse: !isExpand}">
3
+ <h3 v-if="legend" class="ui-form-fieldset-legend" v-once @click="toggle">{{ legend }}</h3>
4
+ <div v-show="isExpand">
5
+ <slot />
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ export default {
12
+ name: 'ui-form-fieldset',
13
+ props: {
14
+ label: {
15
+ type: String,
16
+ default: '分组',
17
+ },
18
+ // 类似于 html fieldset 下的 legend 标签作用
19
+ legend: {
20
+ type: String,
21
+ default() {
22
+ return this.label;
23
+ },
24
+ },
25
+ /**
26
+ * 初始时是否展开
27
+ */
28
+ collapse: {
29
+ type: Boolean,
30
+ default: null,
31
+ },
32
+ },
33
+ data() {
34
+ return {
35
+ expand: !this.collapse,
36
+ };
37
+ },
38
+ computed: {
39
+ hasToggle() {
40
+ return !Object.is(null, this.collapse);
41
+ },
42
+ isExpand() {
43
+ if (!this.hasToggle) {
44
+ return true;
45
+ }
46
+ return this.expand;
47
+ },
48
+ },
49
+ methods: {
50
+ toggle() {
51
+ if (!this.hasToggle) {
52
+ return;
53
+ }
54
+ this.expand = !this.expand;
55
+ },
56
+ },
57
+ };
58
+ </script>
59
+
60
+ <style lang="less" scoped>
61
+ .ui-form-fieldset {
62
+ padding: 30px 20px 10px;
63
+ margin: 30px 0 20px;
64
+ border: 1px dashed #aaa;
65
+ border-radius: 2px;
66
+ position: relative;
67
+ &.toggle {
68
+ &.collapse {
69
+ padding: 0;
70
+ border-bottom: none;
71
+
72
+ .ui-form-fieldset-legend::after {
73
+ content: '\f107';
74
+ }
75
+ }
76
+
77
+ .ui-form-fieldset-legend {
78
+ cursor: pointer;
79
+ font-family: FontAwesome, serif;
80
+ text-rendering: auto;
81
+ -webkit-font-smoothing: antialiased;
82
+ -moz-osx-font-smoothing: grayscale;
83
+ }
84
+
85
+ .ui-form-fieldset-legend::after {
86
+ margin-left: 4px;
87
+ content: '\f106';
88
+ }
89
+ }
90
+
91
+ > .ui-form-fieldset-legend {
92
+ position: absolute;
93
+ top: -8px;
94
+ padding: 0 30px;
95
+ margin: 0;
96
+ height: 16px;
97
+ line-height: 16px;
98
+ font-size: 14px;
99
+ color: #666;
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ background: white;
103
+ user-select: none;
104
+ }
105
+
106
+ & + .ui-form-fieldset {
107
+ margin-top: 40px;
108
+ }
109
+ }
110
+ </style>