feat(diy-card): 增加可配置的外边距和头部样式属性
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<view data-component-name="diy-card-entry" class="diy-card-entry" :class="'entry-' + stylePreset" :style="wrapStyle" hover-class="entry-press" @tap="goLink">
|
||||
<view data-component-name="diy-card-entry" class="diy-card-entry" :class="['entry-' + stylePreset, { 'entry-center': isCenter }]" :style="wrapStyle" hover-class="entry-press" @tap="goLink">
|
||||
<!-- 图标装饰(可选) -->
|
||||
<view v-if="showIcon" class="entry-icon" :style="iconWrapStyle">
|
||||
<image v-if="iconType === 'image' && iconImage" class="icon-img" :src="$util.img(iconImage)" mode="aspectFit" />
|
||||
<text v-else class="icon-glyph">{{ iconGlyph || '💼' }}</text>
|
||||
<text v-else class="icon-glyph" :style="iconGlyphStyle">{{ iconGlyph || '名' }}</text>
|
||||
</view>
|
||||
|
||||
<view class="entry-body">
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
},
|
||||
wrapStyle() {
|
||||
const v = this.v;
|
||||
const radius = px2rpx(num(v.borderRadius, CardTokens.radius.md)) + 'rpx';
|
||||
const radius = px2rpx(num(v.borderRadius, 12)) + 'rpx';
|
||||
const pad = px2rpx(num(v.padding, CardTokens.space.lg)) + 'rpx';
|
||||
if (this.isMinimal) {
|
||||
return this.$util.objToStyle({
|
||||
@@ -91,13 +91,18 @@ export default {
|
||||
background: v.bgColorStart || CardTokens.color.primary,
|
||||
borderRadius: radius,
|
||||
padding: pad,
|
||||
borderLeft: '8rpx solid ' + (v.bgColorEnd || 'rgba(255,255,255,0.35)'),
|
||||
borderLeft: '8rpx solid ' + (v.bgColorEnd || '#1E40AF'),
|
||||
minHeight: '120rpx',
|
||||
});
|
||||
},
|
||||
iconWrapStyle() {
|
||||
return this.$util.objToStyle({
|
||||
background: this.isGradient || !this.isMinimal ? 'rgba(255,255,255,0.18)' : 'rgba(47,107,255,0.10)',
|
||||
background: this.isMinimal ? 'rgba(47,107,255,0.10)' : 'rgba(255,255,255,0.18)',
|
||||
});
|
||||
},
|
||||
iconGlyphStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.textColor || (this.isMinimal ? CardTokens.color.text : '#FFFFFF'),
|
||||
});
|
||||
},
|
||||
titleStyle() {
|
||||
@@ -110,7 +115,7 @@ export default {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.textColor || (this.isMinimal ? CardTokens.color.textSub : '#FFFFFF'),
|
||||
fontSize: px2rpx(num(this.v.subSize, 12)) + 'rpx',
|
||||
opacity: this.isMinimal ? 1 : 0.85,
|
||||
opacity: this.isMinimal ? 0.65 : 0.85,
|
||||
});
|
||||
},
|
||||
btnStyle() {
|
||||
@@ -142,7 +147,10 @@ export default {
|
||||
return this.$util.objToStyle({ color: v.accentColor || '#FFEB3B', fontSize: fontSize });
|
||||
}
|
||||
if (this.buttonStyle === 'link') {
|
||||
return this.$util.objToStyle({ color: v.textColor || CardTokens.color.primary, fontSize: fontSize });
|
||||
return this.$util.objToStyle({
|
||||
color: this.isMinimal ? (v.accentColor || '#FFEB3B') : (v.textColor || '#FFFFFF'),
|
||||
fontSize: fontSize,
|
||||
});
|
||||
}
|
||||
return this.$util.objToStyle({ color: '#333333', fontSize: fontSize });
|
||||
},
|
||||
@@ -152,7 +160,7 @@ export default {
|
||||
*/
|
||||
btnArrowStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.textColor || CardTokens.color.primary,
|
||||
color: this.isMinimal ? (this.v.accentColor || '#FFEB3B') : (this.v.textColor || '#FFFFFF'),
|
||||
fontSize: px2rpx(num(this.v.btnSize, 12) + 2) + 'rpx',
|
||||
});
|
||||
},
|
||||
|
||||
@@ -124,13 +124,13 @@ export default {
|
||||
wallStyle() {
|
||||
return this.$util.objToStyle({
|
||||
background: this.v.bgColor || CardTokens.color.bg,
|
||||
borderRadius: px2rpx(num(this.v.borderRadius, CardTokens.radius.md)) + 'rpx',
|
||||
borderRadius: px2rpx(num(this.v.borderRadius, 12)) + 'rpx',
|
||||
padding: px2rpx(num(this.v.padding, CardTokens.space.md)) + 'rpx',
|
||||
});
|
||||
},
|
||||
titleStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.titleColor || CardTokens.color.text,
|
||||
color: this.v.titleColor || '#333333',
|
||||
fontSize: px2rpx(num(this.v.titleSize, 16)) + 'rpx',
|
||||
});
|
||||
},
|
||||
@@ -151,20 +151,20 @@ export default {
|
||||
/** 网格/列表卡片信息行: 字号可配(默认 11px = 22rpx) */
|
||||
metaStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.infoColor || CardTokens.color.textSub,
|
||||
color: this.v.infoColor || '#888888',
|
||||
fontSize: px2rpx(num(this.v.infoSize, 11)) + 'rpx',
|
||||
});
|
||||
},
|
||||
/** 横滑竖卡信息行: 比网格小一档(默认 10px = 20rpx, 与历史渲染一致) */
|
||||
scrollMetaStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: this.v.infoColor || CardTokens.color.textSub,
|
||||
color: this.v.infoColor || '#888888',
|
||||
fontSize: px2rpx(num(this.v.infoSize, 11) - 1) + 'rpx',
|
||||
});
|
||||
},
|
||||
/** infoColor 纯色(箭头/空态用, 不带字号) */
|
||||
infoStyle() {
|
||||
return this.$util.objToStyle({ color: this.v.infoColor || CardTokens.color.textSub });
|
||||
return this.$util.objToStyle({ color: this.v.infoColor || '#888888' });
|
||||
},
|
||||
countStyle() {
|
||||
return this.$util.objToStyle({
|
||||
@@ -211,12 +211,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 列表项最终样式: itemStyle + 逐项入场动画延迟 合并输出单对象。
|
||||
* uni-app 运行时会静默丢弃 :style="[A, B]" 数组绑定(2026-10-24 mini.vue
|
||||
* 操作区同根因修复的先例), 数组形态禁止回归
|
||||
* 列表项最终样式: itemStyle 字符串 + 逐项入场动画延迟合并输出单字符串。
|
||||
* 不能用 Object.assign 展开样式字符串(会拆成字符索引),也不能绑定样式数组。
|
||||
*/
|
||||
itemFinalStyle(index) {
|
||||
return Object.assign({}, this.itemStyle, { animationDelay: (index * 60) + 'ms' });
|
||||
return ((this.itemStyle || '') + ' animation-delay: ' + (index * 60) + 'ms;').trim();
|
||||
},
|
||||
initialOf,
|
||||
avatarStyle(item) {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- 名片卡(精品名片 show 同款版式: 蓝底顶带 + 白卡压边; 角标压在左上) -->
|
||||
<view v-else class="mini-card-wrap">
|
||||
<view v-if="bandShow" class="mini-band" :style="bandStyle"></view>
|
||||
<view class="mini-card fade-up" :style="wrapStyle" :class="{ 'qr-at-corner': qrPos === 'corner' }">
|
||||
<view class="mini-card fade-up" :style="wrapStyle" :class="{ 'qr-at-corner': showQrCorner }">
|
||||
<!-- 角标插槽(如 self 组件的「我的名片」) -->
|
||||
<view class="mini-badge-slot">
|
||||
<slot name="badge"></slot>
|
||||
@@ -267,18 +267,16 @@ export default {
|
||||
},
|
||||
wrapStyle() {
|
||||
const c = this.c;
|
||||
const style = {
|
||||
return this.$util.objToStyle({
|
||||
background: flagOn(c.useCover, false) && this.card && this.card.cover ? 'transparent' : (c.bgColor || CardTokens.color.bg),
|
||||
borderRadius: px2rpx(num(c.borderRadius, CardTokens.radius.md)) + 'rpx',
|
||||
padding: px2rpx(num(c.padding, CardTokens.space.lg)) + 'rpx',
|
||||
marginTop: px2rpx(num(c.wrapMarginTop, 0)) + 'rpx',
|
||||
marginRight: px2rpx(num(c.wrapMarginRight, 0)) + 'rpx',
|
||||
marginBottom: px2rpx(num(c.wrapMarginBottom, 0)) + 'rpx',
|
||||
marginLeft: px2rpx(num(c.wrapMarginLeft, 0)) + 'rpx',
|
||||
boxShadow: flagOn(c.showShadow, true) ? CardTokens.shadow.card : 'none',
|
||||
};
|
||||
// 2.19.11: 外边距可配
|
||||
const mt = num(c.wrapMarginTop, 0);
|
||||
const mb = num(c.wrapMarginBottom, 0);
|
||||
if (mt > 0) style.marginTop = px2rpx(mt) + 'rpx';
|
||||
if (mb > 0) style.marginBottom = px2rpx(mb) + 'rpx';
|
||||
return this.$util.objToStyle(style);
|
||||
});
|
||||
},
|
||||
showCover() {
|
||||
return flagOn(this.c.useCover, false) && !!(this.card && this.card.cover);
|
||||
@@ -287,8 +285,8 @@ export default {
|
||||
return flagOn(this.c.showGradient, false);
|
||||
},
|
||||
showLogo() {
|
||||
// corner 档二维码占右上同一位, Logo 自动避让(面板有提示)
|
||||
return flagOn(this.c.showLogo, false) && this.qrPos !== 'corner';
|
||||
// 只有 corner 二维码实际显示时才避让;关闭二维码或无码源不隐藏 Logo。
|
||||
return flagOn(this.c.showLogo, false) && !this.showQrCorner;
|
||||
},
|
||||
showActs() {
|
||||
return flagOn(this.c.showQuick, true);
|
||||
@@ -414,22 +412,33 @@ export default {
|
||||
return normalizeHeadStyle(this.c.headStyle) === 'theme';
|
||||
},
|
||||
/**
|
||||
* theme 档头部块: 渐变通铺卡边(负 margin 抵消 wrapStyle 的 padding, WXSS 不用 calc)
|
||||
* 内部左右 padding = 卡片原 padding, 保证头像与下方资料行左缘对齐
|
||||
* 头部容器样式(plain/theme 共用)。未开启自定义间距时完整保留历史布局:
|
||||
* theme 负外边距抵消卡片 padding,plain 不额外设置间距。
|
||||
*/
|
||||
headThemeStyle() {
|
||||
const pad = px2rpx(num(this.c.padding, CardTokens.space.lg));
|
||||
headBoxStyle() {
|
||||
const c = this.c;
|
||||
const custom = flagOn(c.headSpacingCustom, false);
|
||||
const style = {
|
||||
margin: '-' + pad + 'rpx -' + pad + 'rpx 0',
|
||||
background: c.headBgMode === 'custom'
|
||||
? (String(c.headBg || '').trim() || 'transparent')
|
||||
: (this.headTheme ? themeGradient(this.card) : 'transparent'),
|
||||
marginTop: px2rpx(custom ? num(c.headMarginTop, 0) : (this.headTheme ? -num(c.padding, CardTokens.space.lg) : 0)) + 'rpx',
|
||||
marginRight: px2rpx(custom ? num(c.headMarginRight, 0) : (this.headTheme ? -num(c.padding, CardTokens.space.lg) : 0)) + 'rpx',
|
||||
marginBottom: px2rpx(custom ? num(c.headMarginBottom, 0) : 0) + 'rpx',
|
||||
marginLeft: px2rpx(custom ? num(c.headMarginLeft, 0) : (this.headTheme ? -num(c.padding, CardTokens.space.lg) : 0)) + 'rpx',
|
||||
paddingTop: px2rpx(custom ? num(c.headPaddingTop, 16) : (this.headTheme ? 16 : 0)) + 'rpx',
|
||||
paddingRight: px2rpx(custom ? num(c.headPaddingRight, 16) : (this.headTheme ? num(c.padding, CardTokens.space.lg) : 0)) + 'rpx',
|
||||
paddingBottom: px2rpx(custom ? num(c.headPaddingBottom, 14) : (this.headTheme ? 14 : 0)) + 'rpx',
|
||||
paddingLeft: px2rpx(custom ? num(c.headPaddingLeft, 16) : (this.headTheme ? num(c.padding, CardTokens.space.lg) : 0)) + 'rpx',
|
||||
borderRadius: c.headRadiusMode === 'custom'
|
||||
? px2rpx(num(c.headRadius, 8)) + 'rpx'
|
||||
: (this.headTheme ? '0 0 16rpx 16rpx' : '0'),
|
||||
};
|
||||
// 2.19.11: headBg 自定义或主题渐变; headPadV/headPadH 可配
|
||||
const bg = String(this.c.headBg || '').trim();
|
||||
style.background = bg || themeGradient(this.card);
|
||||
const padV = num(this.c.headPadV, 32);
|
||||
const padH = num(this.c.headPadH, 0) || num(this.c.padding, CardTokens.space.lg);
|
||||
style.padding = px2rpx(padV) + 'rpx ' + px2rpx(padH) + 'rpx';
|
||||
return this.$util.objToStyle(style);
|
||||
},
|
||||
headThemeStyle() {
|
||||
return this.headBoxStyle;
|
||||
},
|
||||
/** 资料区标题(2.17): 默认关(历史配置无此字段时不出标题) */
|
||||
rowsTitleShow() {
|
||||
return flagOn(this.c.showRowsTitle, false);
|
||||
@@ -570,17 +579,14 @@ export default {
|
||||
gradientStyle() {
|
||||
return this.$util.objToStyle({ background: themeGradient(this.card) });
|
||||
},
|
||||
/** 2.19.11: 顶带显隐(默认关) */
|
||||
/** 顶部色带默认隐藏;背景可跟随名片设计或使用独立颜色。 */
|
||||
bandShow() {
|
||||
return flagOn(this.c.bandShow, false);
|
||||
},
|
||||
bandStyle() {
|
||||
// 2.19.11: bandBg 自定义或名片主题渐变; bandHeight 控高度
|
||||
const bg = String(this.c.bandBg || '').trim();
|
||||
const h = num(this.c.bandHeight, 8);
|
||||
const custom = this.c.bandBgMode === 'custom';
|
||||
return this.$util.objToStyle({
|
||||
background: bg || themeGradient(this.card),
|
||||
height: px2rpx(h) + 'rpx',
|
||||
background: custom ? (String(this.c.bandBg || '').trim() || 'transparent') : themeGradient(this.card),
|
||||
});
|
||||
},
|
||||
shareBtnStyle() {
|
||||
@@ -836,9 +842,10 @@ export default {
|
||||
if (transform) parts.push('transform:' + transform + ';');
|
||||
return parts.filter(Boolean).join(' ').trim();
|
||||
},
|
||||
/** plain 头最终样式 */
|
||||
/** plain 头最终样式:头部容器配置与 corner 二维码让位合并为单字符串。 */
|
||||
plainHeadFinalStyle() {
|
||||
return this.cornerHeadStyle;
|
||||
const corner = this.$util.objToStyle(this.cornerHeadStyle || {});
|
||||
return [this.headBoxStyle, corner].filter(Boolean).join(' ').trim();
|
||||
},
|
||||
detailBtnStyle() {
|
||||
// 发送名片大按钮: 纯色主题实心(2026-10-22 参考图定稿, 不再用渐变);
|
||||
|
||||
@@ -140,14 +140,27 @@ export default {
|
||||
qrBlockBg: v.qrBlockBg,
|
||||
qrBlockRadius: v.qrBlockRadius,
|
||||
qrBlockPad: v.qrBlockPad,
|
||||
// 顶部色带 / 卡片四向外边距 / 头部背景与盒模型
|
||||
bandShow: v.bandShow,
|
||||
bandBgMode: v.bandBgMode,
|
||||
bandBg: v.bandBg,
|
||||
bandHeight: v.bandHeight,
|
||||
wrapMarginTop: v.wrapMarginTop,
|
||||
wrapMarginRight: v.wrapMarginRight,
|
||||
wrapMarginBottom: v.wrapMarginBottom,
|
||||
wrapMarginLeft: v.wrapMarginLeft,
|
||||
headBgMode: v.headBgMode,
|
||||
headBg: v.headBg,
|
||||
headPadV: v.headPadV,
|
||||
headPadH: v.headPadH,
|
||||
headRadiusMode: v.headRadiusMode,
|
||||
headRadius: v.headRadius,
|
||||
headSpacingCustom: v.headSpacingCustom,
|
||||
headMarginTop: v.headMarginTop,
|
||||
headMarginRight: v.headMarginRight,
|
||||
headMarginBottom: v.headMarginBottom,
|
||||
headMarginLeft: v.headMarginLeft,
|
||||
headPaddingTop: v.headPaddingTop,
|
||||
headPaddingRight: v.headPaddingRight,
|
||||
headPaddingBottom: v.headPaddingBottom,
|
||||
headPaddingLeft: v.headPaddingLeft,
|
||||
};
|
||||
},
|
||||
boxStyle() {
|
||||
|
||||
@@ -105,14 +105,27 @@ export default {
|
||||
qrBlockBg: v.qrBlockBg,
|
||||
qrBlockRadius: v.qrBlockRadius,
|
||||
qrBlockPad: v.qrBlockPad,
|
||||
// 顶部色带 / 卡片四向外边距 / 头部背景与盒模型
|
||||
bandShow: v.bandShow,
|
||||
bandBgMode: v.bandBgMode,
|
||||
bandBg: v.bandBg,
|
||||
bandHeight: v.bandHeight,
|
||||
wrapMarginTop: v.wrapMarginTop,
|
||||
wrapMarginRight: v.wrapMarginRight,
|
||||
wrapMarginBottom: v.wrapMarginBottom,
|
||||
wrapMarginLeft: v.wrapMarginLeft,
|
||||
headBgMode: v.headBgMode,
|
||||
headBg: v.headBg,
|
||||
headPadV: v.headPadV,
|
||||
headPadH: v.headPadH,
|
||||
headRadiusMode: v.headRadiusMode,
|
||||
headRadius: v.headRadius,
|
||||
headSpacingCustom: v.headSpacingCustom,
|
||||
headMarginTop: v.headMarginTop,
|
||||
headMarginRight: v.headMarginRight,
|
||||
headMarginBottom: v.headMarginBottom,
|
||||
headMarginLeft: v.headMarginLeft,
|
||||
headPaddingTop: v.headPaddingTop,
|
||||
headPaddingRight: v.headPaddingRight,
|
||||
headPaddingBottom: v.headPaddingBottom,
|
||||
headPaddingLeft: v.headPaddingLeft,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user