web-component-gallery 2.0.21 → 2.0.22
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/dist/js.umd.js +1 -1
- package/lib/modal/style/index.less +1 -0
- package/lib/model/Model.js +61 -50
- package/lib/model/utils/render.js +74 -49
- package/lib/table/index.vue +4 -4
- package/package.json +1 -1
package/lib/model/Model.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FormModel } from 'ant-design-vue'
|
|
2
2
|
import { getFormWidth, setFormItemRule, setFormItem } from './utils/render'
|
|
3
|
+
import _ from 'lodash'
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
name: 'WModel',
|
|
@@ -31,7 +32,17 @@ export default {
|
|
|
31
32
|
}
|
|
32
33
|
},
|
|
33
34
|
/* 表单项配置 */
|
|
34
|
-
formSetting:
|
|
35
|
+
formSetting: {
|
|
36
|
+
type: Array,
|
|
37
|
+
default: () => [],
|
|
38
|
+
validator: value => {
|
|
39
|
+
return value.every(item => {
|
|
40
|
+
return typeof item === 'object' &&
|
|
41
|
+
'model' in item &&
|
|
42
|
+
'type' in item
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
35
46
|
},
|
|
36
47
|
computed: {
|
|
37
48
|
form: {
|
|
@@ -39,25 +50,13 @@ export default {
|
|
|
39
50
|
/** 校验单独赋值延迟的字段 */
|
|
40
51
|
for (const k in this.value) {
|
|
41
52
|
Object.hasOwnProperty.call(this.formRules, k) && this.$refs.FormModel?.validateField(k)
|
|
42
|
-
}
|
|
53
|
+
}
|
|
43
54
|
return this.value
|
|
44
55
|
},
|
|
45
56
|
set(value) {
|
|
46
57
|
this.$emit('Change:Model', value)
|
|
47
58
|
}
|
|
48
59
|
},
|
|
49
|
-
formAttrs() {
|
|
50
|
-
let attr = {
|
|
51
|
-
labelCol: { span: 4 },
|
|
52
|
-
wrapperCol: { span: 20 },
|
|
53
|
-
...this.$attrs
|
|
54
|
-
}
|
|
55
|
-
this.layout === 'vertical' && (
|
|
56
|
-
delete attr.labelCol,
|
|
57
|
-
delete attr.wrapperCol
|
|
58
|
-
)
|
|
59
|
-
return attr
|
|
60
|
-
},
|
|
61
60
|
filterSetting() {
|
|
62
61
|
return this.formSetting.filter(settingItem => !settingItem.hidden)
|
|
63
62
|
}
|
|
@@ -76,54 +75,66 @@ export default {
|
|
|
76
75
|
this.$emit('update:refForm', this.$refs.FormModel)
|
|
77
76
|
},
|
|
78
77
|
methods: {
|
|
79
|
-
|
|
78
|
+
getDefaultFormAttrs() {
|
|
79
|
+
return {
|
|
80
|
+
labelCol: { span: 4 },
|
|
81
|
+
wrapperCol: { span: 20 }
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
renderSingleFormItem(props) {
|
|
86
|
+
return setFormItem.call(this, h, this.form, props)
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
renderDynamicFormItems(props) {
|
|
90
|
+
return props.multipleConfig.map((configItem, key) => {
|
|
91
|
+
const childAttrs = {
|
|
92
|
+
key,
|
|
93
|
+
prop: `${props.model}.${key}.${configItem.model}`,
|
|
94
|
+
style: getFormWidth.call(this, configItem, this.layoutSize ?? props.layoutSize),
|
|
95
|
+
rules: setFormItemRule.call(this, configItem, props),
|
|
96
|
+
parentModel: props.model
|
|
97
|
+
}
|
|
98
|
+
return setFormItem.call(this, h, this.form[props.model][key], configItem, childAttrs)
|
|
99
|
+
})
|
|
100
|
+
},
|
|
101
|
+
|
|
80
102
|
setModelRender(props) {
|
|
81
103
|
const dynamicModel = this.form[props.model]
|
|
82
104
|
return (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
{/* 使用场景:添加分层提示信息及其他隔层操作 */}
|
|
105
|
+
<div
|
|
106
|
+
class={props.multiple && ['MultipleForm']}
|
|
107
|
+
{...{ attrs: { style: getFormWidth.call(this, props, this.layoutSize, props.multiple ? 24 : 0) } }}
|
|
108
|
+
>
|
|
88
109
|
{this.$scopedSlots[`${props.model}Tips`] && this.$scopedSlots[`${props.model}Tips`](props)}
|
|
89
110
|
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
props.multipleConfig.map( (configItem, key) => {
|
|
94
|
-
/** 为动态项时重新定义绑定key、prop等来进行检验 */
|
|
95
|
-
/** 目前还有一个动态项layoutSize排版问题 */
|
|
96
|
-
const childAttrs = {
|
|
97
|
-
key: index,
|
|
98
|
-
prop: `${props.model}.${index}.${configItem.model}`,
|
|
99
|
-
style: getFormWidth.call(this, configItem, this.layoutSize ?? props.layoutSize),
|
|
100
|
-
rules: setFormItemRule.call(this, configItem, props),
|
|
101
|
-
parentModel: props.model
|
|
102
|
-
}
|
|
103
|
-
return setFormItem.call(this, h, modelItem, configItem, childAttrs)
|
|
104
|
-
} )
|
|
105
|
-
) :
|
|
106
|
-
setFormItem.call(this, h, this.form, props)
|
|
111
|
+
dynamicModel instanceof Array && props.multiple
|
|
112
|
+
? this.renderDynamicFormItems(props)
|
|
113
|
+
: this.renderSingleFormItem(props)
|
|
107
114
|
}
|
|
108
|
-
{/* 使用场景:如另起一行添加其他额外信息及操作 */}
|
|
109
115
|
{this.$scopedSlots[`${props.model}Operate`] && this.$scopedSlots[`${props.model}Operate`](props)}
|
|
110
116
|
</div>
|
|
111
117
|
)
|
|
112
118
|
},
|
|
113
|
-
|
|
119
|
+
|
|
120
|
+
getFormWidth: _.memoize(function(props, layoutSize, multiple) {
|
|
121
|
+
return getFormWidth.call(this, props, layoutSize, multiple ? 24 : 0)
|
|
122
|
+
}),
|
|
123
|
+
|
|
114
124
|
formSubmit() {
|
|
115
125
|
return new Promise((resolve, reject) => {
|
|
116
126
|
this.$refs.FormModel.validate()
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
.then(resolve)
|
|
128
|
+
.catch(err => {
|
|
129
|
+
console.error('表单验证失败:', err)
|
|
130
|
+
this.$nextTick(() => {
|
|
131
|
+
const errorDiv = document.getElementsByClassName('has-error')
|
|
132
|
+
errorDiv[0].scrollIntoView({
|
|
133
|
+
behavior: "smooth",
|
|
134
|
+
block: "center"
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
})
|
|
127
138
|
})
|
|
128
139
|
}
|
|
129
140
|
},
|
|
@@ -148,4 +159,4 @@ export default {
|
|
|
148
159
|
</FormModel>
|
|
149
160
|
)
|
|
150
161
|
}
|
|
151
|
-
}
|
|
162
|
+
}
|
|
@@ -3,82 +3,107 @@ import RenderComp from '../../form-comp/RenderComp.vue'
|
|
|
3
3
|
|
|
4
4
|
const FormModelItem = FormModel.Item
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
/**
|
|
7
|
+
* 根据布局大小计算表单宽度
|
|
8
|
+
* @param {Object} child - 表单项配置
|
|
9
|
+
* @param {number} layoutSize - 一行显示的表单项数量
|
|
10
|
+
* @param {number} [gap=24] - 表单项间距
|
|
11
|
+
* @returns {string} - 计算后的CSS样式
|
|
12
|
+
*/
|
|
13
|
+
export function getFormWidth(child, layoutSize, gap = 24) {
|
|
14
|
+
if (this.layout === 'vertical') {
|
|
15
|
+
const width = (100 / layoutSize) * (child.size ?? 1)
|
|
16
|
+
return `flex: 0 1 calc(${width}% - ${gap}px); margin-right: ${gap}px;`
|
|
17
|
+
}
|
|
10
18
|
return `flex: 0 1 ${(100 / layoutSize) * (child.size ?? 1)}%;`
|
|
11
|
-
}
|
|
19
|
+
}
|
|
12
20
|
|
|
13
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* 动态设置表单项验证规则
|
|
23
|
+
* @param {Object} node - 当前表单项配置
|
|
24
|
+
* @param {Object} [nodeParent={}] - 父表单项配置
|
|
25
|
+
* @returns {Array} - 验证规则数组
|
|
26
|
+
*/
|
|
14
27
|
export function setFormItemRule(node, nodeParent = {}) {
|
|
28
|
+
// 确定是否必填
|
|
15
29
|
const required = (node.required ?? nodeParent.required ?? this.formAttrs.required) ?? true
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const message =
|
|
19
|
-
node.attrs?.placeholder ||
|
|
30
|
+
|
|
31
|
+
// 生成提示信息
|
|
32
|
+
const message = node.attrs?.placeholder ||
|
|
20
33
|
(/(select|picker|radio|upload)/.test((node.is ?? 'Input').toLowerCase()) ? '请选择' : '请输入') +
|
|
21
|
-
|
|
34
|
+
(node.label || '')
|
|
22
35
|
|
|
23
|
-
|
|
36
|
+
// 基础规则
|
|
37
|
+
const baseRules = [
|
|
24
38
|
{
|
|
25
39
|
required,
|
|
26
40
|
message,
|
|
27
|
-
trigger: ['change', 'blur']
|
|
41
|
+
trigger: ['change', 'blur']
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
// 合并自定义规则
|
|
46
|
+
const customRules = (node.rules || []).filter(rule => {
|
|
47
|
+
if (rule.pattern) {
|
|
48
|
+
rule.pattern = new RegExp(rule.pattern)
|
|
28
49
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
i.pattern && (i.pattern = new RegExp(i.pattern))
|
|
32
|
-
return i
|
|
33
|
-
}))
|
|
50
|
+
return rule
|
|
51
|
+
})
|
|
34
52
|
|
|
35
|
-
return
|
|
53
|
+
return [...baseRules, ...customRules]
|
|
36
54
|
}
|
|
37
55
|
|
|
38
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* 动态渲染表单项
|
|
58
|
+
* @param {Function} h - Vue的createElement函数
|
|
59
|
+
* @param {Object} vModel - 表单数据对象
|
|
60
|
+
* @param {Object} child - 表单项配置
|
|
61
|
+
* @param {Object} [childAttrs] - 表单项属性
|
|
62
|
+
* @returns {VNode} - 渲染结果
|
|
63
|
+
*/
|
|
39
64
|
export function setFormItem(h, vModel, child, childAttrs) {
|
|
40
|
-
|
|
41
65
|
const {layout, layoutSize, $scopedSlots} = this
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
67
|
+
// 设置表单项属性
|
|
68
|
+
const formItemAttrs = childAttrs ?? {
|
|
69
|
+
key: child.model,
|
|
70
|
+
prop: child.model,
|
|
71
|
+
colon: !(layout === 'inline')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 生成插槽名称
|
|
75
|
+
const slotsName = (childAttrs?.parentModel ?? '') + child.model
|
|
50
76
|
|
|
51
|
-
|
|
52
|
-
|
|
77
|
+
// 渲染标签
|
|
78
|
+
const renderLabel = customLabel =>
|
|
79
|
+
customLabel ? customLabel(vModel) : <span>{child.label}</span>
|
|
53
80
|
|
|
54
|
-
|
|
81
|
+
// 渲染表单项内容
|
|
82
|
+
const renderContent = () => {
|
|
83
|
+
if ($scopedSlots[child.model]) {
|
|
84
|
+
return $scopedSlots[child.model](child)
|
|
85
|
+
}
|
|
86
|
+
return (
|
|
87
|
+
<RenderComp
|
|
88
|
+
v-model={vModel[child.model]}
|
|
89
|
+
component={child.is}
|
|
90
|
+
{...{ on: child.event, attrs: child.attrs }}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
55
94
|
|
|
56
95
|
return (
|
|
57
96
|
<FormModelItem
|
|
58
97
|
class={[
|
|
59
|
-
{ FormLineVertical: child.size === layoutSize && layout === 'vertical' },
|
|
60
|
-
{ FormLine: child.size === layoutSize }
|
|
98
|
+
{ 'FormLineVertical': child.size === layoutSize && layout === 'vertical' },
|
|
99
|
+
{ 'FormLine': child.size === layoutSize }
|
|
61
100
|
]}
|
|
62
101
|
{...{ attrs: formItemAttrs }}
|
|
63
102
|
>
|
|
64
103
|
<template slot="label">
|
|
65
|
-
{
|
|
66
|
-
customLabel ?
|
|
67
|
-
customLabel(vModel) :
|
|
68
|
-
<span>{label}</span>
|
|
69
|
-
}
|
|
104
|
+
{renderLabel(child.customLabel)}
|
|
70
105
|
</template>
|
|
71
|
-
{
|
|
72
|
-
{$scopedSlots[child.model] ? (
|
|
73
|
-
$scopedSlots[child.model](child)
|
|
74
|
-
) : (
|
|
75
|
-
<RenderComp
|
|
76
|
-
v-model={vModel[child.model]}
|
|
77
|
-
component={child.is}
|
|
78
|
-
{...{ on: child.event, attrs: child.attrs }}
|
|
79
|
-
/>
|
|
80
|
-
)}
|
|
81
|
-
{/* 如若再某个model后需添加按钮等场景(例如地图的选址按钮 */}
|
|
106
|
+
{renderContent()}
|
|
82
107
|
{$scopedSlots[`${slotsName}Handle`] && $scopedSlots[`${slotsName}Handle`](formItemAttrs)}
|
|
83
108
|
</FormModelItem>
|
|
84
109
|
)
|
package/lib/table/index.vue
CHANGED
|
@@ -153,11 +153,11 @@ export default {
|
|
|
153
153
|
},
|
|
154
154
|
watch: {
|
|
155
155
|
paginationParams(newValue) {
|
|
156
|
-
this.pagination = { ...newValue }
|
|
156
|
+
this.pagination = { ...this.pagination, ...newValue }
|
|
157
157
|
}
|
|
158
158
|
},
|
|
159
159
|
mounted() {
|
|
160
|
-
this.pagination = { ...this.paginationParams }
|
|
160
|
+
this.pagination = { ...this.pagination, ...this.paginationParams }
|
|
161
161
|
// 监听父级高度
|
|
162
162
|
this.initResizeObserver()
|
|
163
163
|
const scrollTimer = setTimeout(() => {
|
|
@@ -196,8 +196,8 @@ export default {
|
|
|
196
196
|
16 - // 基础间距
|
|
197
197
|
tableTitleHeight -
|
|
198
198
|
headerHeight -
|
|
199
|
-
|
|
200
|
-
/**
|
|
199
|
+
24 // 浮动空间缓冲
|
|
200
|
+
/** 24为获取高度时抹掉的小数点后两位的浮动空间(存在叠加多个获取错误的情况) */
|
|
201
201
|
},
|
|
202
202
|
/** 根据高度判断dom元素是否加载 进行删除 */
|
|
203
203
|
removeDomElement() {
|