mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-10-11 08:03:28 +08:00
添加OptionEditor组件,优化参数传递方式
This commit is contained in:
@@ -52,7 +52,7 @@ export default defineComponent({
|
||||
localConfig() {
|
||||
return [...this.commonConfig, ...this.subCommandConfig].map((item) => {
|
||||
const value =
|
||||
item.type === "varInput"
|
||||
item.component === "VariableInput"
|
||||
? item.defaultValue || newVarInputVal("str")
|
||||
: // 其他类型情况复杂,不做判断,没有默认值返回undefined
|
||||
item.defaultValue;
|
||||
@@ -147,15 +147,27 @@ export default defineComponent({
|
||||
if (!code) return argvs;
|
||||
|
||||
const variableFormatPaths = [];
|
||||
|
||||
const addVariableFormatPath = (prefix, config) => {
|
||||
if (config.component === "VariableInput") {
|
||||
variableFormatPaths.push(prefix);
|
||||
} else if (config.component === "ArrayEditor") {
|
||||
variableFormatPaths.push(`${prefix}[*]`);
|
||||
} else if (config.component === "DictEditor") {
|
||||
variableFormatPaths.push(`${prefix}.**`);
|
||||
}
|
||||
};
|
||||
|
||||
this.localConfig.forEach((item, index) => {
|
||||
if (item.type === "varInput") {
|
||||
variableFormatPaths.push(`arg${index}`);
|
||||
} else if (item.type === "arrayEditor") {
|
||||
variableFormatPaths.push(`arg${index}[*]`);
|
||||
} else if (item.type === "dictEditor") {
|
||||
variableFormatPaths.push(`arg${index}.**`);
|
||||
if (item.component === "OptionEditor") {
|
||||
Object.entries(item.options).forEach(([key, config]) => {
|
||||
addVariableFormatPath(`arg${index}.${key}`, config);
|
||||
});
|
||||
} else {
|
||||
addVariableFormatPath(`arg${index}`, item);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
argvs = parseFunction(code, { variableFormatPaths }).argvs;
|
||||
} catch (e) {
|
||||
|
@@ -22,6 +22,7 @@
|
||||
:no-icon="true"
|
||||
:placeholder="key.placeholder"
|
||||
:options="key.options"
|
||||
:disable-toggle-type="key.disableToggleType"
|
||||
@update:model-value="
|
||||
(val) => updateItemKeyValue(index, key.value, val)
|
||||
"
|
||||
@@ -38,6 +39,7 @@
|
||||
:options="{
|
||||
items: options.items,
|
||||
}"
|
||||
:disable-toggle-type="disableToggleType"
|
||||
@update:model-value="(val) => updateItemValue(index, val)"
|
||||
/>
|
||||
</div>
|
||||
@@ -186,6 +188,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
disableToggleType: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
computed: {
|
||||
|
@@ -103,7 +103,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
updateNumber(delta) {
|
||||
const newValue = (this.localValue || 0) + delta;
|
||||
const newValue = +((this.localValue || 0) + delta).toFixed(10);
|
||||
if (newValue > this.max) {
|
||||
this.$emit("update:modelValue", this.max);
|
||||
} else if (newValue < this.min) {
|
||||
|
144
src/components/composer/common/OptionEditor.vue
Normal file
144
src/components/composer/common/OptionEditor.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<component
|
||||
:is="!!label ? 'BorderLabel' : 'div'"
|
||||
:label="label"
|
||||
:icon="icon"
|
||||
:model-value="isCollapse"
|
||||
>
|
||||
<div class="param-grid">
|
||||
<div
|
||||
v-for="([key, config], index) in Object.entries(options)"
|
||||
:key="`${key}-${index}`"
|
||||
class="grid-item"
|
||||
:style="getColumnStyle(config.width)"
|
||||
>
|
||||
<component
|
||||
:is="config.component"
|
||||
:model-value="localObject[key]"
|
||||
@update:model-value="updateOption(key, $event)"
|
||||
v-bind="config"
|
||||
filled
|
||||
dense
|
||||
:emit-value="config.component === 'q-select'"
|
||||
:map-options="config.component === 'q-select'"
|
||||
>
|
||||
<template v-slot:prepend v-if="shouldShowQIcon(config)">
|
||||
<q-icon :name="config.icon" />
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import BorderLabel from "./BorderLabel.vue";
|
||||
import VariableInput from "./VariableInput.vue";
|
||||
import NumberInput from "./NumberInput.vue";
|
||||
import ArrayEditor from "./ArrayEditor.vue";
|
||||
import DictEditor from "./DictEditor.vue";
|
||||
import ButtonGroup from "./ButtonGroup.vue";
|
||||
import ControlInput from "./ControlInput.vue";
|
||||
import CheckGroup from "./CheckGroup.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "OptionEditor",
|
||||
components: {
|
||||
BorderLabel,
|
||||
VariableInput,
|
||||
NumberInput,
|
||||
ArrayEditor,
|
||||
DictEditor,
|
||||
ButtonGroup,
|
||||
ControlInput,
|
||||
CheckGroup,
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isCollapse: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
localObject() {
|
||||
return this.modelValue;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateOption(key, value) {
|
||||
this.$emit("update:modelValue", { ...this.localObject, [key]: value });
|
||||
},
|
||||
getColumnStyle(width = 12) {
|
||||
if (width === "auto") {
|
||||
return {
|
||||
flex: "1 1 0%",
|
||||
minWidth: "0",
|
||||
};
|
||||
}
|
||||
const columnWidth = (width / 12) * 100;
|
||||
return {
|
||||
width: `calc(${columnWidth}% - var(--grid-gap))`,
|
||||
flex: "0 0 auto",
|
||||
};
|
||||
},
|
||||
shouldShowQIcon(config) {
|
||||
return ["q-input", "q-select"].includes(config.component) && config.icon;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.param-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--grid-gap);
|
||||
width: 100%;
|
||||
--grid-gap: 8px;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
min-width: 50px;
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.grid-item > * {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 让开关、复选框和按钮组居中显示 */
|
||||
.grid-item > .q-toggle,
|
||||
.grid-item > .q-checkbox,
|
||||
.grid-item > .q-btn-group {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.grid-item {
|
||||
width: 100% !important;
|
||||
flex: 1 1 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -6,86 +6,20 @@
|
||||
class="grid-item"
|
||||
:style="getColumnStyle(config.width)"
|
||||
>
|
||||
<ControlInput
|
||||
v-if="config.type === 'controlInput'"
|
||||
<component
|
||||
:is="config.component"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<VariableInput
|
||||
v-else-if="config.type === 'varInput'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<NumberInput
|
||||
v-else-if="config.type === 'numInput'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<ArrayEditor
|
||||
v-else-if="config.type === 'arrayEditor'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<DictEditor
|
||||
v-else-if="config.type === 'dictEditor'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<q-toggle
|
||||
v-else-if="config.type === 'switch'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<q-select
|
||||
v-else-if="config.type === 'select'"
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
map-options
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
:emit-value="config.component === 'q-select'"
|
||||
:map-options="config.component === 'q-select'"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon :name="config.icon || 'code'" />
|
||||
<template v-slot:prepend v-if="shouldShowQIcon(config)">
|
||||
<q-icon :name="config.icon" />
|
||||
</template>
|
||||
</q-select>
|
||||
<q-input
|
||||
v-else-if="config.type === 'input'"
|
||||
filled
|
||||
dense
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon :name="config.icon || 'code'" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-checkbox
|
||||
v-else-if="config.type === 'checkbox'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-else-if="config.type === 'buttonGroup'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
<CheckGroup
|
||||
v-else-if="config.type === 'checkGroup'"
|
||||
:model-value="values[index]"
|
||||
@update:model-value="$emit('update', index, $event)"
|
||||
v-bind="config"
|
||||
/>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -99,6 +33,7 @@ import DictEditor from "./DictEditor.vue";
|
||||
import ButtonGroup from "./ButtonGroup.vue";
|
||||
import ControlInput from "./ControlInput.vue";
|
||||
import CheckGroup from "./CheckGroup.vue";
|
||||
import OptionEditor from "./OptionEditor.vue";
|
||||
|
||||
/**
|
||||
* 参数输入组件
|
||||
@@ -121,6 +56,7 @@ export default defineComponent({
|
||||
ButtonGroup,
|
||||
ControlInput,
|
||||
CheckGroup,
|
||||
OptionEditor,
|
||||
},
|
||||
props: {
|
||||
configs: {
|
||||
@@ -147,6 +83,9 @@ export default defineComponent({
|
||||
flex: "0 0 auto",
|
||||
};
|
||||
},
|
||||
shouldShowQIcon(config) {
|
||||
return ["q-input", "q-select"].includes(config.component) && config.icon;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@@ -30,8 +30,9 @@
|
||||
>
|
||||
<q-tooltip>{{
|
||||
isString
|
||||
? "当前类型是:字符串,点击切换"
|
||||
: "当前类型是:变量、数字、表达式等,点击切换"
|
||||
? "当前类型是:字符串"
|
||||
: "当前类型是:变量、数字、表达式等" +
|
||||
(disableToggleType ? "" : ",点击切换")
|
||||
}}</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- 选项下拉按钮 -->
|
||||
@@ -222,6 +223,10 @@ export default defineComponent({
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
disableToggleType: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
emits: ["update:modelValue"],
|
||||
@@ -308,6 +313,7 @@ export default defineComponent({
|
||||
|
||||
// 切换类型
|
||||
toggleType() {
|
||||
if (this.disableToggleType) return;
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
isString: !this.modelValue.isString,
|
||||
|
Reference in New Issue
Block a user