feat: 字母描红页样式开发基本完成

This commit is contained in:
R524809
2026-04-09 17:43:22 +08:00
parent 653737c481
commit a911da6181
59 changed files with 1043 additions and 206 deletions
@@ -32,6 +32,10 @@
flex-shrink: 0;
}
.nav-bar__back--hidden {
visibility: hidden;
}
.nav-bar__back-icon {
font-size: 40rpx;
color: @color-nav-title;
@@ -57,4 +61,4 @@
.nav-bar__placeholder {
width: 100%;
flex-shrink: 0;
}
}
+44 -9
View File
@@ -1,5 +1,13 @@
import { NAV_INNER_PX } from '../../utils/navMetrics';
const HOME_TAB_URL = '/pages/home/home';
const TAB_BAR_ROUTES = new Set([
'pages/home/home',
'pages/age/age',
'pages/favorites/favorites',
'pages/profile/profile',
]);
Component({
options: { multipleSlots: true },
properties: {
@@ -9,26 +17,53 @@ Component({
data: {
statusBarHeight: 0,
navBlockHeight: 0,
showBackButton: false,
leftActionType: 'none',
},
lifetimes: {
attached() {
const { statusBarHeight } = wx.getWindowInfo();
const pages = getCurrentPages();
this.setData({
statusBarHeight,
navBlockHeight: statusBarHeight + NAV_INNER_PX,
showBackButton: pages.length > 1,
});
this.syncLeftAction();
},
},
pageLifetimes: {
show() {
this.syncLeftAction();
},
},
methods: {
handleBack() {
wx.navigateBack({
fail: () => {
wx.switchTab({ url: '/pages/home/home' });
},
});
syncLeftAction() {
const pages = getCurrentPages();
const currentRoute = pages[pages.length - 1]?.route || '';
const isTabBarPage = TAB_BAR_ROUTES.has(currentRoute);
let leftActionType: 'none' | 'back' | 'home' = 'none';
if (pages.length > 1) {
leftActionType = 'back';
} else if (!isTabBarPage) {
leftActionType = 'home';
}
this.setData({ leftActionType });
},
handleLeftAction() {
if (this.data.leftActionType === 'back') {
wx.navigateBack({
fail: () => {
wx.switchTab({ url: HOME_TAB_URL });
},
});
return;
}
if (this.data.leftActionType === 'home') {
wx.switchTab({ url: HOME_TAB_URL });
}
},
},
});
+11 -5
View File
@@ -1,10 +1,16 @@
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px; {{background ? 'background:' + background + ';' : ''}}">
<view
class="nav-bar"
style="padding-top: {{statusBarHeight}}px; {{background ? 'background:' + background + ';' : ''}}">
<view class="nav-bar__inner">
<view
wx:if="{{showBackButton}}"
class="nav-bar__back"
bindtap="handleBack">
<text class="toy-icon toy-icon-arrow-left nav-bar__back-icon"></text>
class="nav-bar__back {{leftActionType === 'none' ? 'nav-bar__back--hidden' : ''}}"
bindtap="handleLeftAction">
<text
wx:if="{{leftActionType === 'back'}}"
class="toy-icon toy-icon-arrow-left nav-bar__back-icon"></text>
<text
wx:elif="{{leftActionType === 'home'}}"
class="toy-icon toy-icon-home-o nav-bar__back-icon"></text>
</view>
<slot name="left"></slot>
<text class="nav-bar__title">{{title}}</text>
@@ -6,7 +6,8 @@
bottom: 0;
width: 100%;
padding: 0 24rpx;
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
// padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
z-index: 60;
@@ -22,23 +23,27 @@
gap: 16rpx;
}
/* flex 子项:占宽比例;min-width:0 避免子项溢出时把 flex 算崩 */
&__secondary {
flex: 4;
flex: 3.92;
min-width: 0;
}
&__primary {
flex: 6;
flex: 6.18;
min-width: 0;
}
&__secondary .toy-btn,
&__primary .toy-btn {
width: 100%;
height: 88rpx;
/*
* 以下类通过 toy-button 的 custom-class 作用在内部原生 button 上。
* 不能写 &__primary .toy-btn:小程序样式无法穿透进子自定义组件。
*/
.preview-footer-actions__toy-btn {
border-radius: 28rpx;
font-size: 30rpx;
}
&__primary .toy-btn--primary {
.preview-footer-actions__toy-btn--primary {
box-shadow: 0 4rpx 12rpx rgba(255, 215, 0, 0.3);
}
}
@@ -9,12 +9,21 @@ Component({
properties: {
primaryText: {
type: String,
value: '保存到作品库',
value: '保存到相册',
},
primaryIcon: {
type: String,
value: 'download',
},
secondaryText: {
type: String,
value: '分享',
},
/** 须对应 iconfont 中 toy-icon-{name};历史上常用 wechat 已映射为 wechat-o */
secondaryIcon: {
type: String,
value: 'line-share',
},
disabled: {
type: Boolean,
value: false,
@@ -28,7 +37,31 @@ Component({
value: 'share',
},
},
data: {
/** 经归一化后的图标名,供 wxml 绑定(避免父级传 wechat 等 iconfont 中不存在的 name */
resolvedSecondaryIcon: 'line-share',
},
observers: {
secondaryIcon() {
this.syncSecondaryIconGlyph();
},
},
lifetimes: {
attached() {
this.syncSecondaryIconGlyph();
},
},
methods: {
syncSecondaryIconGlyph() {
const raw = (this.data.secondaryIcon ?? '').trim();
const aliases: Record<string, string> = {
wechat: 'wechat-o',
};
const name = aliases[raw] || raw;
this.setData({
resolvedSecondaryIcon: name || 'line-share',
});
},
onPrimaryTap() {
if (this.data.disabled || this.data.loading) return;
this.triggerEvent('primary');
@@ -1,23 +1,33 @@
<view class="preview-footer-actions">
<view class="preview-footer-actions__bar">
<toy-button
class="preview-footer-actions__secondary"
type="secondary"
icon="line-share"
icon-size="40rpx"
open-type="{{ shareOpenType }}"
bind:click="onSecondaryTap">
{{ secondaryText }}
</toy-button>
<toy-button
class="preview-footer-actions__primary"
type="primary"
icon="download"
icon-size="40rpx"
disabled="{{ disabled }}"
loading="{{ loading }}"
bind:click="onPrimaryTap">
{{ primaryText }}
</toy-button>
<view class="preview-footer-actions__secondary">
<toy-button
type="secondary"
icon="{{ resolvedSecondaryIcon }}"
icon-size="40rpx"
block
width="100%"
height="88rpx"
open-type="{{ shareOpenType }}"
custom-class="preview-footer-actions__toy-btn"
bind:click="onSecondaryTap">
{{ secondaryText }}
</toy-button>
</view>
<view class="preview-footer-actions__primary">
<toy-button
type="primary"
icon="{{ primaryIcon }}"
icon-size="40rpx"
block
width="100%"
height="88rpx"
disabled="{{ disabled }}"
loading="{{ loading }}"
custom-class="preview-footer-actions__toy-btn preview-footer-actions__toy-btn--primary"
bind:click="onPrimaryTap">
{{ primaryText }}
</toy-button>
</view>
</view>
</view>