Skip to content

Commit 65098be

Browse files
Create ParamsBindGrid.vue
1 parent a37dd08 commit 65098be

1 file changed

Lines changed: 249 additions & 0 deletions

File tree

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
<template>
2+
<tiny-form ref="ruleFormRef" :model="validateData" :rules="rules">
3+
<tiny-grid
4+
:data="tableData"
5+
:tree-config="{ children: 'children', indent: 6 }"
6+
>
7+
<tiny-grid-column type="index" title="序号" width="60"></tiny-grid-column>
8+
<tiny-grid-column
9+
field="prop"
10+
title="字段"
11+
width="140"
12+
tree-node
13+
></tiny-grid-column>
14+
<tiny-grid-column field="type" title="类型" width="60"></tiny-grid-column>
15+
<tiny-grid-column
16+
field="description"
17+
show-overflow
18+
title="描述"
19+
width="100"
20+
></tiny-grid-column>
21+
<tiny-grid-column field="required" title="是否必填" width="66">
22+
<template #default="data">
23+
<span>{{ data.row?.required ? "是" : "否" }}</span>
24+
</template>
25+
</tiny-grid-column>
26+
<tiny-grid-column field="modelType" title="绑定类型" width="100">
27+
<template #default="data">
28+
<tiny-select
29+
v-model="data.row.modelType"
30+
value-field="value"
31+
text-field="label"
32+
:tree-op="typeOptions"
33+
@change="data.row.bindValue = null"
34+
render-type="tree"
35+
clearable
36+
>
37+
</tiny-select>
38+
</template>
39+
</tiny-grid-column>
40+
<tiny-grid-column field="varible" title="绑定字段" width="140">
41+
<template #default="data">
42+
<tiny-form-item :prop="data.row.prop" :show-message="false">
43+
<tiny-select
44+
v-model="data.row.bindValue"
45+
value-key="value"
46+
value-field="value"
47+
text-field="label"
48+
render-type="tree"
49+
:tree-op="modelTypeChange(data.row.modelType)"
50+
@change="varibleChange"
51+
clearable
52+
>
53+
</tiny-select>
54+
</tiny-form-item>
55+
</template>
56+
</tiny-grid-column>
57+
</tiny-grid>
58+
</tiny-form>
59+
</template>
60+
61+
<script setup>
62+
import {
63+
Grid as TinyGrid,
64+
GridColumn as TinyGridColumn,
65+
Select as TinySelect,
66+
Form as TinyForm,
67+
FormItem as TinyFormItem,
68+
} from "@opentiny/vue";
69+
import { defineExpose, defineProps, ref, computed, reactive } from "vue";
70+
import { useCanvas } from "@opentiny/tiny-engine";
71+
72+
const props = defineProps({
73+
// 入参或出参数据
74+
data: {
75+
type: Object,
76+
default: [],
77+
},
78+
// 入参或出参类型标注
79+
type: String,
80+
});
81+
82+
const { getPageSchema } = useCanvas();
83+
const ruleFormRef = ref();
84+
85+
const addModelTypeToTableData = (gridData) => {
86+
gridData.forEach((item) => {
87+
item.modelType = "model";
88+
if (item.children?.length) {
89+
addModelTypeToTableData(item.children);
90+
}
91+
});
92+
};
93+
94+
const tableData = computed(() => {
95+
const gridData = [...props.data];
96+
addModelTypeToTableData(gridData);
97+
return gridData;
98+
});
99+
100+
const validateData = reactive({});
101+
102+
const rules = computed(() => {
103+
const rulesMap = {};
104+
tableData.value.forEach((item) => {
105+
if (item?.required) {
106+
rulesMap[item.prop] = [{ required: true, trigger: "blur" }];
107+
}
108+
});
109+
return rulesMap;
110+
});
111+
112+
const objectToTreeData = (state, prefix, treeData) => {
113+
const tree = treeData;
114+
Object.entries(state).forEach(([key, value]) => {
115+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
116+
tree.push({
117+
label: key,
118+
value: {
119+
type: "JSExpression",
120+
value: `${prefix}.${key}`,
121+
},
122+
children: [],
123+
});
124+
objectToTreeData(
125+
value,
126+
`${prefix}.${key}`,
127+
tree[tree.length - 1].children
128+
);
129+
} else {
130+
tree.push({
131+
label: key,
132+
value: {
133+
type: "JSExpression",
134+
value: `${prefix}.${key}`,
135+
},
136+
});
137+
}
138+
});
139+
};
140+
141+
const getModelStates = () => {
142+
const pageSchema = getPageSchema();
143+
const states = pageSchema.state;
144+
// 否则当前绑定事件的组件不是模型组件,则可以绑定任意已创建的模型state变量
145+
return Object.entries(states)
146+
.map(([key, value]) => {
147+
if (key.includes("modelState_")) {
148+
return {
149+
label: key,
150+
value: key,
151+
};
152+
}
153+
return null;
154+
})
155+
.filter((item) => !(item === null));
156+
};
157+
158+
const typeOptions = ref({
159+
data: [
160+
{
161+
value: "model",
162+
label: "模型",
163+
children: getModelStates(),
164+
},
165+
{
166+
value: "varible",
167+
label: "变量",
168+
children: [],
169+
},
170+
],
171+
});
172+
173+
const modelOptions = (modelKey) => {
174+
const pageSchema = getPageSchema();
175+
const modelState = pageSchema.state[modelKey];
176+
const treeData = [];
177+
objectToTreeData(modelState, `this.state.${modelKey}`, treeData);
178+
return treeData;
179+
};
180+
181+
const stateOptions = computed(() => {
182+
const pageSchema = getPageSchema();
183+
const treeData = [];
184+
const state = {};
185+
for (const key in pageSchema.state) {
186+
if (!key.includes("modelState_")) {
187+
state[key] = pageSchema.state[key];
188+
}
189+
}
190+
objectToTreeData(state, `this.state`, treeData);
191+
return treeData;
192+
});
193+
194+
const modelTypeChange = (type) => {
195+
if (type === "varible") {
196+
return { data: stateOptions.value };
197+
}
198+
if (type && type.includes("modelState_")) {
199+
return { data: modelOptions(type) };
200+
}
201+
return { data: [] };
202+
};
203+
204+
const varibleChange = () => {
205+
tableData.value.forEach((item) => {
206+
validateData[item.prop] = item.bindValue ?? "";
207+
});
208+
};
209+
210+
defineExpose({
211+
validateForm: () => {
212+
return ruleFormRef.value.validate().then((valid) => {
213+
return valid;
214+
});
215+
},
216+
getData: () => tableData.value,
217+
});
218+
</script>
219+
220+
<style lang="less">
221+
.tiny-grid {
222+
.tiny-grid__header,
223+
.tiny-grid__body {
224+
width: 100% !important;
225+
.tiny-grid-body__row {
226+
height: 36px;
227+
.col__treenode {
228+
border-bottom: 1px solid var(--te-common-border-divider) !important;
229+
}
230+
.tiny-grid-cell {
231+
.tiny-form-item {
232+
.tiny-form-item__content {
233+
margin: 0 !important;
234+
}
235+
}
236+
}
237+
}
238+
}
239+
.tiny-grid__empty-block {
240+
padding: 20px 0;
241+
}
242+
}
243+
.tiny-tree-node.is-leaf:not(.is-root) .tiny-tree-node__content {
244+
padding-left: 4px;
245+
.tiny-tree-node__content-left {
246+
padding: 0 6px;
247+
}
248+
}
249+
</style>

0 commit comments

Comments
 (0)