路由页动效与细节一批

基调是简单快速:hover 颜色 0.15s 过渡(全局规则,只过渡颜色不碰布局)、
对话框入场淡入加 6px 上移、tab 下划线改成共享的一条并在切换时滑动、tab
内容 out-in 淡切、配置折叠箭头居右随展开旋转 90 度、订阅下拉 0.12s 出入场。
不引 animate.css:这些效果各自十几行 CSS,引库只多不少。

配置展开和拨开链式代理时,若详情底部长出窗口则平滑滚进视野;tab 切换
不触发,来回切时页面跟着跳只会晕。二次确认对话框点遮罩可关闭,内边距
挪进内层,否则点在 dialog 自己的 padding 上也会被当成遮罩。新增入站的
表单不做遮罩关闭:误点会丢掉填了一半的内容。对话框标题改为「新增路由」
「编辑路由」。select 换自绘箭头,原生箭头贴边且位置调不了。
This commit is contained in:
2026-08-11 16:23:03 +08:00
parent a44f410074
commit de3a4c9bcd
6 changed files with 222 additions and 65 deletions
+25 -7
View File
@@ -25,28 +25,46 @@ watch(
else dialog.value?.close()
},
)
/** 点在遮罩上就关闭。内容区的点击 target 是 .body 里的元素,到不了 dialog 本身。 */
function onBackdrop(event: MouseEvent) {
if (event.target === dialog.value) emit('close')
}
</script>
<template>
<dialog ref="dialog" class="dlg" @close="emit('close')" @cancel.prevent="emit('close')">
<p class="msg">{{ message }}</p>
<footer class="acts">
<button type="button" class="btn" @click="emit('close')">取消</button>
<button type="button" class="btn go" @click="emit('confirm')">{{ action }}</button>
</footer>
<dialog
ref="dialog"
class="dlg"
@click="onBackdrop"
@close="emit('close')"
@cancel.prevent="emit('close')"
>
<div class="body">
<p class="msg">{{ message }}</p>
<footer class="acts">
<button type="button" class="btn" @click="emit('close')">取消</button>
<button type="button" class="btn go" @click="emit('confirm')">{{ action }}</button>
</footer>
</div>
</dialog>
</template>
<style scoped>
.dlg {
width: min(400px, calc(100vw - 2 * var(--s-5)));
padding: var(--s-5);
/* 内边距放在 .body 上:dialog 自己的内边距区域点了会被当成遮罩点击 */
padding: 0;
border: 1px solid var(--c-border-strong);
border-radius: var(--r-lg);
background: var(--c-surface);
color: var(--c-text);
}
.body {
padding: var(--s-5);
}
.dlg::backdrop {
background: rgb(0 0 0 / 0.45);
}
+3
View File
@@ -100,6 +100,9 @@ function delayClass(ms: number | null): string {
border: 1px solid var(--c-border);
border-radius: var(--r-sm);
background: var(--c-surface-sunken);
transition:
border-color 0.15s ease,
background-color 0.15s ease;
}
.card.tone-chain {
+18 -2
View File
@@ -92,7 +92,8 @@ function onFocusOut(event: FocusEvent) {
/>
</div>
<ul v-if="open" class="menu" role="listbox" aria-multiselectable="true">
<Transition name="menu">
<ul v-if="open" class="menu" role="listbox" aria-multiselectable="true">
<li v-if="options.length === 0" class="none">没有可选的订阅</li>
<li v-else-if="filtered.length === 0" class="none">没有匹配的订阅</li>
<li v-for="(name, i) in filtered" :key="name">
@@ -108,7 +109,8 @@ function onFocusOut(event: FocusEvent) {
{{ name }}
</button>
</li>
</ul>
</ul>
</Transition>
</div>
</template>
@@ -128,6 +130,7 @@ function onFocusOut(event: FocusEvent) {
border-radius: var(--r-sm);
background: var(--c-surface);
cursor: text;
transition: border-color 0.15s ease;
}
.box:focus-within {
@@ -230,4 +233,17 @@ function onFocusOut(event: FocusEvent) {
color: var(--c-text-faint);
font-size: var(--t-sm);
}
.menu-enter-active,
.menu-leave-active {
transition:
opacity 0.12s ease,
transform 0.12s ease;
}
.menu-enter-from,
.menu-leave-to {
opacity: 0;
transform: translateY(-4px);
}
</style>