el-form-renderer-vue3 1.0.3 → 1.0.4

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.
@@ -0,0 +1,48 @@
1
+ import _kebabcase from "lodash.kebabcase";
2
+ export default function transformContent(content) {
3
+ return content.map(({ ...item }) => {
4
+ if (item.type === "group") {
5
+ item.items = transformContent(item.items);
6
+ } else {
7
+ removeDollarInKey(item);
8
+ setItemId(item);
9
+ extractRulesFromComponent(item);
10
+ // 有些旧写法是 checkboxGroup & radioGroup
11
+ // 转换字符串string为kebab case.(foo-bar)
12
+ item.type = _kebabcase(item.type);
13
+ }
14
+
15
+ return item;
16
+ });
17
+ }
18
+ // 兼容旧写法:$id、$name
19
+ function removeDollarInKey(item) {
20
+ Object.keys(item)
21
+ // 首先检查属性名是否以"$"开头,然后检查去掉"$"后的属性名是否不在对象item中。
22
+ .filter((k) => k.startsWith("$") && !(k.slice(1) in item))
23
+ // 将对象item中的k属性的值赋给item[k.slice(1)],然后删除原来的k属性,以实现将"$"去除的操作。
24
+ .forEach((k) => ((item[k.slice(1)] = item[k]), delete item[k]));
25
+ }
26
+
27
+ // 为一个对象 item 设置一个 id 属性,但只有在 item 的 id 属性不存在时才会执行。
28
+ function setItemId(item) {
29
+ if (item.id) return;
30
+ // name 是符合表单项直觉的命名; prop 是为了与 element 的 table 的 columns 匹配
31
+ item.id = item.name || item.prop;
32
+ }
33
+
34
+ // 其作用是从给定的 item 参数中提取规则并将其添加到 item.rules 属性中
35
+ export function extractRulesFromComponent(item) {
36
+ // 是否覆盖自定义组件内置的校验规则;(overrideRules:true不校验组件内规则)
37
+ if (item.overrideRules) return;
38
+ const { component } = item;
39
+
40
+ // 使用全局注册的组件暂时无法处理(处理自定义组件内的rules)
41
+ if (!component || typeof component === "string") return;
42
+ console.log(component);
43
+ const { rules = [] } = component;
44
+ item.rules = [
45
+ ...(item.rules || []),
46
+ ...(typeof rules === "function" ? rules(item) : rules),
47
+ ];
48
+ }
@@ -0,0 +1,126 @@
1
+ import _isplainobject from "lodash.isplainobject";
2
+ // var pairs = [
3
+ // ["a", 1],
4
+ // ["b", 2],
5
+ // ["c", 3],
6
+ // ];==》{ 'a': 1, 'b': 2, 'c': 3 }
7
+ import _frompairs from "lodash.frompairs";
8
+ // collect 函数接受两个参数,content 和 key,其中 content 是一个包含嵌套数据的数组,key 是要收集的键的名称。(key:options| defult)
9
+ export function collect(content, key) {
10
+ return _frompairs(
11
+ content
12
+
13
+ // 使用 map 函数对 content 数组进行映射操作。对每个数组中的元素(item)进行处理,创建一个新的对象,该对象包含三个属性:
14
+ .map((item) => ({
15
+ id: item.id,
16
+ type: item.type,
17
+ value: item.type === "group" ? collect(item.items, key) : item[key],
18
+ }))
19
+ // 函数对上一步生成的对象数组进行过滤。只保留那些满足以下条件的对象:(带有optios数据的)
20
+ .filter(
21
+ ({ type, value }) =>
22
+ value !== undefined || (type === "group" && Object.keys(value).length)
23
+ )
24
+ // 返回 [select(id),optons]
25
+ .map(({ id, value }) => [id, value])
26
+ );
27
+ }
28
+ /**
29
+ * 根据 content 中的 outputFormat 来处理 value;
30
+ * 如果 outputFormat 处理后的值是对象类型,会覆盖(Object.assign)到 value 上
31
+ */
32
+
33
+ // value 是待处理的值,content 是一个数组,strict 是一个可选的参数,默认为 false。(当 strict 为 true 时,只返回设置的表单项的值, 过滤掉冗余字段, )
34
+ export function transformOutputValue(value, content, { strict = false } = {}) {
35
+ // 参数的值创建一个新的对象 newVal,如果 strict 为 true,则创建一个空对象,否则创建一个与输入 value 一样的对象的副本。
36
+ const newVal = strict ? {} : { ...value };
37
+
38
+ Object.keys(value).forEach((id) => {
39
+ // 找出表单项
40
+ const item = content.value.find((item) => item.id === id);
41
+ if (!item) return;
42
+ // 除去多选
43
+ if (item.type !== "group") {
44
+ // 用于处理输出值,参数为对应组件返回值
45
+ // 如果处理后的值是对象类型,会覆盖(Object.assign)到整个表单的值上
46
+ if (item.outputFormat) {
47
+ const v = item.outputFormat(value[id]);
48
+ // REVIEW: 仅根据 format 后的类型来判断赋值形式,有些隐晦
49
+ // (boolean): 如果 value 为一个普通对象,那么返回 true,否则返回 false(({ 'x': 0, 'y': 0 }); (Object.create(null));)
50
+ if (_isplainobject(v)) Object.assign(newVal, v);
51
+ else newVal[id] = v;
52
+ } else {
53
+ // 如果 item 没有 outputFormat 属性,直接将 value[id] 赋值给 newVal[id]。
54
+ newVal[id] = value[id];
55
+ }
56
+ } else {
57
+ // 多选递归处理
58
+ newVal[id] = transformOutputValue(value[id], item.items, { strict });
59
+ }
60
+ });
61
+
62
+ return newVal;
63
+ }
64
+
65
+ /**
66
+ * 根据 content 中的 inputFormat 来处理 value
67
+ * inputFormat 接受的是当前层级的 value
68
+ * 复杂点在于,不管传入的 value 是否包含某表单项的 key,所有使用了 inputFormat 的项都有可能在这次 update 中被更新
69
+ */
70
+ export function transformInputValue(value, content) {
71
+ // 首先,创建了一个名为 newVal 的新对象,它是 value 的副本,以便在不修改原始数据的情况下进行操作。
72
+ const newVal = { ...value };
73
+ const processItem = (item) => {
74
+ const { id } = item;
75
+ if (item.inputFormat) {
76
+ // 对于每个 item,它检查是否存在 inputFormat 属性。如果存在,它将调用 item.inputFormat(value) 来处理 value,
77
+ // 然后将处理后的结果赋值给 newVal 的相应属性(根据 id 来确定属性名),但仅在处理后的值不为 undefined 时才会进行赋值。
78
+ const v = item.inputFormat(value);
79
+ if (v !== undefined) newVal[id] = v;
80
+ } else if (id in value) {
81
+ // 如果 item 没有 inputFormat 属性,它会检查是否 value 中存在与 item 的 id 相匹配的属性。如果存在,它会将该属性的值赋值给 newVal 的相应属性。
82
+ if (item.type !== "group") {
83
+ newVal[id] = value[id];
84
+ } else {
85
+ // 如果 item 的类型是 "group",则会递归调用 transformInputValue 函数来处理嵌套的对象。
86
+ newVal[id] = transformInputValue(value[id], item.items);
87
+ }
88
+ }
89
+ };
90
+ // 判断响应式数据的类型
91
+ const itemsToProcess = content.value || content;
92
+ itemsToProcess.forEach(processItem);
93
+ return newVal;
94
+ }
95
+
96
+ // 对 group checkbox-group初始化值修正默认为空数组
97
+ export function correctValue(value, content) {
98
+ content.forEach(({ type, id, items }) => {
99
+ switch (type) {
100
+ case "group":
101
+ if (!(id in value)) value[id] = {};
102
+ correctValue(value[id], items);
103
+ break;
104
+ case "checkbox-group":
105
+ if (!(id in value)) value[id] = [];
106
+ break;
107
+ }
108
+ });
109
+ }
110
+ /**
111
+ * 递归合并 oldV & newV,策略如下:
112
+ * 1. 如果该项的 type 不是 GROUP,直接覆盖合并到 oldV
113
+ * 2. 如果是,则递归执行步骤 1
114
+ */
115
+ export function mergeValue(oldV, newV, content) {
116
+ // 遍历 newV 对象的所有属性
117
+ Object.keys(newV).forEach((k) => {
118
+ // 对于每个属性 k,首先尝试在 content 数组中查找具有相同 id 值的项,如果找不到则使用一个空对象。
119
+ const item = content.value.find((item) => item.id === k) || {};
120
+ // 如果不是 "group" 类型, 就直接将 newV 中的属性值覆盖到 oldV 中的对应属性上,实现合并。
121
+ if (item.type !== "group") oldV[k] = newV[k];
122
+ // 如果项的类型是 "group",则递归调用这个函数 mergeValue,以进一步合并 oldV[k] 和 newV[k],并传入该项的子项数组 item.items 作为 content 参数。
123
+ else mergeValue(oldV[k], newV[k], item.items);
124
+ });
125
+ }
126
+ export function noop() {}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "el-form-renderer-vue3",
3
- "version": "1.0.3",
4
- "description": "",
3
+ "version": "1.0.4",
4
+ "description": "render form-item easily",
5
5
  "main": "el-form-renderer-vue3.es.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"