update ConnectSetting.vue

This commit is contained in:
Timi
2026-04-13 16:11:37 +08:00
parent a6c89717a6
commit 753ab56e06
8 changed files with 155 additions and 165 deletions

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -131,7 +131,8 @@ const router = createRouter({
navBarVisible: true,
navBarCanBack: true,
navBarTitle: "连接配置",
tabBarVisible: false
tabBarVisible: false,
bodyBackground: "#F4F4F4"
},
component: ConnectSetting
},

View File

@@ -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
};