uTools-quickcommand/src/js/composer/customComponentGuide.js
2025-01-08 14:39:08 +08:00

413 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Custom Component Creation Guide
* 自定义组件创建指南
*/
const customComponentGuide = {
description: "创建自定义命令组件的完整流程",
important: "创建过程中严禁删除、修改任何已有的函数或对象",
steps: {
"1. Backend Interface": {
location: "plugin/lib/quickcomposer/xxx/yyy.js",
description: "创建具体功能实现",
requirements: {
functionDefinition: "使用独立函数而非对象方法",
asyncHandling: "使用 async/await 处理异步操作",
errorHandling: "合理的错误捕获和提示",
paramValidation: "检查必要参数是否存在",
},
},
"2. Interface Export": {
location: "plugin/lib/quickcomposer/xxx/index.js",
description: "导出接口给quickcomposer使用",
examples: {
singleFunction: "module.exports = { operation }",
multipleFunctions: "module.exports = { ...encoder, ...hash }",
},
},
"3. Interface Registration": {
location: "plugin/lib/quickcomposer.js",
description: "将接口注册到quickcomposer对象",
format: "quickcomposer.xxx = require('./quickcomposer/xxx')",
},
"4. Component Development": {
location: "src/components/composer/xxx/YourComponent.vue",
basicStructure: {
template: "组件模板使用quasar组件库",
script: "组件逻辑使用Vue3 defineComponent",
style: "组件样式建议使用scoped",
},
keyPoints: {
props: {
modelValue: {
description: "必需的属性,包含组件的完整配置",
type: "Object",
required: true,
structure: {
value: "组件对应的函数名",
code: "生成的代码字符串",
argvs: "解析后的参数对象",
},
},
},
computed: {
argvs: {
description: "处理参数的计算属性",
implementation: `
return this.modelValue.argvs ||
this.parseCodeToArgvs(this.modelValue.code) ||
this.defaultArgvs;
`,
},
},
data: {
defaultArgvs: {
description: "定义组件的默认参数结构",
example: `{
key: "",
modifiers: {
control: false,
alt: false,
shift: false,
command: false,
}
}`,
},
},
methods: {
generateCode: {
description: "生成代码字符串的方法",
parameters: "argvs - 当前参数对象",
implementation: {
simpleCase: `
// 简单参数的情况
const args = [value, ...modifiers];
return \`functionName("\${args.join('","')})\`;
`,
objectCase: `
// 对象参数的情况
const formattedConfig = stringifyArgv(config);
return \`functionName(\${formattedConfig})\`;
`,
},
},
parseCodeToArgvs: {
description: "解析代码字符串为参数对象严禁使用eval",
parameters: "code - 要解析的代码字符串",
implementation: {
steps: [
"1. 检查代码是否存在",
"2. 定义需要使用variable格式的路径",
"3. 使用parseFunction解析代码",
"4. 处理解析结果并返回参数对象",
],
example: `
// 定义需要使用variable格式的路径
const variableFormatPaths = [
'arg0', // url参数
'arg*.headers.**', // 所有headers字段
'!arg*.headers.Content-Type' // 排除Content-Type
];
// 解析代码
const result = parseFunction(code, { variableFormatPaths });
if (!result) return this.defaultArgvs;
// 处理解析结果
const [url, config] = result.argvs;
// 返回处理后的参数对象
return {
...this.defaultArgvs,
url,
...config
};
`,
},
},
getSummary: {
description: "生成命令的简短描述,用于在命令列表中显示",
parameters: "argvs - 当前参数对象",
implementation: {
simpleCase: `
// 返回操作类型的标签
return this.operations.find(op => op.value === argvs.operation).label;
`,
complexCase: `
// 返回关键参数的值
return argvs.command.value;
`,
},
notes: [
"返回值应该简洁明了,帮助用户快速识别命令的功能",
"对于复杂命令,应该返回最关键的参数信息",
"返回的文本长度应该适中,避免过长",
],
},
updateModelValue: {
description: "更新组件的值并触发更新事件",
parameters: "argvs - 当前参数对象",
implementation: `
this.$emit("update:modelValue", {
...this.modelValue,
summary: this.getSummary(argvs),
code: this.generateCode(argvs),
argvs,
});
`,
notes: [
"必须保留原有的 modelValue 属性",
"必须包含 summary、code 和 argvs 三个字段",
"summary 用于在命令列表中显示",
"code 是生成的代码字符串",
"argvs 是当前的参数对象",
],
usage: [
"在 mounted 钩子中初始化组件值",
"在 argvs setter 中更新组件值",
"在任何需要更新组件值的地方调用",
],
},
},
mounted: {
description: "组件初始化时的处理",
implementation: `
// 如果没有 argvs 和 code使用默认值初始化
if (!this.modelValue.argvs && !this.modelValue.code) {
this.$emit("update:modelValue", {
...this.modelValue,
argvs: this.defaultArgvs,
code: this.generateCode(this.defaultArgvs)
});
}
`,
},
stringHandling: {
stringifyArgv: {
description: "将对象转换为代码字符串",
usage: "用于生成包含对象参数的代码",
example: "将 {key: 'value'} 转换为 '{key:\"value\"}'",
},
parseFunction: {
description: "解析函数调用代码为对象",
usage: "用于解析函数调用代码,支持变量格式的路径匹配",
parameters: {
functionStr: "要解析的函数调用代码字符串",
options: {
variableFormatPaths: "需要使用variable格式的路径模式数组",
},
},
pathPatterns: {
paramPosition: {
description: "参数位置匹配",
examples: [
"arg0 - 第一个参数",
"arg1 - 第二个参数",
"arg* - 任意参数",
],
},
objectProps: {
description: "对象属性匹配",
examples: [
"arg0.headers - 精确匹配",
"arg1.data.* - 直接子属性",
"arg2.params.** - 所有嵌套属性",
],
},
wildcards: {
description: "通配符使用",
examples: [
"* - 单层匹配",
"** - 多层匹配",
"Accept* - 前缀匹配",
],
},
exclusions: {
description: "排除规则",
examples: [
"!arg*.headers.Content-Type",
"!arg*.headers.Cookie",
],
},
},
example: `
const result = parseFunction(
'axios(url, { headers: { "User-Agent": ua } })',
{
variableFormatPaths: [
'arg0',
'arg*.headers.**',
'!arg*.headers.Content-Type'
]
}
);
`,
returns: {
functionName: "函数名称",
args: "解析后的参数数组,根据路径规则处理变量格式",
},
},
parseToHasType: {
description: "将字符串解析为带类型的值",
usage: "用于解析 VariableInput 类型的值",
example: "将 '\"text\"' 解析为 newVarInputVal('str', 'text')",
},
},
},
},
"5. Component Registration": {
location: "src/js/composer/cardComponents.js",
description: "使用defineAsyncComponent注册组件",
format:
"export const YourComponent = defineAsyncComponent(() => import('path/to/component'))",
},
"6. Command Configuration": {
location: "src/js/composer/commands/xxxCommands.js",
requiredFields: {
value: "quickcomposer.xxx.yyy",
label: "显示名称",
component: "组件名称",
},
optionalFields: {
desc: "命令描述",
isAsync: "是否异步命令",
isControlFlow: "是否控制流命令",
},
},
},
notes: {
variableHandling: {
description: "VariableInput 值的处理方式取决于参数类型",
cases: {
objectCase:
"当值在对象中时,使用 formatJsonVariables 处理,如 AxiosConfigEditor",
simpleCase: "当值是直接参数时,直接使用值本身,如 MultiParams",
},
tips: "formatJsonVariables 主要用于处理对象中的变量,避免对简单参数使用,以免产生不必要的引号",
},
commonComponents: {
description: "常用组件的使用说明",
components: {
VariableInput: {
description: "变量输入组件",
usage: "用于输入可能包含变量的字符串",
props: [
"model-value - 输入值,需要包含 value、isString、__varInputVal__ 属性, 通过 varInputValManager 的 newVarInputVal 创建",
"label - 输入框标签",
"icon - 输入框图标",
],
},
DictEditor: {
description: "键值对编辑组件",
usage: "用于编辑对象类型的配置,如 headers、env 等",
features: [
"自带添加/删除按钮",
"支持键值对编辑",
"值部分默认使用 VariableInput",
"支持下拉选项(通过 options.items 配置)",
],
notes: [
"初始值应该是一个对象,如 {}",
"支持通过 options 属性配置下拉选项",
],
},
NumberInput: {
description: "数字输入组件",
usage: "用于输入数字类型的配置",
props: [
"model-value - 数字值",
"label - 输入框标签",
"icon - 输入框图标",
],
},
},
},
dataFlow: {
description: "数据流转说明",
patterns: {
modelValue: {
description: "组件数据结构",
structure: {
value: "函数名,来自命令配置",
code: "生成的代码字符串",
argvs: "解析后的参数对象",
},
},
updateFlow: {
description: "数据更新流程",
steps: [
"1. 用户输入触发 update:model-value 事件",
"2. 组件内部更新 argvs",
"3. argvs 更新触发 generateCode",
"4. 发送完整的 modelValue 给父组件",
],
},
},
},
bestPractices: {
description: "最佳实践",
tips: [
"使用现有组件而不是重新开发",
"参考 axios 等成熟组件的实现",
"保持数据流的清晰和一致",
"合理使用计算属性和方法",
"避免直接修改 props",
"正确处理默认值",
],
},
commonPitfalls: {
description: "自定义组件开发中的常见错误和最佳实践",
componentRegistration: {
description: "组件注册相关注意事项",
tips: [
"组件名使用 PascalCase 命名,如 SystemCommandEditor",
"在 cardComponents.js 中注册时使用字符串形式,如 component: 'SystemCommandEditor'",
"不要在配置文件中导入组件",
"不要在配置文件中定义 defaultArgvs这应该只在组件内部定义",
],
},
codeGeneration: {
description: "代码生成相关注意事项",
tips: [
"使用 modelValue.value 获取函数名,避免硬编码",
"在 generateCode 中正确处理默认值的移除",
"正确定义 variableFormatPaths 以处理变量格式",
],
},
dataManagement: {
description: "数据管理相关注意事项",
tips: [
"使用 updateArgvs(key, value) 方法显式更新数据",
"在模板中使用 :model-value 和 @update:model-value 而不是 v-model",
"在 emit 时不需要提交 value 字段,因为这在 command 配置里已定义",
"使用 getter/setter 形式的 argvs 计算属性",
"在 mounted 和 updateArgvs 中保留原始字段 ...this.modelValue",
"处理嵌套对象更新时需要正确处理路径,如 'options.encoding' 需要分别更新 options 对象",
"更新嵌套对象时要保持对象的响应性,使用解构运算符复制对象",
],
},
performance: {
description: "性能优化相关注意事项",
tips: [
"避免使用过多的 watch 属性,容易造成性能问题",
"使用 computed 代替复杂的 watch",
"减少不必要的数据更新和重渲染",
"保持简单的 getter/setter 模式,避免复杂的嵌套对象更新",
],
},
componentStructure: {
description: "组件结构相关注意事项",
tips: [
"使用 data() 而不是 setup 来定义组件数据",
"在配置文件中的 value 应该包含完整路径,如 quickcomposer.system.exec",
"组件内部保持简单清晰的结构,避免过度复杂的逻辑",
],
},
},
},
examples: {
simpleComponent: "RegexEditor - 单一功能的组件",
complexComponent: "AxiosConfigEditor - 多功能、多配置的组件",
controlComponent: "ConditionalJudgment - 流程控制组件",
},
};