新增operationcard组件

This commit is contained in:
fofolee 2025-01-06 21:18:03 +08:00
parent 516e6c2d16
commit 25be7f4926
10 changed files with 262 additions and 326 deletions

View File

@ -1,27 +1,11 @@
<template>
<div class="flex-container">
<div
<OperationCard
v-if="hasFunctionSelector"
class="flex-item"
:style="{ flex: localCommand.functionSelector.width || 3 }"
>
<div class="operation-cards">
<div
v-for="option in localCommand.functionSelector?.options"
:key="option.value"
:class="['operation-card', { active: funcName === option.value }]"
:data-value="option.value"
@click="funcName = option.value"
>
<q-icon
:name="option.icon || localCommand.icon || 'functions'"
size="16px"
:color="funcName === option.value ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ option.label }}</div>
</div>
</div>
</div>
:model-value="funcName"
@update:model-value="funcName = $event"
:options="localCommand.functionSelector?.options"
/>
<div class="flex-container">
<div
v-for="(item, index) in localConfig"
@ -102,6 +86,7 @@ import VariableInput from "components/composer/common/VariableInput.vue";
import NumberInput from "components/composer/common/NumberInput.vue";
import ArrayEditor from "components/composer/common/ArrayEditor.vue";
import DictEditor from "components/composer/common/DictEditor.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
export default defineComponent({
@ -111,6 +96,7 @@ export default defineComponent({
NumberInput,
ArrayEditor,
DictEditor,
OperationCard,
},
props: {
modelValue: {
@ -219,23 +205,6 @@ export default defineComponent({
this.updateModelValue(this.funcName, this.defaultArgvs);
}
},
watch: {
funcName: {
immediate: true,
handler(newVal) {
//
this.$nextTick(() => {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
});
</script>

View File

@ -0,0 +1,148 @@
<template>
<div class="operation-cards-container" :style="containerStyle">
<div ref="scrollArea" class="scroll-container" @wheel.prevent="handleWheel">
<div class="cards-wrapper">
<div
v-for="option in options"
:key="option.value"
:class="['operation-card', { active: modelValue === option.value }]"
:data-value="option.value"
@click="$emit('update:modelValue', option.value)"
>
<q-icon
:name="option.icon || 'functions'"
size="16px"
:color="modelValue === option.value ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ option.label }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
default: () => [],
},
modelValue: {
type: String,
default: () => this.options[0]?.value,
},
minWidth: {
type: String,
default: "80px",
},
},
computed: {
containerStyle() {
return {
"--min-width": this.minWidth,
"--total-items": this.options.length,
"--total-gap": `${(this.options.length - 1) * 8}px`,
};
},
},
methods: {
//
handleWheel(e) {
const scrollArea = this.$refs.scrollArea;
//
const delta =
Math.abs(e.deltaX) > Math.abs(e.deltaY) ? e.deltaX : e.deltaY * 0.8;
if (scrollArea) {
scrollArea.scrollLeft += delta;
}
},
},
watch: {
modelValue(newVal) {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
},
},
};
</script>
<style scoped>
.operation-cards-container {
position: relative;
width: 100%;
}
.scroll-container {
overflow-x: auto;
overflow-y: hidden;
}
.scroll-container::-webkit-scrollbar {
display: none;
}
.cards-wrapper {
display: grid;
grid-auto-flow: column;
grid-auto-columns: minmax(
var(--min-width),
calc((100% - (var(--total-gap, 0px))) / var(--total-items, 1))
);
gap: 8px;
width: fit-content;
min-width: 100%;
padding: 1px;
}
.operation-card {
cursor: pointer;
transition: all 0.2s ease;
border: 1px solid transparent;
border-radius: 16px;
background: rgba(0, 0, 0, 0.03);
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
padding: 4px 8px;
user-select: none;
}
.operation-card:hover {
background: var(--q-primary-opacity-5);
transform: translateY(-1px);
border: 1px solid var(--q-primary-opacity-5);
}
.operation-card.active {
border-color: var(--q-primary);
background: var(--q-primary-opacity-5);
}
/* 暗色模式适配 */
.body--dark .operation-card {
background: rgba(255, 255, 255, 0.03);
}
.body--dark .operation-card:hover {
background: var(--q-primary-opacity-5);
}
.body--dark .operation-card.active {
border-color: var(--q-primary-opacity-50);
background: var(--q-primary-opacity-5);
}
.operation-card .text-caption {
text-align: center;
word-break: break-word;
line-height: 1.2;
}
</style>

View File

@ -1,23 +1,11 @@
<template>
<div class="buffer-editor">
<!-- 操作类型选择 -->
<div class="operation-cards">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
:data-value="op.name"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 操作配置 -->
<div class="operation-options q-mt-sm">
<div class="options-container">
@ -366,6 +354,7 @@ import { stringifyArgv, parseFunction } from "js/composer/formatString";
import VariableInput from "components/composer/common/VariableInput.vue";
import NumberInput from "components/composer/common/NumberInput.vue";
import ArrayEditor from "components/composer/common/ArrayEditor.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "BufferEditor",
@ -373,6 +362,7 @@ export default defineComponent({
VariableInput,
NumberInput,
ArrayEditor,
OperationCard,
},
props: {
modelValue: {
@ -384,16 +374,16 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "from", label: "创建Buffer", icon: "add_box" },
{ name: "toString", label: "转换字符串", icon: "text_fields" },
{ name: "write", label: "写入数据", icon: "edit" },
{ name: "fill", label: "填充数据", icon: "format_color_fill" },
{ name: "copy", label: "复制数据", icon: "content_copy" },
{ name: "compare", label: "比较数据", icon: "compare" },
{ name: "concat", label: "连接Buffer", icon: "merge" },
{ name: "indexOf", label: "查找数据", icon: "search" },
{ name: "slice", label: "切片数据", icon: "content_cut" },
{ name: "swap", label: "交换字节序", icon: "swap_horiz" },
{ value: "from", label: "创建Buffer", icon: "add_box" },
{ value: "toString", label: "转换字符串", icon: "text_fields" },
{ value: "write", label: "写入数据", icon: "edit" },
{ value: "fill", label: "填充数据", icon: "format_color_fill" },
{ value: "copy", label: "复制数据", icon: "content_copy" },
{ value: "compare", label: "比较数据", icon: "compare" },
{ value: "concat", label: "连接Buffer", icon: "merge" },
{ value: "indexOf", label: "查找数据", icon: "search" },
{ value: "slice", label: "切片数据", icon: "content_cut" },
{ value: "swap", label: "交换字节序", icon: "swap_horiz" },
],
encodings: [
{ label: "UTF-8", value: "utf8" },
@ -669,7 +659,7 @@ export default defineComponent({
},
getSummary(argvs) {
const op = this.operations.find(
(op) => op.name === argvs.operation
(op) => op.value === argvs.operation
)?.label;
return op;
},
@ -687,22 +677,6 @@ export default defineComponent({
this.updateModelValue(this.defaultArgvs);
}
},
watch: {
"argvs.operation": {
immediate: true,
handler(newVal) {
this.$nextTick(() => {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
});
</script>

View File

@ -1,31 +1,18 @@
<template>
<div class="zlib-editor">
<!-- 操作类型选择 -->
<div class="row items-center q-gutter-x-xs">
<!-- 数据输入 -->
<VariableInput
:model-value="argvs.data"
@update:model-value="(val) => updateArgvs('data', val)"
label="要处理的数据"
class="col"
icon="data_object"
/>
<div class="col-auto row items-center q-gutter-x-xs">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 数据输入 -->
<VariableInput
:model-value="argvs.data"
@update:model-value="(val) => updateArgvs('data', val)"
label="要处理的数据"
icon="data_object"
/>
<!-- 操作配置 -->
<div class="operation-options">
<div class="options-container">
@ -144,12 +131,13 @@ import { defineComponent } from "vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
import VariableInput from "components/composer/common/VariableInput.vue";
import NumberInput from "components/composer/common/NumberInput.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "ZlibEditor",
components: {
VariableInput,
NumberInput,
OperationCard,
},
props: {
modelValue: {
@ -161,8 +149,8 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "compressData", label: "压缩", icon: "compress" },
{ name: "decompressData", label: "解压", icon: "expand" },
{ value: "compressData", label: "压缩", icon: "compress" },
{ value: "decompressData", label: "解压", icon: "expand" },
],
methods: [
{ label: "Gzip", value: "gzip" },
@ -299,7 +287,7 @@ export default defineComponent({
},
getSummary(argvs) {
const op = this.operations.find(
(op) => op.name === argvs.operation
(op) => op.value === argvs.operation
)?.label;
const method = this.methods.find((m) => m.value === argvs.method)?.label;
return `${op} (${method})`;

View File

@ -1,22 +1,11 @@
<template>
<div class="dns-editor">
<!-- 操作类型选择 -->
<div class="operation-cards">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
:data-value="op.name"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 操作配置 -->
<div class="operation-options">
@ -75,11 +64,12 @@
import { defineComponent } from "vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
import VariableInput from "components/composer/common/VariableInput.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "DnsEditor",
components: {
VariableInput,
OperationCard,
},
props: {
modelValue: {
@ -91,19 +81,19 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "lookupHost", label: "DNS查询", icon: "search" },
{ name: "resolveAll", label: "解析所有记录", icon: "all_inclusive" },
{ name: "resolveIpv4", label: "解析IPv4", icon: "filter_4" },
{ name: "resolveIpv6", label: "解析IPv6", icon: "filter_6" },
{ name: "resolveMxRecords", label: "解析MX记录", icon: "mail" },
{ value: "lookupHost", label: "DNS查询", icon: "search" },
{ value: "resolveAll", label: "解析所有记录", icon: "all_inclusive" },
{ value: "resolveIpv4", label: "解析IPv4", icon: "filter_4" },
{ value: "resolveIpv6", label: "解析IPv6", icon: "filter_6" },
{ value: "resolveMxRecords", label: "解析MX记录", icon: "mail" },
{
name: "resolveTxtRecords",
value: "resolveTxtRecords",
label: "解析TXT记录",
icon: "text_fields",
},
{ name: "resolveNsRecords", label: "解析NS记录", icon: "dns" },
{ name: "resolveCnameRecords", label: "解析CNAME记录", icon: "link" },
{ name: "reverseResolve", label: "反向解析", icon: "swap_horiz" },
{ value: "resolveNsRecords", label: "解析NS记录", icon: "dns" },
{ value: "resolveCnameRecords", label: "解析CNAME记录", icon: "link" },
{ value: "reverseResolve", label: "反向解析", icon: "swap_horiz" },
],
families: [
{ label: "自动", value: 0 },
@ -214,7 +204,7 @@ export default defineComponent({
},
getSummary(argvs) {
const op = this.operations.find(
(op) => op.name === argvs.operation
(op) => op.value === argvs.operation
)?.label;
return op === "反向解析"
? "反向解析 " + argvs.ip.value
@ -234,22 +224,6 @@ export default defineComponent({
this.updateModelValue(this.defaultArgvs);
}
},
watch: {
"argvs.operation": {
immediate: true,
handler(newVal) {
this.$nextTick(() => {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
});
</script>
@ -264,8 +238,4 @@ export default defineComponent({
gap: 8px;
padding-top: 8px;
}
.command-composer .operation-card {
min-width: 95px;
}
</style>

View File

@ -1,22 +1,11 @@
<template>
<div class="url-editor">
<!-- 操作类型选择 -->
<div class="operation-cards">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
:data-value="op.name"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 操作配置 -->
<div class="operation-options q-mt-sm">
@ -172,12 +161,14 @@ import { defineComponent } from "vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
import VariableInput from "components/composer/common/VariableInput.vue";
import DictEditor from "components/composer/common/DictEditor.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "UrlEditor",
components: {
VariableInput,
DictEditor,
OperationCard,
},
props: {
modelValue: {
@ -189,17 +180,17 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "parse", label: "解析URL", icon: "link_off" },
{ name: "format", label: "格式化URL", icon: "link" },
{ name: "parseQuery", label: "解析查询字符串", icon: "search" },
{ name: "formatQuery", label: "格式化查询字符串", icon: "edit" },
{ name: "parsePath", label: "解析路径", icon: "folder_open" },
{ name: "parseHost", label: "解析主机名", icon: "dns" },
{ name: "getQueryParam", label: "获取参数", icon: "find_in_page" },
{ name: "addQueryParam", label: "添加参数", icon: "add_circle" },
{ name: "removeQueryParam", label: "移除参数", icon: "remove_circle" },
{ name: "isAbsolute", label: "检查绝对URL", icon: "check_circle" },
{ name: "parseComponents", label: "解析组成部分", icon: "category" },
{ value: "parse", label: "解析URL", icon: "link_off" },
{ value: "format", label: "格式化URL", icon: "link" },
{ value: "parseQuery", label: "解析查询字符串", icon: "search" },
{ value: "formatQuery", label: "格式化查询字符串", icon: "edit" },
{ value: "parsePath", label: "解析路径", icon: "folder_open" },
{ value: "parseHost", label: "解析主机名", icon: "dns" },
{ value: "getQueryParam", label: "获取参数", icon: "find_in_page" },
{ value: "addQueryParam", label: "添加参数", icon: "add_circle" },
{ value: "removeQueryParam", label: "移除参数", icon: "remove_circle" },
{ value: "isAbsolute", label: "检查绝对URL", icon: "check_circle" },
{ value: "parseComponents", label: "解析组成部分", icon: "category" },
],
defaultArgvs: {
operation: "parse",
@ -428,7 +419,7 @@ export default defineComponent({
},
getSummary(argvs) {
const op = this.operations.find(
(op) => op.name === argvs.operation
(op) => op.value === argvs.operation
)?.label;
return op + " " + argvs.url.value;
},
@ -446,22 +437,6 @@ export default defineComponent({
this.updateModelValue(this.defaultArgvs);
}
},
watch: {
"argvs.operation": {
immediate: true,
handler(newVal) {
this.$nextTick(() => {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
});
</script>
@ -477,9 +452,4 @@ export default defineComponent({
flex-direction: column;
justify-content: center;
}
/* 覆盖command-composer的样式 */
.command-composer .operation-card {
min-width: 100px;
}
</style>

View File

@ -1,21 +1,11 @@
<template>
<div class="os-editor">
<!-- 操作类型选择 -->
<div class="operation-cards">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 操作配置 -->
<div class="operation-options q-mt-sm" v-if="hasOptions">
@ -91,9 +81,12 @@
<script>
import { defineComponent } from "vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "OsEditor",
components: {
OperationCard,
},
props: {
modelValue: {
type: Object,
@ -104,11 +97,11 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "arch", label: "系统架构", icon: "memory" },
{ name: "cpus", label: "CPU信息", icon: "developer_board" },
{ name: "memory", label: "内存信息", icon: "storage" },
{ name: "network", label: "网络信息", icon: "wifi" },
{ name: "platform", label: "平台信息", icon: "computer" },
{ value: "arch", label: "系统架构", icon: "memory" },
{ value: "cpus", label: "CPU信息", icon: "developer_board" },
{ value: "memory", label: "内存信息", icon: "storage" },
{ value: "network", label: "网络信息", icon: "wifi" },
{ value: "platform", label: "平台信息", icon: "computer" },
],
formatOptions: [
{ label: "完整信息", value: "full" },
@ -192,7 +185,7 @@ export default defineComponent({
},
pointerStyle() {
const activeIndex = this.operations.findIndex(
(op) => op.name === this.argvs.operation
(op) => op.value === this.argvs.operation
);
if (activeIndex === -1) return {};
@ -281,7 +274,7 @@ export default defineComponent({
};
},
getSummary(argvs) {
return this.operations.find((op) => op.name === argvs.operation).label;
return this.operations.find((op) => op.value === argvs.operation).label;
},
updateModelValue(argvs) {
this.$emit("update:modelValue", {

View File

@ -1,22 +1,11 @@
<template>
<div class="path-editor">
<!-- 操作类型选择 -->
<div class="operation-cards">
<div
v-for="op in operations"
:key="op.name"
:class="['operation-card', { active: argvs.operation === op.name }]"
@click="updateArgvs('operation', op.name)"
:data-value="op.name"
>
<q-icon
:name="op.icon"
size="16px"
:color="argvs.operation === op.name ? 'primary' : 'grey'"
/>
<div class="text-caption">{{ op.label }}</div>
</div>
</div>
<OperationCard
:model-value="argvs.operation"
@update:model-value="(val) => updateArgvs('operation', val)"
:options="operations"
/>
<!-- 操作配置 -->
<div class="operation-options q-mt-sm">
@ -163,11 +152,12 @@
import { defineComponent } from "vue";
import { stringifyArgv, parseFunction } from "js/composer/formatString";
import VariableInput from "components/composer/common/VariableInput.vue";
import OperationCard from "components/composer/common/OperationCard.vue";
export default defineComponent({
name: "PathEditor",
components: {
VariableInput,
OperationCard,
},
props: {
modelValue: {
@ -179,16 +169,16 @@ export default defineComponent({
data() {
return {
operations: [
{ name: "normalize", label: "规范化路径", icon: "straighten" },
{ name: "join", label: "连接路径", icon: "add_link" },
{ name: "parse", label: "解析路径", icon: "account_tree" },
{ name: "dirname", label: "获取目录名", icon: "folder" },
{ name: "basename", label: "获取文件名", icon: "description" },
{ name: "extname", label: "获取扩展名", icon: "extension" },
{ name: "isAbsolute", label: "判断绝对路径", icon: "check_circle" },
{ name: "relative", label: "计算相对路径", icon: "compare_arrows" },
{ name: "resolve", label: "解析绝对路径", icon: "assistant_direction" },
{ name: "format", label: "格式化路径", icon: "format_shapes" },
{ value: "normalize", label: "规范化路径", icon: "straighten" },
{ value: "join", label: "连接路径", icon: "add_link" },
{ value: "parse", label: "解析路径", icon: "account_tree" },
{ value: "dirname", label: "获取目录名", icon: "folder" },
{ value: "basename", label: "获取文件名", icon: "description" },
{ value: "extname", label: "获取扩展名", icon: "extension" },
{ value: "isAbsolute", label: "判断绝对路径", icon: "check_circle" },
{ value: "relative", label: "计算相对路径", icon: "compare_arrows" },
{ value: "resolve", label: "解析绝对路径", icon: "assistant_direction" },
{ value: "format", label: "格式化路径", icon: "format_shapes" },
],
defaultArgvs: {
operation: "normalize",
@ -265,7 +255,7 @@ export default defineComponent({
},
pointerStyle() {
const activeIndex = this.operations.findIndex(
(op) => op.name === this.argvs.operation
(op) => op.value === this.argvs.operation
);
if (activeIndex === -1) return {};
@ -414,7 +404,7 @@ export default defineComponent({
this.updateArgvs("paths", newPaths);
},
getSummary(argvs) {
return this.operations.find((op) => op.name === argvs.operation)?.label;
return this.operations.find((op) => op.value === argvs.operation)?.label;
},
updateModelValue(argvs) {
this.$emit("update:modelValue", {
@ -430,22 +420,6 @@ export default defineComponent({
this.updateModelValue(this.defaultArgvs);
}
},
watch: {
"argvs.operation": {
immediate: true,
handler(newVal) {
this.$nextTick(() => {
document
.querySelector(`.operation-card[data-value="${newVal}"]`)
?.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest",
});
});
},
},
},
});
</script>

View File

@ -1,53 +1,3 @@
/* 操作卡片样式 */
.command-composer .operation-cards {
display: flex;
align-items: center;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
padding: 1px;
gap: 8px;
border-radius: 8px;
}
.command-composer .operation-cards::-webkit-scrollbar {
display: none;
}
.command-composer .operation-card {
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid transparent;
border-radius: 6px;
min-width: 72px;
max-height: 36px;
background: rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.command-composer .operation-card:hover {
background: var(--q-primary-opacity-5);
transform: translateY(-1px);
border: 1px solid var(--q-primary-opacity-10);
}
.command-composer .operation-card.active {
border-color: var(--q-primary);
background: var(--q-primary-opacity-5);
}
/* 暗色模式适配 */
.body--dark .command-composer .operation-card {
background: rgba(255, 255, 255, 0.03);
}
.body--dark .command-composer .operation-card.active {
border-color: var(--q-primary-opacity-50);
}
/* 滚动美化 */
.command-composer .q-scrollarea__thumb {
width: 2px;

View File

@ -130,7 +130,7 @@ const customComponentGuide = {
implementation: {
simpleCase: `
// 返回操作类型的标签
return this.operations.find(op => op.name === argvs.operation).label;
return this.operations.find(op => op.value === argvs.operation).label;
`,
complexCase: `
// 返回关键参数的值