mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 14:34:13 +08:00
优化Axios界面及布局
This commit is contained in:
parent
28f034814b
commit
15ad67a753
@ -6,15 +6,7 @@
|
||||
<div class="col-3">
|
||||
<q-select
|
||||
v-model="localConfig.method"
|
||||
:options="[
|
||||
'GET',
|
||||
'POST',
|
||||
'PUT',
|
||||
'DELETE',
|
||||
'PATCH',
|
||||
'HEAD',
|
||||
'OPTIONS',
|
||||
]"
|
||||
:options="methods"
|
||||
label="请求方法"
|
||||
dense
|
||||
filled
|
||||
@ -39,183 +31,130 @@
|
||||
</div>
|
||||
<!-- 响应设置 -->
|
||||
<div class="col-12">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-3">
|
||||
<q-select
|
||||
v-model="localConfig.responseType"
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
map-options
|
||||
:options="['json', 'text', 'blob', 'arraybuffer']"
|
||||
label="响应类型"
|
||||
@update:model-value="updateConfig"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="data_object" />
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VariableInput
|
||||
v-model="localConfig.maxRedirects"
|
||||
label="最大重定向次数"
|
||||
:command="{ icon: 'repeat', inputType: 'number' }"
|
||||
<q-tabs
|
||||
v-model="activeTab"
|
||||
dense
|
||||
class="text-grey q-py-none"
|
||||
active-color="primary"
|
||||
indicator-color="primary"
|
||||
align="justify"
|
||||
narrow-indicator
|
||||
inline-label
|
||||
>
|
||||
<q-tab
|
||||
v-for="tab in visibleTabs"
|
||||
:key="tab.name"
|
||||
:name="tab.name"
|
||||
class="q-px-xs text-caption"
|
||||
style="min-height: 32px"
|
||||
>
|
||||
<template v-slot:default>
|
||||
<div class="row items-center no-wrap">
|
||||
<q-icon :name="tab.icon" size="16px" />
|
||||
<div class="text-caption q-ml-xs" style="font-size: 11px">
|
||||
{{ tab.label }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</q-tab>
|
||||
</q-tabs>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="activeTab" animated class="q-px-none">
|
||||
<!-- Headers tab -->
|
||||
<q-tab-panel name="headers" class="q-pa-sm">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-12">
|
||||
<q-select
|
||||
v-model="localConfig.headers['Content-Type']"
|
||||
label="Content-Type"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
:options="contentTypes"
|
||||
@update:model-value="updateConfig"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="data_object" />
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<VariableInput
|
||||
v-model="localConfig.headers['User-Agent']"
|
||||
label="User Agent"
|
||||
:command="{ icon: 'devices' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto flex items-center">
|
||||
<q-btn-dropdown flat dense dropdown-icon="menu">
|
||||
<q-list>
|
||||
<q-item
|
||||
v-for="ua in userAgentOptions"
|
||||
:key="ua.value"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="setUserAgent(ua.value)"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ ua.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<DictEditor
|
||||
v-model="otherHeaders"
|
||||
:options="{
|
||||
items: commonHeaderOptions,
|
||||
}"
|
||||
@update:model-value="updateHeaders"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
|
||||
<!-- 请求体和URL参数 tabs -->
|
||||
<q-tab-panel v-if="hasRequestData" name="data" class="q-pa-sm">
|
||||
<DictEditor
|
||||
v-model="localConfig.data"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VariableInput
|
||||
v-model="localConfig.timeout"
|
||||
label="超时时间(ms)"
|
||||
:command="{ icon: 'timer', inputType: 'number' }"
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="params" class="q-pa-sm">
|
||||
<DictEditor
|
||||
v-model="localConfig.params"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
|
||||
<!-- Headers -->
|
||||
<!-- Content-Type -->
|
||||
<q-select
|
||||
v-model="localConfig.headers['Content-Type']"
|
||||
label="Content-Type"
|
||||
dense
|
||||
filled
|
||||
emit-value
|
||||
map-options
|
||||
:options="contentTypes"
|
||||
class="col-12"
|
||||
@update:model-value="updateConfig"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="data_object" />
|
||||
</template>
|
||||
</q-select>
|
||||
<!-- User-Agent -->
|
||||
<div class="col-12 row q-col-gutter-sm">
|
||||
<div class="col">
|
||||
<VariableInput
|
||||
v-model="localConfig.headers['User-Agent']"
|
||||
label="User Agent"
|
||||
:command="{ icon: 'devices' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto flex items-center">
|
||||
<q-btn-dropdown flat dense dropdown-icon="menu">
|
||||
<q-list>
|
||||
<q-item
|
||||
v-for="ua in userAgentOptions"
|
||||
:key="ua.value"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="setUserAgent(ua.value)"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ ua.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 请求体 -->
|
||||
<div v-if="hasRequestData" class="col-12">
|
||||
<BorderLabel label="请求体" :modelValue="false">
|
||||
<DictEditor
|
||||
v-model="localConfig.data"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
|
||||
<!-- Other Headers -->
|
||||
<div class="col-12">
|
||||
<BorderLabel label="Headers">
|
||||
<DictEditor
|
||||
v-model="otherHeaders"
|
||||
:options="{
|
||||
items: commonHeaderOptions,
|
||||
}"
|
||||
@update:model-value="updateHeaders"
|
||||
/>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
|
||||
<!-- 请求参数 -->
|
||||
<div class="col-12">
|
||||
<BorderLabel label="URL参数">
|
||||
<DictEditor
|
||||
v-model="localConfig.params"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
|
||||
<!-- 认证信息 -->
|
||||
<div class="col-12">
|
||||
<BorderLabel label="HTTP认证">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-6">
|
||||
<VariableInput
|
||||
v-model="localConfig.auth.username"
|
||||
label="用户名"
|
||||
:command="{ icon: 'person' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<VariableInput
|
||||
v-model="localConfig.auth.password"
|
||||
label="密码"
|
||||
:command="{ icon: 'password' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</BorderLabel>
|
||||
</div>
|
||||
|
||||
<!-- 代理设置 -->
|
||||
<div class="col-12">
|
||||
<BorderLabel label="代理设置">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-3">
|
||||
<VariableInput
|
||||
v-model="localConfig.proxy.host"
|
||||
label="主机"
|
||||
:command="{ icon: 'dns' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<VariableInput
|
||||
v-model="localConfig.proxy.port"
|
||||
label="端口"
|
||||
:command="{ icon: 'router', inputType: 'number' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<VariableInput
|
||||
v-model="localConfig.proxy.auth.username"
|
||||
label="用户名"
|
||||
:command="{ icon: 'person' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<VariableInput
|
||||
v-model="localConfig.proxy.auth.password"
|
||||
label="密码"
|
||||
:command="{ icon: 'password' }"
|
||||
@update:model-value="updateConfig"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</BorderLabel>
|
||||
<!-- 其他通用 panels -->
|
||||
<template v-for="panel in commonPanels" :key="panel.name">
|
||||
<q-tab-panel :name="panel.name" class="q-pa-sm">
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div
|
||||
v-for="field in panel.fields"
|
||||
:key="field.key"
|
||||
:class="field.colClass || 'col-4'"
|
||||
>
|
||||
<component
|
||||
:is="field.component"
|
||||
:modelValue="getFieldValue(field.key)"
|
||||
v-bind="field.props"
|
||||
@update:modelValue="(val) => setFieldValue(field.key, val)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
</template>
|
||||
</q-tab-panels>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -225,15 +164,19 @@ import { defineComponent } from "vue";
|
||||
import VariableInput from "components/composer/ui/VariableInput.vue";
|
||||
import DictEditor from "components/composer/ui/DictEditor.vue";
|
||||
import { formatJsonVariables } from "js/composer/formatString";
|
||||
import { userAgent, commonHeaders, contentTypes } from "js/options/httpHeaders";
|
||||
import BorderLabel from "components/composer/ui/BorderLabel.vue";
|
||||
import {
|
||||
userAgent,
|
||||
commonHeaders,
|
||||
contentTypes,
|
||||
methods,
|
||||
responseTypes,
|
||||
} from "js/options/httpOptions";
|
||||
|
||||
export default defineComponent({
|
||||
name: "AxiosConfigEditor",
|
||||
components: {
|
||||
VariableInput,
|
||||
DictEditor,
|
||||
BorderLabel,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
@ -267,7 +210,8 @@ export default defineComponent({
|
||||
url: "",
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"User-Agent": userAgent[0].value,
|
||||
"Content-Type": contentTypes[0].value,
|
||||
},
|
||||
params: {},
|
||||
data: {},
|
||||
@ -288,12 +232,147 @@ export default defineComponent({
|
||||
},
|
||||
...initialConfig,
|
||||
},
|
||||
methods,
|
||||
userAgentOptions: userAgent,
|
||||
contentTypes,
|
||||
commonHeaderOptions: commonHeaders
|
||||
.filter((h) => !["User-Agent", "Content-Type"].includes(h.value))
|
||||
.map((h) => h.value),
|
||||
otherHeaders: {},
|
||||
activeTab: "headers",
|
||||
commonPanels: [
|
||||
{
|
||||
name: "response",
|
||||
fields: [
|
||||
{
|
||||
key: "responseType",
|
||||
component: "q-select",
|
||||
props: {
|
||||
label: "响应类型",
|
||||
filled: true,
|
||||
dense: true,
|
||||
"emit-value": true,
|
||||
"map-options": true,
|
||||
options: responseTypes,
|
||||
"prepend-icon": "data_object",
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "maxRedirects",
|
||||
component: "VariableInput",
|
||||
props: {
|
||||
label: "最大重定向次数",
|
||||
command: { icon: "repeat", inputType: "number" },
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "timeout",
|
||||
component: "VariableInput",
|
||||
props: {
|
||||
label: "超时时间(ms)",
|
||||
command: { icon: "timer", inputType: "number" },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "auth",
|
||||
fields: [
|
||||
{
|
||||
key: "auth.username",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "用户名",
|
||||
command: { icon: "person" },
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "auth.password",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "密码",
|
||||
command: { icon: "password" },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "proxy",
|
||||
fields: [
|
||||
{
|
||||
key: "proxy.host",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "主机",
|
||||
command: { icon: "dns" },
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "proxy.port",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "端口",
|
||||
command: { icon: "router", inputType: "number" },
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "proxy.auth.username",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "用户名",
|
||||
command: { icon: "person" },
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "proxy.auth.password",
|
||||
component: "VariableInput",
|
||||
colClass: "col-6",
|
||||
props: {
|
||||
label: "密码",
|
||||
command: { icon: "password" },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
tabs: [
|
||||
{
|
||||
name: "headers",
|
||||
icon: "list_alt",
|
||||
label: "请求头",
|
||||
},
|
||||
{
|
||||
name: "data",
|
||||
icon: "data_object",
|
||||
label: "请求体",
|
||||
condition: () => this.hasRequestData,
|
||||
},
|
||||
{
|
||||
name: "params",
|
||||
icon: "link",
|
||||
label: "URL参数",
|
||||
},
|
||||
{
|
||||
name: "response",
|
||||
icon: "settings",
|
||||
label: "响应",
|
||||
},
|
||||
{
|
||||
name: "auth",
|
||||
icon: "security",
|
||||
label: "认证",
|
||||
},
|
||||
{
|
||||
name: "proxy",
|
||||
icon: "dns",
|
||||
label: "代理",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@ -306,6 +385,9 @@ export default defineComponent({
|
||||
hasRequestData() {
|
||||
return ["PUT", "POST", "PATCH"].includes(this.localConfig.method);
|
||||
},
|
||||
visibleTabs() {
|
||||
return this.tabs.filter((tab) => !tab.condition || tab.condition());
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateConfig() {
|
||||
@ -341,6 +423,16 @@ export default defineComponent({
|
||||
this.localConfig.headers["User-Agent"] = value;
|
||||
this.updateConfig();
|
||||
},
|
||||
getFieldValue(path) {
|
||||
return path.split(".").reduce((obj, key) => obj?.[key], this.localConfig);
|
||||
},
|
||||
setFieldValue(path, value) {
|
||||
const keys = path.split(".");
|
||||
const lastKey = keys.pop();
|
||||
const target = keys.reduce((obj, key) => obj[key], this.localConfig);
|
||||
target[lastKey] = value;
|
||||
this.updateConfig();
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue: {
|
||||
|
@ -67,7 +67,7 @@
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { userAgent } from "js/options/httpHeaders";
|
||||
import { userAgent } from "js/options/httpOptions";
|
||||
import VariableInput from "components/composer/ui/VariableInput.vue";
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { deviceName } from "js/options/httpHeaders";
|
||||
import { deviceName } from "js/options/httpOptions";
|
||||
import VariableInput from "components/composer/ui/VariableInput.vue";
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -113,3 +113,15 @@ export const contentTypes = [
|
||||
value: "application/octet-stream",
|
||||
},
|
||||
];
|
||||
|
||||
export const methods = [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
"PATCH",
|
||||
"HEAD",
|
||||
"OPTIONS",
|
||||
];
|
||||
|
||||
export const responseTypes = ["json", "text", "blob", "arraybuffer"];
|
Loading…
x
Reference in New Issue
Block a user