web-component-gallery 2.0.20 → 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.
@@ -59,5 +59,6 @@
59
59
  }
60
60
  &-body {
61
61
  flex: 1;
62
+ min-height: 0;
62
63
  }
63
64
  }
@@ -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: Array
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
- * multiple为动态多项
85
- * multipleConfig为配置的动态项数据 */
86
- <div class={props.multiple && ['MultipleForm']} {...{ attrs: { style: getFormWidth.call(this, props, this.layoutSize) } }}>
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
- dynamicModel instanceof Array && props.multiple ?
92
- dynamicModel.map( (modelItem, index) =>
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
- .then(resolve)
118
- .catch(err =>
119
- this.$nextTick(() => {
120
- const errorDiv = document.getElementsByClassName('has-error')
121
- errorDiv[0].scrollIntoView({
122
- behavior: "smooth",
123
- block: "center"
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
- /** 根据layoutSize来进行距离及大小切分 */
7
- export function getFormWidth(child, layoutSize) {
8
- if (this.layout === 'vertical')
9
- return `flex: 0 1 calc((${(100 / layoutSize) * (child.size ?? 1)}% - 24px));margin-right:24px;`
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
- /** node.placeholder与组件内的提示文字位置不对等 */
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
- (node.label || '')
34
+ (node.label || '')
22
35
 
23
- const rules = [
36
+ // 基础规则
37
+ const baseRules = [
24
38
  {
25
39
  required,
26
40
  message,
27
- trigger: ['change', 'blur']
41
+ trigger: ['change', 'blur']
28
42
  }
29
- ].concat(
30
- (node.rules || []).filter(i => {
31
- i.pattern && (i.pattern = new RegExp(i.pattern))
32
- return i
33
- }))
43
+ ]
34
44
 
35
- return rules
45
+ // 合并自定义规则
46
+ const customRules = (node.rules || []).filter(rule => {
47
+ if (rule.pattern) {
48
+ rule.pattern = new RegExp(rule.pattern)
49
+ }
50
+ return rule
51
+ })
52
+
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
- let formItemAttrs =
44
- childAttrs ??
45
- {
46
- key: child.model,
47
- prop: child.model,
48
- colon: !(layout == 'inline')
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
- const slotsName =
52
- (childAttrs?.parentModel ?? '') + child.model
77
+ // 渲染标签
78
+ const renderLabel = customLabel =>
79
+ customLabel ? customLabel(vModel) : <span>{child.label}</span>
53
80
 
54
- const {label, customLabel} = child
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
- {/* 当前表单项可slot进行单独开发配置 (目前仅支持非动态增减情况) */}
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
  )
@@ -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
- 20 // 浮动空间缓冲
200
- /** 20为获取高度时抹掉的小数点后两位的浮动空间(存在叠加多个获取错误的情况) */
199
+ 24 // 浮动空间缓冲
200
+ /** 24为获取高度时抹掉的小数点后两位的浮动空间(存在叠加多个获取错误的情况) */
201
201
  },
202
202
  /** 根据高度判断dom元素是否加载 进行删除 */
203
203
  removeDomElement() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-component-gallery",
3
- "version": "2.0.20",
3
+ "version": "2.0.22",
4
4
  "description": "基础vue、antdvue、less实现的私有组件库",
5
5
  "main": "dist/index.umd.js",
6
6
  "files": [