Browse Source

Merge remote-tracking branch 'origin/master'

master
yuliang 6 months ago
parent
commit
a10a8746cd
  1. 12
      src/components/data-form/DataFormConstant.ts
  2. 45
      src/components/data-form/DataFormUtils.tsx
  3. 96
      src/components/data-form/inputs/CheckboxGroup.vue
  4. 96
      src/components/data-form/inputs/RadioGroup.vue
  5. 96
      src/components/data-form/inputs/Select.vue
  6. 5
      src/editor/propEditors/IMetaProp.ts
  7. 19
      src/pages/DataForm01.vue

12
src/components/data-form/DataFormConstant.ts

@ -3,7 +3,6 @@ import {
ElAutocomplete,
ElCascader,
ElCheckbox,
ElCheckboxGroup,
ElColorPicker,
ElDatePicker,
ElInput,
@ -11,9 +10,7 @@ import {
ElInputTag,
ElMention,
ElRadio,
ElRadioGroup,
ElRate,
ElSelect,
ElSelectV2,
ElSlider,
ElSwitch,
@ -23,6 +20,9 @@ import {
ElTreeSelect,
ElUpload,
} from "element-plus";
import CheckboxGroup from "./inputs/CheckboxGroup.vue";
import RadioGroup from "./inputs/RadioGroup.vue";
import Select from "./inputs/Select.vue";
import type { DisplayMode } from "./DataFormTypes.ts";
/** 内建的表单输入组件 */
@ -30,11 +30,11 @@ const builtInInputComponents = {
Input: markRaw<any>(ElInput),
InputNumber: markRaw<any>(ElInputNumber),
Checkbox: markRaw<any>(ElCheckbox),
CheckboxGroup: markRaw<any>(ElCheckboxGroup),
CheckboxGroup: markRaw<any>(CheckboxGroup),
Radio: markRaw<any>(ElRadio),
RadioGroup: markRaw<any>(ElRadioGroup),
RadioGroup: markRaw<any>(RadioGroup),
Switch: markRaw<any>(ElSwitch),
Select: markRaw<any>(ElSelect),
Select: markRaw<any>(Select),
SelectV2: markRaw<any>(ElSelectV2),
DatePicker: markRaw<any>(ElDatePicker),
TimePicker: markRaw<any>(ElTimePicker),

45
src/components/data-form/DataFormUtils.tsx

@ -1,4 +1,5 @@
import lodash from "lodash";
import { toRaw } from "vue";
import { Typeof } from "@ease-forge/shared";
/**
@ -28,10 +29,54 @@ function dataPathToNamePath(dataPath: string): string | number | Array<string |
return namePath;
}
// 空函数
function _emptyFun() {
}
/**
* vue组件的expose对象sources中存在且expose中不存在的属性合并到expose对象
* @param expose expose对象
* @param sources
* @param onlyFun
*/
function mergeExpose(expose: Record<string, any>, sources: any, onlyFun: boolean = false) {
if (!expose) return;
sources = toRaw(sources);
if (!sources || Typeof.isDate(sources) || Typeof.isArray(sources) || !Typeof.isObj(sources)) return;
// sources 是 dom 对象
if (sources instanceof HTMLElement || (sources.constructor?.name?.includes("HTML") && sources.constructor?.name?.includes("Element"))) {
expose.$el = sources;
return;
}
// 压制警告[Vue warn] Object.keys(sources)
const rawConsoleWarn = console.warn;
console.warn = _emptyFun;
let keys = Object.keys(sources);
console.warn = rawConsoleWarn;
// 处理 expose
for (let key of keys) {
const newValue = sources[key];
if (Typeof.noValue(newValue)) continue;
if (onlyFun && !Typeof.isFun(newValue)) continue;
expose[key] = newValue;
}
if (!onlyFun) {
// 处理 vue 组件内置属性
keys = ["$data", "$props", "$attrs", "$slots", "$refs", "$emit", "$on", "$off", "$once", "$forceUpdate", "$nextTick", "$watch", "$el", "$options", "$parent", "$root"];
for (let key of keys) {
const newValue = sources[key];
if (Typeof.noValue(newValue)) continue;
expose[key] = newValue;
}
}
}
export default {
dataPathToNamePath,
mergeExpose,
}
export {
dataPathToNamePath,
mergeExpose,
}

96
src/components/data-form/inputs/CheckboxGroup.vue

@ -0,0 +1,96 @@
<script setup lang="ts">
import lodash from "lodash";
import { computed, createVNode, defineExpose, onMounted, reactive, useAttrs, useSlots, useTemplateRef } from "vue";
import { ElCheckbox, ElCheckboxGroup } from "element-plus";
import { Typeof } from "@ease-forge/shared";
import { mergeExpose } from "../DataFormUtils.tsx";
defineOptions({
name: 'CheckboxGroup',
});
//
const attrs = useAttrs();
//
const slots = useSlots();
interface OptionItem {
value: string | number | boolean;
label: string;
[key: string]: any;
}
// Props
interface CheckboxGroupProps {
options?: Array<OptionItem>;
}
// props
const props = withDefaults(defineProps<CheckboxGroupProps>(), {
options: () => ([]),
});
// State
interface CheckboxGroupState {
}
// state
const state = reactive<CheckboxGroupState>({
loading: false,
});
//
const input = useTemplateRef<InstanceType<typeof ElCheckboxGroup>>("inputRef");
//
const options = computed(() => {
let opts: Array<OptionItem> = [];
let options = props.options;
if (options) {
if (Typeof.isArray(options)) {
opts = options;
} else {
console.log("options 配置必须是数组类型");
}
}
return opts;
});
// props
const inputProps = computed<any>(() => {
const res: any = { ...attrs };
if (Typeof.hasValue(res.modelValue) && !Typeof.isStr(res.modelValue)) res.modelValue = lodash.toString(res.modelValue);
return res;
});
function toString(val: any) {
if (Typeof.hasValue(val) && !Typeof.isStr(val)) return lodash.toString(val);
return val;
}
const expose = {
/** 组件状态 */
state,
};
onMounted(() => {
if (input.value) mergeExpose(expose, input.value);
});
//
defineExpose(expose);
export type {
OptionItem,
CheckboxGroupProps,
CheckboxGroupState,
}
</script>
<template>
<component ref="inputRef" :is="createVNode(ElCheckboxGroup, inputProps, slots)">
<ElCheckbox v-for="(item, idx) in options" v-bind="item" :value="toString(item.value)"/>
</component>
</template>
<style scoped>
</style>

96
src/components/data-form/inputs/RadioGroup.vue

@ -0,0 +1,96 @@
<script setup lang="ts">
import lodash from "lodash";
import { computed, createVNode, defineExpose, onMounted, reactive, useAttrs, useSlots, useTemplateRef } from "vue";
import { ElRadio, ElRadioGroup } from "element-plus";
import { Typeof } from "@ease-forge/shared";
import { mergeExpose } from "../DataFormUtils.tsx";
defineOptions({
name: 'RadioGroup',
});
//
const attrs = useAttrs();
//
const slots = useSlots();
interface OptionItem {
value: string | number | boolean;
label: string;
[key: string]: any;
}
// Props
interface RadioGroupProps {
options?: Array<OptionItem>;
}
// props
const props = withDefaults(defineProps<RadioGroupProps>(), {
options: () => ([]),
});
// State
interface RadioGroupState {
}
// state
const state = reactive<RadioGroupState>({
loading: false,
});
//
const input = useTemplateRef<InstanceType<typeof ElRadioGroup>>("inputRef");
//
const options = computed(() => {
let opts: Array<OptionItem> = [];
let options = props.options;
if (options) {
if (Typeof.isArray(options)) {
opts = options;
} else {
console.log("options 配置必须是数组类型");
}
}
return opts;
});
// props
const inputProps = computed<any>(() => {
const res: any = { ...attrs };
if (Typeof.hasValue(res.modelValue) && !Typeof.isStr(res.modelValue)) res.modelValue = lodash.toString(res.modelValue);
return res;
});
function toString(val: any) {
if (Typeof.hasValue(val) && !Typeof.isStr(val)) return lodash.toString(val);
return val;
}
const expose = {
/** 组件状态 */
state,
};
onMounted(() => {
if (input.value) mergeExpose(expose, input.value);
});
//
defineExpose(expose);
export type {
OptionItem,
RadioGroupProps,
RadioGroupState,
}
</script>
<template>
<component ref="inputRef" :is="createVNode(ElRadioGroup, inputProps, slots)">
<ElRadio v-for="(item, idx) in options" v-bind="item" :value="toString(item.value)"/>
</component>
</template>
<style scoped>
</style>

96
src/components/data-form/inputs/Select.vue

@ -0,0 +1,96 @@
<script setup lang="ts">
import lodash from "lodash";
import { computed, createVNode, defineExpose, onMounted, reactive, useAttrs, useSlots, useTemplateRef } from "vue";
import { ElOption, ElSelect } from "element-plus";
import { Typeof } from "@ease-forge/shared";
import { mergeExpose } from "../DataFormUtils.tsx";
defineOptions({
name: 'Select',
});
//
const attrs = useAttrs();
//
const slots = useSlots();
interface OptionItem {
value: string | number | boolean;
label: string;
[key: string]: any;
}
// Props
interface SelectProps {
options?: Array<OptionItem>;
}
// props
const props = withDefaults(defineProps<SelectProps>(), {
options: () => ([]),
});
// State
interface SelectState {
}
// state
const state = reactive<SelectState>({
loading: false,
});
//
const input = useTemplateRef<InstanceType<typeof ElSelect>>("inputRef");
//
const options = computed(() => {
let opts: Array<OptionItem> = [];
let options = props.options;
if (options) {
if (Typeof.isArray(options)) {
opts = options;
} else {
console.log("options 配置必须是数组类型");
}
}
return opts;
});
// props
const inputProps = computed<any>(() => {
const res: any = { ...attrs };
if (Typeof.hasValue(res.modelValue) && !Typeof.isStr(res.modelValue)) res.modelValue = lodash.toString(res.modelValue);
return res;
});
function toString(val: any) {
if (Typeof.hasValue(val) && !Typeof.isStr(val)) return lodash.toString(val);
return val;
}
const expose = {
/** 组件状态 */
state,
};
onMounted(() => {
if (input.value) mergeExpose(expose, input.value);
});
//
defineExpose(expose);
export type {
OptionItem,
SelectProps,
SelectState,
}
</script>
<template>
<component ref="inputRef" :is="createVNode(ElSelect, inputProps, slots)">
<ElOption v-for="(item, idx) in options" v-bind="item" :value="toString(item.value)"/>
</component>
</template>
<style scoped>
</style>

5
src/editor/propEditors/IMetaProp.ts

@ -28,6 +28,9 @@ export default defineComponent({
computed: {
object3D(): THREE.Object3D {
return this.viewport.state.selectedObject
},
item(): ItemJson {
return this.viewport.state.selectedItem
}
}
})
})

19
src/pages/DataForm01.vue

@ -93,7 +93,10 @@ const dataForm1 = reactive<DataFormProps>({
dataPath: 'checkbox_group_1', label: '复选组', input: 'CheckboxGroup',
inputProps: {
max: 2,
// TODO options
options: [
{ value: "001", label: "选项1" },
{ value: "v2", label: "选项2" },
],
},
},
{
@ -105,7 +108,10 @@ const dataForm1 = reactive<DataFormProps>({
{
dataPath: 'radio_group_1', label: '单选组', input: 'RadioGroup',
inputProps: {
// TODO options
options: [
{ value: "001", label: "选项1" },
{ value: "002", label: "选项2" },
],
},
},
{
@ -123,7 +129,14 @@ const dataForm1 = reactive<DataFormProps>({
inputProps: {
placeholder: "请选择",
clearable: true,
// TODO options
options: [
{ value: "001", label: "选项1" },
{ value: "002", label: "选项2" },
{ value: "003", label: "选项3" },
{ value: "004", label: "选项4" },
{ value: "005", label: "选项5" },
{ value: "006", label: "选项6" },
],
},
},
{

Loading…
Cancel
Save