update ConnectSetting.vue
This commit is contained in:
@@ -5,9 +5,14 @@
|
||||
v-if="navBarStore.isShowing"
|
||||
class="nav-bar"
|
||||
:title="navBarStore.title"
|
||||
:left-arrow="!!navBarStore.canBack"
|
||||
@left-click="doBack"
|
||||
:left-arrow="!hasCustomLeft && !!navBarStore.canBack"
|
||||
@left-click="onLeftClick"
|
||||
>
|
||||
<template v-if="hasCustomLeft" #left>
|
||||
<div class="nav-extra nav-extra-left">
|
||||
<component :is="navBarStore.leftRenderer" />
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<div class="nav-extra">
|
||||
<component :is="navBarStore.rightRenderer" v-if="navBarStore.rightRenderer" />
|
||||
@@ -80,6 +85,8 @@ onUnmounted(() => {
|
||||
|
||||
// ---------- 导航返回 ----------
|
||||
|
||||
const hasCustomLeft = computed(() => !!navBarStore.leftRenderer);
|
||||
|
||||
function doBack(): void {
|
||||
if (navBarStore.backTo) {
|
||||
router.push(navBarStore.backTo);
|
||||
@@ -89,6 +96,14 @@ function doBack(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function onLeftClick(): void {
|
||||
if (hasCustomLeft.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
doBack();
|
||||
}
|
||||
|
||||
const navBarPadding = computed(() => {
|
||||
if (navBarStore.isShowing) {
|
||||
return `${navBarStore.height || 48}px`;
|
||||
@@ -202,6 +217,10 @@ const contentHeight = computed(() => {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.nav-extra-left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.router-view {
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
/>
|
||||
</section>
|
||||
<div v-else-if="pageLoading" class="loading-wrap">
|
||||
<t-loading text="Loading directory" />
|
||||
<t-loading text="Loading directory" />
|
||||
</div>
|
||||
<t-empty v-else description="Directory is empty" />
|
||||
<t-empty v-else description="Directory is empty" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -393,10 +393,4 @@ function getDirectoryKey(pathSegments: string[]): string {
|
||||
font-size: .8125rem;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) .page {
|
||||
.go-up {
|
||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .22);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,103 +1,84 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<section class="card">
|
||||
<div class="head">
|
||||
<p class="tag">连接配置</p>
|
||||
<h2 class="header">服务器连接</h2>
|
||||
<p class="desc">这里的配置会持久化保存,缺失时应用会强制回到连接引导页。</p>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<p class="label">协议</p>
|
||||
<div class="protocols">
|
||||
<t-button
|
||||
size="small"
|
||||
theme="primary"
|
||||
:variant="form.protocol === 'http' ? 'base' : 'outline'"
|
||||
@click="setProtocol('http')"
|
||||
>
|
||||
HTTP
|
||||
</t-button>
|
||||
<t-button
|
||||
size="small"
|
||||
theme="primary"
|
||||
:variant="form.protocol === 'https' ? 'base' : 'outline'"
|
||||
@click="setProtocol('https')"
|
||||
>
|
||||
HTTPS
|
||||
</t-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<p class="label">主机地址</p>
|
||||
<t-input v-model="form.host" clearable placeholder="例如 192.168.1.100 或 nas.local" />
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<p class="label">端口</p>
|
||||
<t-input v-model="form.port" clearable type="number" placeholder="例如 8080" />
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<p class="label">访问令牌</p>
|
||||
<t-input v-model="form.token" clearable placeholder="请输入 token" />
|
||||
</div>
|
||||
|
||||
<t-button block theme="primary" @click="saveConnect">
|
||||
保存连接配置
|
||||
</t-button>
|
||||
<t-button block variant="outline" @click="resetConnect">
|
||||
清空连接配置
|
||||
</t-button>
|
||||
</section>
|
||||
<div class="connect-setting">
|
||||
<t-cell-group title="服务器连接" theme="card">
|
||||
<t-cell title="使用 HTTPS">
|
||||
<template #rightIcon>
|
||||
<t-switch v-model="httpsEnabled" />
|
||||
</template>
|
||||
</t-cell>
|
||||
<t-input
|
||||
v-model.trim="form.host"
|
||||
clearable
|
||||
label="地址"
|
||||
placeholder="192.168.1.10 或 nas.local"
|
||||
/>
|
||||
<t-input
|
||||
v-model.trim="form.port"
|
||||
clearable
|
||||
label="端口"
|
||||
placeholder="8080"
|
||||
type="number"
|
||||
/>
|
||||
<t-input
|
||||
v-model.trim="form.token"
|
||||
clearable
|
||||
label="密钥"
|
||||
placeholder="请输入访问密钥"
|
||||
/>
|
||||
</t-cell-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import type { ConnectProtocol, ConnectSetting } from "@/store/settingStore";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import type { ConnectSetting } from "@/store/settingStore";
|
||||
import { useSettingStore } from "@/store/settingStore";
|
||||
|
||||
defineOptions({
|
||||
name: "ConnectSetting"
|
||||
});
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
const navBarStore = useNavBarStore();
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
const form = reactive<ConnectSetting>({
|
||||
protocol: "http",
|
||||
host: "",
|
||||
port: "",
|
||||
token: ""
|
||||
// ---------- 顶部导航 ----------
|
||||
|
||||
const navBarOwner = `connect-setting-${Math.random().toString(36).slice(2)}`;
|
||||
|
||||
const navBarLeftRenderer = defineComponent({
|
||||
name: "connect-setting-nav-left",
|
||||
setup() {
|
||||
const buttonComponent = resolveComponent("t-button");
|
||||
|
||||
return () => h(buttonComponent, {
|
||||
variant: "text",
|
||||
theme: "default",
|
||||
size: "small",
|
||||
onClick: cancelConnect
|
||||
}, () => "取消");
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => settingStore.connect,
|
||||
(connect) => {
|
||||
Object.assign(form, connect);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
const navBarRightRenderer = defineComponent({
|
||||
name: "connect-setting-nav-right",
|
||||
setup() {
|
||||
const buttonComponent = resolveComponent("t-button");
|
||||
|
||||
function setProtocol(protocol: ConnectProtocol): void {
|
||||
form.protocol = protocol;
|
||||
}
|
||||
|
||||
function validateConnect(): boolean {
|
||||
const host = form.host.trim();
|
||||
const port = form.port.trim();
|
||||
const token = form.token.trim();
|
||||
|
||||
if (!host || !port || !token) {
|
||||
Toast({
|
||||
theme: "warning",
|
||||
message: "请完整填写连接配置"
|
||||
});
|
||||
return false;
|
||||
return () => h(buttonComponent, {
|
||||
variant: "text",
|
||||
theme: "primary",
|
||||
size: "small",
|
||||
onClick: saveConnect
|
||||
}, () => "保存");
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
function cancelConnect(): void {
|
||||
Object.assign(form, settingStore.connect);
|
||||
router.back();
|
||||
}
|
||||
|
||||
function saveConnect(): void {
|
||||
@@ -112,69 +93,57 @@ function saveConnect(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function resetConnect(): void {
|
||||
settingStore.resetConnect();
|
||||
Object.assign(form, settingStore.connect);
|
||||
Toast({
|
||||
theme: "success",
|
||||
message: "连接配置已清空"
|
||||
});
|
||||
onMounted(() => {
|
||||
navBarStore.setLeftRenderer(navBarLeftRenderer, navBarOwner);
|
||||
navBarStore.setRightRenderer(navBarRightRenderer, navBarOwner);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
navBarStore.clearLeft(navBarOwner);
|
||||
navBarStore.clearRight(navBarOwner);
|
||||
});
|
||||
|
||||
// ---------- 表单 ----------
|
||||
|
||||
const form = reactive<ConnectSetting>({
|
||||
protocol: "http",
|
||||
host: "",
|
||||
port: "",
|
||||
token: ""
|
||||
});
|
||||
|
||||
watch(() => settingStore.connect, (connect) => {
|
||||
Object.assign(form, connect);
|
||||
}, { immediate: true });
|
||||
|
||||
const httpsEnabled = computed({
|
||||
get: () => form.protocol === "https",
|
||||
set: (value: boolean) => {
|
||||
form.protocol = value ? "https" : "http";
|
||||
}
|
||||
});
|
||||
|
||||
function validateConnect(): boolean {
|
||||
const host = form.host.trim();
|
||||
const port = form.port.trim();
|
||||
const token = form.token.trim();
|
||||
if (!host || !port || !token) {
|
||||
Toast({
|
||||
theme: "warning",
|
||||
message: "请完整填写连接配置"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.page {
|
||||
padding: 1rem;
|
||||
.connect-setting {
|
||||
padding-top: var(--app-nav-offset);
|
||||
|
||||
.card {
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
border-radius: 1rem;
|
||||
flex-direction: column;
|
||||
border: 1px solid var(--app-line);
|
||||
background: var(--app-card);
|
||||
box-shadow: 0 .35rem 1rem rgba(17, 32, 56, .05);
|
||||
}
|
||||
|
||||
.head,
|
||||
.group {
|
||||
gap: .5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.tag,
|
||||
.label,
|
||||
.desc {
|
||||
margin: 0;
|
||||
color: var(--app-sub);
|
||||
}
|
||||
|
||||
.tag,
|
||||
.label {
|
||||
font-size: .875rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.protocols {
|
||||
gap: .75rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) .page {
|
||||
.card {
|
||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
||||
:deep(.t-input:last-child:after) {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -256,10 +256,4 @@ function normalizeSecondValue(value: string, fallback: number): number {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) .page {
|
||||
.card {
|
||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -84,10 +84,4 @@ const themeModeList: Array<{ label: string; value: ThemeMode }> = [
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) .page {
|
||||
.card {
|
||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="connect-setting">
|
||||
<section class="card">
|
||||
<div class="head">
|
||||
<p class="tag">系统设置</p>
|
||||
@@ -42,7 +42,7 @@ function openThemeSetting(): void {
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.page {
|
||||
.connect-setting {
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
padding: 1rem;
|
||||
@@ -91,7 +91,7 @@ function openThemeSetting(): void {
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) .page {
|
||||
:global(.theme-dark) .connect-setting {
|
||||
.card {
|
||||
box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,8 @@ const router = createRouter({
|
||||
navBarVisible: true,
|
||||
navBarCanBack: true,
|
||||
navBarTitle: "连接配置",
|
||||
tabBarVisible: false
|
||||
tabBarVisible: false,
|
||||
bodyBackground: "#F4F4F4"
|
||||
},
|
||||
component: ConnectSetting
|
||||
},
|
||||
|
||||
@@ -8,6 +8,8 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
||||
const height = ref(0);
|
||||
const title = ref("");
|
||||
const backTo = ref<string>();
|
||||
const leftRenderer = shallowRef<Component>();
|
||||
const leftOwner = ref<string>();
|
||||
const rightRenderer = shallowRef<Component>();
|
||||
const rightOwner = ref<string>();
|
||||
|
||||
@@ -34,6 +36,20 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
||||
title.value = value || "";
|
||||
}
|
||||
|
||||
function setLeftRenderer(renderer?: Component, owner?: string): void {
|
||||
leftRenderer.value = renderer;
|
||||
leftOwner.value = owner;
|
||||
}
|
||||
|
||||
function clearLeft(owner?: string): void {
|
||||
if (owner && leftOwner.value !== owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
leftRenderer.value = undefined;
|
||||
leftOwner.value = undefined;
|
||||
}
|
||||
|
||||
function setRightRenderer(renderer?: Component, owner?: string): void {
|
||||
rightRenderer.value = renderer;
|
||||
rightOwner.value = owner;
|
||||
@@ -52,12 +68,15 @@ export const useNavBarStore = defineStore("nav-bar", () => {
|
||||
height,
|
||||
title,
|
||||
backTo,
|
||||
leftRenderer,
|
||||
rightRenderer,
|
||||
isShowing,
|
||||
canBack,
|
||||
setHeight,
|
||||
setBackTo,
|
||||
setTitle,
|
||||
setLeftRenderer,
|
||||
clearLeft,
|
||||
setRightRenderer,
|
||||
clearRight
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user