el-plus-crud 0.0.2

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 (86) hide show
  1. package/.eslintignore +18 -0
  2. package/.eslintrc.js +78 -0
  3. package/.lintstagedrc +3 -0
  4. package/.prettierrc.js +39 -0
  5. package/CHANGELOG.md +5 -0
  6. package/LICENSE +21 -0
  7. package/README.md +15 -0
  8. package/example/App.vue +79 -0
  9. package/example/assets/vue.svg +1 -0
  10. package/example/main.js +18 -0
  11. package/example/style.css +5 -0
  12. package/index.html +13 -0
  13. package/lib/components/el-plus-form/ElPlusForm.vue +744 -0
  14. package/lib/components/el-plus-form/ElPlusFormDialog.vue +107 -0
  15. package/lib/components/el-plus-form/components/ElPlusFormAutocomplete.vue +49 -0
  16. package/lib/components/el-plus-form/components/ElPlusFormBtn.vue +96 -0
  17. package/lib/components/el-plus-form/components/ElPlusFormBtns.vue +133 -0
  18. package/lib/components/el-plus-form/components/ElPlusFormCascader.vue +38 -0
  19. package/lib/components/el-plus-form/components/ElPlusFormCascaderPanel.vue +51 -0
  20. package/lib/components/el-plus-form/components/ElPlusFormCheckbox.vue +42 -0
  21. package/lib/components/el-plus-form/components/ElPlusFormCheckboxButton.vue +42 -0
  22. package/lib/components/el-plus-form/components/ElPlusFormColor.vue +38 -0
  23. package/lib/components/el-plus-form/components/ElPlusFormDate.vue +37 -0
  24. package/lib/components/el-plus-form/components/ElPlusFormDaterange.vue +44 -0
  25. package/lib/components/el-plus-form/components/ElPlusFormDatetime.vue +38 -0
  26. package/lib/components/el-plus-form/components/ElPlusFormFile.vue +47 -0
  27. package/lib/components/el-plus-form/components/ElPlusFormImage.vue +113 -0
  28. package/lib/components/el-plus-form/components/ElPlusFormInput.vue +56 -0
  29. package/lib/components/el-plus-form/components/ElPlusFormLink.vue +271 -0
  30. package/lib/components/el-plus-form/components/ElPlusFormNbinput.vue +51 -0
  31. package/lib/components/el-plus-form/components/ElPlusFormNumber.vue +107 -0
  32. package/lib/components/el-plus-form/components/ElPlusFormPassword.vue +39 -0
  33. package/lib/components/el-plus-form/components/ElPlusFormRadio.vue +42 -0
  34. package/lib/components/el-plus-form/components/ElPlusFormRate.vue +38 -0
  35. package/lib/components/el-plus-form/components/ElPlusFormSelect.vue +149 -0
  36. package/lib/components/el-plus-form/components/ElPlusFormSlider.vue +38 -0
  37. package/lib/components/el-plus-form/components/ElPlusFormStatus.vue +67 -0
  38. package/lib/components/el-plus-form/components/ElPlusFormSwitch.vue +38 -0
  39. package/lib/components/el-plus-form/components/ElPlusFormTag.vue +78 -0
  40. package/lib/components/el-plus-form/components/ElPlusFormText.vue +115 -0
  41. package/lib/components/el-plus-form/components/ElPlusFormTextarea.vue +45 -0
  42. package/lib/components/el-plus-form/components/ElPlusFormTransfer.vue +44 -0
  43. package/lib/components/el-plus-form/components/ElPlusFormTree.vue +53 -0
  44. package/lib/components/el-plus-form/components/ElPlusFormTreeSelect.vue +36 -0
  45. package/lib/components/el-plus-form/components/components/IconSelectorList.vue +92 -0
  46. package/lib/components/el-plus-form/components/components/file-icons/FileIcons.vue +135 -0
  47. package/lib/components/el-plus-form/components/components/file-icons/data/index.ts +27 -0
  48. package/lib/components/el-plus-form/components/components/file-icons/images/doc.svg +13 -0
  49. package/lib/components/el-plus-form/components/components/file-icons/images/file.svg +19 -0
  50. package/lib/components/el-plus-form/components/components/file-icons/images/jpg.svg +14 -0
  51. package/lib/components/el-plus-form/components/components/file-icons/images/pdf.svg +13 -0
  52. package/lib/components/el-plus-form/components/components/file-icons/images/png.svg +13 -0
  53. package/lib/components/el-plus-form/components/components/file-icons/images/ppt.svg +13 -0
  54. package/lib/components/el-plus-form/components/components/file-icons/images/xls.svg +13 -0
  55. package/lib/components/el-plus-form/components/index.ts +17 -0
  56. package/lib/components/el-plus-form/data/file.ts +74 -0
  57. package/lib/components/el-plus-form/images/icon/excel.png +0 -0
  58. package/lib/components/el-plus-form/images/icon/file.png +0 -0
  59. package/lib/components/el-plus-form/images/icon/pdf.png +0 -0
  60. package/lib/components/el-plus-form/images/icon/ppt.png +0 -0
  61. package/lib/components/el-plus-form/images/icon/txt.png +0 -0
  62. package/lib/components/el-plus-form/images/icon/word.png +0 -0
  63. package/lib/components/el-plus-form/images/icon/zip.png +0 -0
  64. package/lib/components/el-plus-form/mixins/index.ts +113 -0
  65. package/lib/components/el-plus-form/util/index.ts +266 -0
  66. package/lib/components/el-plus-form/util/validate.ts +310 -0
  67. package/lib/components/el-plus-table/ElPlusTable.vue +723 -0
  68. package/lib/components/el-plus-table/components/columnItem.vue +185 -0
  69. package/lib/components/el-plus-table/components/header.vue +185 -0
  70. package/lib/components/el-plus-table/components/settingColumn.vue +168 -0
  71. package/lib/components/el-plus-table/components/statisticInfo.vue +47 -0
  72. package/lib/components/el-plus-table/util/index.ts +123 -0
  73. package/lib/config/form.ts +12 -0
  74. package/lib/config/index.ts +9 -0
  75. package/lib/index.ts +29 -0
  76. package/package.json +65 -0
  77. package/public/vite.svg +1 -0
  78. package/tsconfig.json +68 -0
  79. package/types/axios.d.ts +13 -0
  80. package/types/formList.d.ts +365 -0
  81. package/types/global.d.ts +145 -0
  82. package/types/layout.d.ts +57 -0
  83. package/types/mitt.d.ts +38 -0
  84. package/types/pinia.d.ts +149 -0
  85. package/types/views.d.ts +329 -0
  86. package/vite.config.ts +68 -0
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <el-date-picker class="ElPlusFormDatetime-panel" v-bind="attrs" v-on="onEvents" type="datetime" v-model="currentValue" />
3
+ </template>
4
+ <script lang="ts">
5
+ export default {
6
+ name: 'ElPlusFormDatetime',
7
+ inheritAttrs: false,
8
+ typeName: 'datetime',
9
+ customOptions: {}
10
+ }
11
+ </script>
12
+ <script lang="ts" setup>
13
+ import { ref, useAttrs, onBeforeMount } from 'vue'
14
+ import { getAttrs, getEvents } from '../mixins'
15
+
16
+ const props = defineProps<{
17
+ modelValue?: string | number | '' | null
18
+ field: string
19
+ desc: { [key: string]: any }
20
+ formData: { [key: string]: any }
21
+ }>()
22
+
23
+ const emits = defineEmits(['update:modelValue'])
24
+ const currentValue = ref(props.modelValue)
25
+ const attrs = ref({} as any)
26
+ const onEvents = ref(getEvents(props))
27
+
28
+ emits('update:modelValue', currentValue)
29
+
30
+ onBeforeMount(async () => {
31
+ attrs.value = await getAttrs(props, { valueFormat: 'YYYY-MM-DD HH:mm:ss', ...useAttrs() })
32
+ })
33
+ </script>
34
+ <style lang="scss" scoped>
35
+ .ElPlusFormDatetime-panel {
36
+ display: flex;
37
+ }
38
+ </style>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div class="ele-form-file" :style="{ marginTop: props.modelValue && props.modelValue.length > 0 ? '10px' : '0' }">
3
+ <template v-if="props.modelValue && props.modelValue.length > 0">
4
+ <FileIcons :files="props.modelValue" showName preview />
5
+ </template>
6
+ <span v-else class="no-img-tip">暂无</span>
7
+ </div>
8
+ </template>
9
+ <script lang="ts">
10
+ export default {
11
+ name: 'ElPlusFormFile',
12
+ inheritAttrs: false,
13
+ typeName: 'file',
14
+ customOptions: {}
15
+ }
16
+ </script>
17
+ <script lang="ts" setup>
18
+ import FileIcons from './components/file-icons/FileIcons.vue'
19
+
20
+ const props = defineProps<{
21
+ modelValue?: Array<IOssInfo>
22
+ field: string
23
+ loading?: boolean
24
+ desc: { [key: string]: any }
25
+ formData: { [key: string]: any }
26
+ }>()
27
+ </script>
28
+ <style lang="scss">
29
+ .ele-form-file {
30
+ width: 100%;
31
+ display: flex;
32
+ justify-content: center;
33
+ margin-top: 10px;
34
+
35
+ .form-file-list {
36
+ display: flex;
37
+ flex-direction: column;
38
+ width: 100%;
39
+ }
40
+
41
+ .no-img-tip {
42
+ width: 100%;
43
+ color: #999999;
44
+ padding-left: 20px;
45
+ }
46
+ }
47
+ </style>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <div class="ele-form-image">
3
+ <template v-if="imagLIst && imagLIst.length > 0">
4
+ <el-image v-for="(image, i) in imagLIst" :class="desc.class" :key="image" :preview-src-list="attrs.isShowPreview === false ? null : imagLIst" :initial-index="i" :src="format.imgUrl(image)" v-bind="attrs" :style="styles" v-on="onEvents" :fit="attrs.fit || 'cover'" />
5
+ </template>
6
+ <div v-else>
7
+ <span class="no-img-tip">—</span>
8
+ </div>
9
+ </div>
10
+ </template>
11
+ <script lang="ts">
12
+ export default {
13
+ name: 'ElPlusFormImage',
14
+ inheritAttrs: false,
15
+ typeName: 'image',
16
+ customOptions: {}
17
+ }
18
+ </script>
19
+ <script lang="ts" setup>
20
+ import { ref, computed, useAttrs, onBeforeMount, inject } from 'vue'
21
+ import { getAttrs, getEvents } from '../mixins'
22
+
23
+ // 格式化
24
+ const format = inject('format') as any
25
+
26
+ const props = defineProps<{
27
+ modelValue?: Array<any> | string | null
28
+ field: string
29
+ loading?: boolean
30
+ desc: { [key: string]: any }
31
+ formData: { [key: string]: any }
32
+ }>()
33
+
34
+ const attrs = ref({} as any)
35
+ const onEvents = ref(getEvents(props))
36
+
37
+ onBeforeMount(async () => {
38
+ attrs.value = await getAttrs(props, { isShowPreview: true, previewTeleported: true, ...useAttrs() })
39
+ })
40
+
41
+ const imagLIst = computed(() => {
42
+ if (!props.modelValue) {
43
+ return []
44
+ }
45
+ if (Array.isArray(props.modelValue)) {
46
+ if (typeof props.modelValue[0] === 'string') {
47
+ return props.modelValue
48
+ } else {
49
+ return props.modelValue.map((item) => item.shareUrl || item.furl)
50
+ }
51
+ } else if (typeof props.modelValue === 'string') {
52
+ return props.modelValue.split(',').map((url) => format.imgUrl(url))
53
+ } else {
54
+ // console.log('unknown image Type.....')
55
+ }
56
+ return []
57
+ })
58
+
59
+ /**
60
+ * 格式化样式
61
+ * large,default,small
62
+ */
63
+ const styles = computed(() => {
64
+ let width = ''
65
+ let height = ''
66
+ let size = props.desc.size || 'default'
67
+ switch (size) {
68
+ case 'large':
69
+ width = '44px'
70
+ height = '44px'
71
+ break
72
+ case 'default':
73
+ width = '36px'
74
+ height = '36px'
75
+ break
76
+ case 'small':
77
+ width = '28px'
78
+ height = '28px'
79
+ break
80
+ default:
81
+ width = parseInt(size) + 'px'
82
+ height = parseInt(size) + 'px'
83
+ break
84
+ }
85
+ return Object.assign({}, props.desc.style, { width, height, 'max-width': width })
86
+ })
87
+ </script>
88
+ <style lang="scss">
89
+ .ele-form-image {
90
+ display: flex;
91
+ // justify-content: center;
92
+ flex-wrap: wrap;
93
+
94
+ .no-img-tip {
95
+ color: #999999;
96
+ }
97
+
98
+ .el-image {
99
+ margin-left: 10px;
100
+ margin-bottom: 10px;
101
+ }
102
+ }
103
+
104
+ .ele-form-image .el-image {
105
+ border-radius: 5px;
106
+ margin-bottom: 10px;
107
+
108
+ .el-image__error {
109
+ font-size: 12px;
110
+ line-height: 13px;
111
+ }
112
+ }
113
+ </style>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <el-input style="display: flex" v-bind="attrs" v-on="onEvents" v-model="currentValue">
3
+ <template v-for="(item, key, index) of slots" #[key] :key="index">
4
+ <slot :name="key" />
5
+ </template>
6
+ </el-input>
7
+ </template>
8
+ <script lang="ts">
9
+ export default {
10
+ name: 'ElPlusFormInput',
11
+ inheritAttrs: false,
12
+ typeName: 'input',
13
+ customOptions: {}
14
+ }
15
+ </script>
16
+ <script lang="ts" setup>
17
+ import { ref, watch, useAttrs, useSlots, onBeforeMount } from 'vue'
18
+ import { getAttrs, getEvents } from '../mixins'
19
+
20
+ const props = defineProps<{
21
+ modelValue?: string | null
22
+ field: string
23
+ desc: { [key: string]: any }
24
+ formData: { [key: string]: any }
25
+ }>()
26
+ const emits = defineEmits(['update:modelValue', 'validateThis'])
27
+ const slots = ref(Object.assign({}, useSlots(), props.desc.slots))
28
+ const attrs = ref({} as any)
29
+ const onEvents = ref(getEvents(props))
30
+
31
+ const currentValue = ref()
32
+ emits('update:modelValue', currentValue)
33
+
34
+ onBeforeMount(async () => {
35
+ attrs.value = await getAttrs(props, { autocomplete: 'new-password', maxlength: 20, clearable: true, ...useAttrs() })
36
+ })
37
+
38
+ watch(
39
+ () => props.modelValue,
40
+ (data: string | null | undefined) => {
41
+ // 这里要截取一下字符串长度
42
+ if (data && data.length > attrs.value.maxlength) {
43
+ data = data.substring(0, attrs.value.maxlength)
44
+ }
45
+ currentValue.value = data
46
+ },
47
+ { immediate: true }
48
+ )
49
+
50
+ watch(
51
+ () => currentValue.value,
52
+ () => {
53
+ emits('validateThis')
54
+ }
55
+ )
56
+ </script>
@@ -0,0 +1,271 @@
1
+ <template>
2
+ <div class="el-plus-form-link">
3
+ <el-select ref="selectRef" style="width: 100%" :class="desc.class" :style="desc.style" v-bind="topAttrs" :teleported="false" :loading="loading" :modelValue="values" @visible-change="handelVisibleChange" @clear="handelClear" v-on="onEvents">
4
+ <el-option v-for="option in options" :key="option.value" v-bind="option" />
5
+ </el-select>
6
+ <!-- 弹框 -->
7
+ <el-dialog :width="desc.dialogWidth || '1000px'" :title="desc.placeholder || '选择' + desc.label" draggable :closeOnClickModal="false" showCancel v-model="isShowDialog" append-to-body destroy-on-close>
8
+ <div style="width: 100%" class="form-link-dialog">
9
+ <div class="panel-left">
10
+ <!-- 左侧列表 -->
11
+ <ElPlusTable v-if="tableConfig" ref="multipleTableRef" :tableConfig="tableConfig" :type="multiple ? 'selection' : 'index'" :isIndex="false" :rowKey="vkey" @selection="handelTableSelection" />
12
+ </div>
13
+ <div v-if="multiple" class="panel-right">
14
+ <div class="right-title">已选中项:</div>
15
+ <el-scrollbar height="480px" class="tag-list">
16
+ <el-tag class="tag-item" style="margin-right: 10px; margin-bottom: 10px" v-for="tag in selectData" :key="tag.value" closable @close="() => handelTagRemove(tag)">
17
+ {{ tag.label }}
18
+ </el-tag>
19
+ </el-scrollbar>
20
+ <div class="btn-panel">
21
+ <el-button @click="cancel">取消</el-button>
22
+ <el-button type="primary" @click="submit">确定</el-button>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </el-dialog>
27
+ </div>
28
+ </template>
29
+ <script lang="ts">
30
+ export default {
31
+ name: 'ElPlusFormLink',
32
+ inheritAttrs: false,
33
+ typeName: 'link',
34
+ customOptions: {}
35
+ }
36
+ </script>
37
+ <script lang="ts" setup>
38
+ import { cloneDeep } from 'lodash'
39
+ import { ref, reactive, watch, onMounted, computed } from 'vue'
40
+ import { getEvents } from '../mixins'
41
+
42
+ interface ILinkItem {
43
+ label: string
44
+ value: string
45
+ }
46
+
47
+ const props = defineProps<{
48
+ modelValue?: any
49
+ field: string
50
+ loading?: boolean
51
+ desc: { [key: string]: any }
52
+ formData: { [key: string]: any }
53
+ }>()
54
+
55
+ const onEvents = ref(getEvents(props))
56
+
57
+ const emits = defineEmits(['update:modelValue', 'change', 'input', 'validateThis'])
58
+
59
+ const currentValue = ref(props.modelValue)
60
+ emits('update:modelValue', currentValue)
61
+
62
+ // 顶部的select
63
+ const selectRef = ref()
64
+ const values = reactive([] as any[])
65
+ const options = reactive([] as any[])
66
+ const topAttrs = reactive({
67
+ multiple: true,
68
+ size: props.desc.size,
69
+ collapseTags: true,
70
+ collapseTagsTooltip: true,
71
+ clearable: true
72
+ })
73
+
74
+ // 显示弹框
75
+ const isShowDialog = ref(false)
76
+ const tableConfig = ref({} as any)
77
+ const vkey = computed(() => (props.desc.vkey as string) || 'id')
78
+
79
+ const multiple = ref(false)
80
+
81
+ const multipleTableRef = ref()
82
+
83
+ // 存储的值
84
+ const selectData = reactive([] as ILinkItem[])
85
+
86
+ /**
87
+ * 处理点击事件
88
+ * @param val
89
+ */
90
+ function handelVisibleChange(val: any) {
91
+ if (val) {
92
+ selectRef.value.blur()
93
+ isShowDialog.value = true
94
+ }
95
+ }
96
+
97
+ /**
98
+ * 处理清空选项
99
+ */
100
+ function handelClear() {
101
+ selectData.splice(0, selectData.length)
102
+ submit()
103
+ }
104
+
105
+ /**
106
+ * 处理列表批量选中
107
+ * @param selection
108
+ */
109
+ function handelTableSelection(selection: any[]) {
110
+ // 这里全是新增
111
+ selectData.splice(0, selectData.length)
112
+ selection.map((row) => {
113
+ selectData.push({ label: row[props.desc.lkey || 'name'], value: row[vkey.value] })
114
+ })
115
+ }
116
+
117
+ /**
118
+ * 处理表格操作列单个选中
119
+ * @param btnBack
120
+ */
121
+ function handelSignleSelect({ row }: IBtnBack) {
122
+ selectData.splice(0, selectData.length)
123
+ selectData.push({ label: row[props.desc.lkey || 'name'], value: row[vkey.value] })
124
+ // 直接关闭
125
+ submit()
126
+ }
127
+
128
+ /**
129
+ * 处理删除标签
130
+ * @param item
131
+ */
132
+ function handelTagRemove(item: ILinkItem) {
133
+ selectData.splice(
134
+ selectData.findIndex((i) => i.value === item.value),
135
+ 1
136
+ )
137
+ // 通知table刷新
138
+ multipleTableRef.value.changeSelect([{ [vkey.value]: item.value }])
139
+ }
140
+
141
+ /**
142
+ * 取消按钮
143
+ */
144
+ function cancel() {
145
+ isShowDialog.value = false
146
+ }
147
+
148
+ /**
149
+ * 确认按钮
150
+ */
151
+ function submit() {
152
+ options.splice(0, options.length, ...selectData)
153
+ const tempIds = [] as string[]
154
+ values.splice(0, values.length)
155
+
156
+ // 遍历数据
157
+ selectData.map((item) => {
158
+ values.push(item.value)
159
+ tempIds.push(item.value)
160
+ })
161
+ // 设置值
162
+ currentValue.value = selectData.length > 0 ? tempIds : null
163
+
164
+ isShowDialog.value = false
165
+ emits('validateThis')
166
+ }
167
+
168
+ // 表格配置
169
+ watch(
170
+ () => props.desc.tableConfig,
171
+ (val) => {
172
+ let tempConfig = {} as ITableConfig
173
+ if (val) {
174
+ tempConfig = cloneDeep(val)
175
+ if (typeof props.desc.multiple === 'function') {
176
+ multiple.value = props.desc.multiple(props.formData)
177
+ } else {
178
+ multiple.value = props.desc.multiple
179
+ }
180
+ // 如果是多选
181
+ if (multiple.value) {
182
+ // TODO
183
+ } else if (!multiple.value && tempConfig.column[tempConfig.column.length - 1].label !== '操作') {
184
+ // 如果是单选
185
+ tempConfig.column.push({ label: '操作', width: '120px', fixed: 'right', type: 'btns', btns: [{ label: '选中', on: { click: handelSignleSelect } }] })
186
+ }
187
+ tempConfig.maxHeight = 400
188
+ }
189
+ tableConfig.value = tempConfig
190
+ },
191
+ { deep: true }
192
+ )
193
+
194
+ onMounted(async () => {})
195
+ </script>
196
+ <style lang="scss" scoped>
197
+ .el-plus-form-link {
198
+ width: 100%;
199
+
200
+ .items-panel {
201
+ :deep(.el-input__inner) {
202
+ cursor: pointer;
203
+ }
204
+ }
205
+
206
+ :deep(.el-tag__close) {
207
+ display: none !important;
208
+ }
209
+ }
210
+ </style>
211
+ <style lang="scss">
212
+ .form-link-dialog {
213
+ width: 100%;
214
+ display: flex;
215
+ box-sizing: border-box;
216
+
217
+ .panel-left {
218
+ flex: 1;
219
+ height: 500px;
220
+ display: flex;
221
+ flex-direction: column;
222
+
223
+ .dept-breadcrumb {
224
+ width: 100%;
225
+ padding: 0 10px;
226
+ margin-bottom: 20px;
227
+ cursor: pointer;
228
+ }
229
+ }
230
+
231
+ .panel-right {
232
+ // min-width: 40%;
233
+ max-width: 40%;
234
+ margin-left: 20px;
235
+ border-left: 1px var(--el-border-color) var(--el-border-style);
236
+ padding: 20px;
237
+ display: flex;
238
+ overflow: hidden;
239
+ flex-direction: column;
240
+
241
+ .right-title {
242
+ width: 100%;
243
+ font-size: 14px;
244
+ color: #999999;
245
+ margin-bottom: 20px;
246
+ }
247
+
248
+ .tag-list {
249
+ width: 100%;
250
+ height: 400px;
251
+ overflow: hidden;
252
+ .tag-item {
253
+ .el-tag__content {
254
+ max-width: 100px;
255
+ text-overflow: ellipsis;
256
+ overflow: hidden;
257
+ white-space: nowrap;
258
+ }
259
+ }
260
+ }
261
+
262
+ .btn-panel {
263
+ width: 100%;
264
+ min-height: 50px;
265
+ padding-top: 10px;
266
+ display: flex;
267
+ justify-content: center;
268
+ }
269
+ }
270
+ }
271
+ </style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <el-input :class="desc.class" :style="desc.style" :clearable="attrs.clearable ?? true" type="number" v-bind="attrs" v-on="onEvents" v-model="currentValue">
3
+ <template v-for="(item, key, index) of slots" #[key] :key="index">
4
+ <slot :name="key" />
5
+ </template>
6
+ <template v-if="desc.rtext" #append>{{ desc.rtext.text }}</template>
7
+ </el-input>
8
+ </template>
9
+ <script lang="ts">
10
+ export default {
11
+ name: 'ElPlusFormNbinput',
12
+ inheritAttrs: false,
13
+ typeName: 'nbinput',
14
+ customOptions: {}
15
+ }
16
+ </script>
17
+ <script lang="ts" setup>
18
+ import { ref, useAttrs, useSlots, onBeforeMount } from 'vue'
19
+ import { getAttrs, getEvents } from '../mixins'
20
+
21
+ const props = defineProps<{
22
+ modelValue?: string | number | '' | null
23
+ field: string
24
+ loading?: boolean
25
+ desc: { [key: string]: any }
26
+ formData: { [key: string]: any }
27
+ rowIndex?: number
28
+ }>()
29
+ const emits = defineEmits(['update:modelValue'])
30
+ const currentValue = ref(props.modelValue)
31
+ emits('update:modelValue', currentValue)
32
+
33
+ const slots = ref(Object.assign({}, useSlots(), props.desc.slots))
34
+ const attrs = ref({} as any)
35
+ const onEvents = ref(getEvents(props))
36
+
37
+ onBeforeMount(async () => {
38
+ attrs.value = await getAttrs(props, { ...useAttrs() })
39
+ })
40
+ </script>
41
+ <style lang="scss">
42
+ /*input输入框屏蔽浏览器出现上下箭头*/
43
+ input::-webkit-outer-spin-button,
44
+ input::-webkit-inner-spin-button {
45
+ -webkit-appearance: none;
46
+ }
47
+
48
+ input[type='number'] {
49
+ -moz-appearance: textfield;
50
+ }
51
+ </style>
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <el-input-number class="ElPlusFormNumber-panel" v-bind="attrs" v-on="onEvents" v-model="currentValue" onkeypress="return( /[\d\.]/.test(String.fromCharCode(event.keyCode)))" />
3
+ </template>
4
+ <script lang="ts">
5
+ export default {
6
+ name: 'ElPlusFormNumber',
7
+ inheritAttrs: false,
8
+ typeName: 'number',
9
+ customOptions: {}
10
+ }
11
+ </script>
12
+ <script lang="ts" setup>
13
+ import { ref, computed, useAttrs, onBeforeMount, nextTick } from 'vue'
14
+ import { getAttrs, getEvents } from '../mixins'
15
+ import { ElMessage } from 'element-plus'
16
+
17
+ const props = defineProps<{
18
+ modelValue?: number | null
19
+ field: string
20
+ loading?: boolean
21
+ desc: { [key: string]: any }
22
+ formData: { [key: string]: any }
23
+ rowIndex?: number
24
+ }>()
25
+ const emits = defineEmits(['update:modelValue'])
26
+ const currentValue = ref(props.modelValue)
27
+ emits('update:modelValue', currentValue)
28
+ const attrs = ref({} as any)
29
+ const onEvents = ref(getEvents(props))
30
+
31
+ onBeforeMount(async () => {
32
+ attrs.value = await getAttrs(props, { min: 0, max: 999999999, precision: 0, controlsPosition: 'right', ...useAttrs() })
33
+ delete attrs.value.min
34
+ delete attrs.value.max
35
+ })
36
+
37
+ /**
38
+ * 绑定属性
39
+ */
40
+ const numBindAttr = computed(() => {
41
+ let numAttrs = props.desc.attrs || { min: 0, max: 999999999, precision: 0, controlsPosition: 'right' }
42
+ if (typeof props.desc.attrs === 'function') {
43
+ numAttrs = props.desc.attrs(props.formData)
44
+ }
45
+ // 这里判断一下,最小和最大值的大小
46
+ if (numAttrs.min > numAttrs.max) {
47
+ numAttrs.min = numAttrs.max
48
+ } else if (numAttrs.max < numAttrs.min) {
49
+ numAttrs.max = numAttrs.min
50
+ }
51
+ return numAttrs
52
+ })
53
+
54
+ // 判断一下初始值
55
+ if (currentValue.value !== undefined && currentValue.value !== null) {
56
+ if (currentValue.value < numBindAttr.value.min) {
57
+ currentValue.value = numBindAttr.value.min
58
+ } else if (currentValue.value > numBindAttr.value.max) {
59
+ currentValue.value = numBindAttr.value.max
60
+ }
61
+ }
62
+
63
+ const change = onEvents.value.change
64
+
65
+ if (change) {
66
+ onEvents.value.change = (val: any, oldVal: any) => {
67
+ handelValChange(val, oldVal)
68
+ }
69
+ } else {
70
+ onEvents.value.change = handelValChange
71
+ }
72
+
73
+ /**
74
+ * 监听值改变
75
+ * @param val
76
+ */
77
+ function handelValChange(val: any, oldVal: any) {
78
+ if (val !== oldVal) {
79
+ if (val < numBindAttr.value.min) {
80
+ ElMessage.warning(`${props.desc?.label || ''}最少不能低于${numBindAttr.value.min}`)
81
+ nextTick(() => {
82
+ currentValue.value = numBindAttr.value.min
83
+ })
84
+ } else if (val > numBindAttr.value.max) {
85
+ ElMessage.warning(`${props.desc?.label || ''}最多不能大于${numBindAttr.value.max}`)
86
+ nextTick(() => {
87
+ currentValue.value = numBindAttr.value.max
88
+ change && change()
89
+ })
90
+ } else {
91
+ change && change()
92
+ }
93
+ }
94
+ }
95
+ </script>
96
+ <style lang="scss" scoped>
97
+ .ElPlusFormNumber-panel {
98
+ width: 100% !important;
99
+ max-width: 100%;
100
+ :deep(.el-input__wrapper) {
101
+ // padding-left: 11px !important;
102
+ input {
103
+ text-align: left !important;
104
+ }
105
+ }
106
+ }
107
+ </style>