feat(diy-article): add number humanization and fix layout alignment
1. 新增_humanizeNum方法实现阅读/点赞数的千/万单位人性化展示 2. 调整图标间距与日期布局为自然的左右分栏样式 3. 修复style-1无图item与有图item的元信息行垂直对齐问题
This commit is contained in:
@@ -44,11 +44,11 @@
|
||||
</block>
|
||||
<view class="num" v-if="readNumStyle.support && readNumStyle.control">
|
||||
<uni-icons type="eye" size="12" :color="metaColor" />
|
||||
<text>{{ item.read_num || 0 }}</text>
|
||||
<text>{{ _humanizeNum(item.read_num || 0) }}</text>
|
||||
</view>
|
||||
<view class="num" v-if="dianzanStyle.support && dianzanStyle.control">
|
||||
<uni-icons type="star" size="12" :color="metaColor" />
|
||||
<text>{{ item.dianzan_num || 0 }}</text>
|
||||
<text>{{ _humanizeNum(item.dianzan_num || 0) }}</text>
|
||||
</view>
|
||||
<text class="date" v-if="dateStyle.support && dateStyle.control">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
|
||||
</view>
|
||||
@@ -80,11 +80,11 @@
|
||||
</block>
|
||||
<view class="num" v-if="readNumStyle.support && readNumStyle.control">
|
||||
<uni-icons type="eye" size="12" :color="metaColor" />
|
||||
<text>{{ item.read_num || 0 }}</text>
|
||||
<text>{{ _humanizeNum(item.read_num || 0) }}</text>
|
||||
</view>
|
||||
<view class="num" v-if="dianzanStyle.support && dianzanStyle.control">
|
||||
<uni-icons type="star" size="12" :color="metaColor" />
|
||||
<text>{{ item.dianzan_num || 0 }}</text>
|
||||
<text>{{ _humanizeNum(item.dianzan_num || 0) }}</text>
|
||||
</view>
|
||||
<text class="date" v-if="dateStyle.support && dateStyle.control">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
|
||||
</view>
|
||||
@@ -514,8 +514,10 @@ export default {
|
||||
// 图左文右:item 高度 = max(图, 内容) + padding
|
||||
return Math.max(imageH, contentH) + padding;
|
||||
} else {
|
||||
// 无图:CSS .item.no-image .info-wrap { min-height: 240rpx }
|
||||
return Math.max(240, contentH) + padding;
|
||||
// 无图:CSS .item.no-image .info-wrap { min-height: 160rpx } 兜底,
|
||||
// 让 read-wrap 在 space-between 下被推到 160 起点 + read 高度处,
|
||||
// 与有图短内容场景(read-wrap 推到 160 起点)Y 对齐
|
||||
return Math.max(160, contentH) + padding;
|
||||
}
|
||||
}
|
||||
// style-2/3:上图下文,item 高度 = 图 + 内容 + padding
|
||||
@@ -541,10 +543,12 @@ export default {
|
||||
},
|
||||
// list 为空时的兜底 maxItemHeight(全字段最坏情况,与 swiperHeight 公式配合:
|
||||
// swiperHeight = (maxItemHeight + itemGap) × N)
|
||||
// style-1: 有图 = max(160,content) + 40;无图 = max(160,content) + 40;全字段最坏 = 280
|
||||
// 注:有图/无图都用 min-height 160 兜底,所以 _itemHeight 公式统一取 max(160, contentH) + padding
|
||||
_staticMaxItemHeight() {
|
||||
var style = this.value.style;
|
||||
switch (style) {
|
||||
case 'style-1': return 280; // 有图273/无图280
|
||||
case 'style-1': return 280; // 有图273/无图240(短内容)/全字段最坏280
|
||||
case 'style-2': return 584; // 图320+info 224+padding40
|
||||
case 'style-3': return 316; // 图200+info 96+padding20
|
||||
case 'style-4': return 104; // 标题28+read24+5margin+40padding+8buffer
|
||||
@@ -555,6 +559,27 @@ export default {
|
||||
tagArr(str) {
|
||||
return (str || '').split(',').filter(Boolean);
|
||||
},
|
||||
// 数字人性化:千/万单位(中文 app 主流写法)
|
||||
// < 1000: 原样("123")
|
||||
// 1000-9999: 转 k,保留 1 位小数,整数小数位去掉("1k" / "1.2k")
|
||||
// ≥ 10000: 转 万,规则同上("1万" / "1.2万" / "12.3万" / "1234万")
|
||||
// 非数字/负数/NaN: 返回原值(防御性,后端偶发返回 string/0/负数时不崩)
|
||||
// 为什么不直接 toLocaleString('zh-CN'):toLocaleString 在 H5 端正常,但在 MP-WXSS / Harmony 上
|
||||
// 对 zh-CN locale 支持不一致,有的会把 12000 渲染成 "12,000" 有的渲染成 "12,000.00" —
|
||||
// 跨端不稳。手写 if-else 跨端一致。
|
||||
_humanizeNum(n) {
|
||||
var num = Number(n);
|
||||
if (!isFinite(num) || num < 0) return n;
|
||||
if (num < 1000) return String(num);
|
||||
if (num < 10000) {
|
||||
// 千位:num / 1000,保留 1 位小数,去掉无意义的 .0
|
||||
var k = (num / 1000).toFixed(1);
|
||||
return (k.endsWith('.0') ? k.slice(0, -2) : k) + 'k';
|
||||
}
|
||||
// 万位:num / 10000
|
||||
var w = (num / 10000).toFixed(1);
|
||||
return (w.endsWith('.0') ? w.slice(0, -2) : w) + 'w';
|
||||
},
|
||||
getList() {
|
||||
this.loading = true;
|
||||
var data = {
|
||||
@@ -902,12 +927,17 @@ export default {
|
||||
.iconfont {
|
||||
/* 图标大小由 CSS 变量驱动 */
|
||||
font-size: var(--article-meta-icon-size, 24rpx);
|
||||
margin-right: 6rpx;
|
||||
/* 图标与数字之间的视觉间隔:之前 6rpx 太挤,数字 1k / 1.2万 看起来"粘"在图标上;
|
||||
10rpx 给到舒服的阅读节奏,与 view.icon(uni-icons 在 .num 内)的内边距不冲突 */
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 16rpx;
|
||||
/* margin-left: auto 把日期推到阅读区最右侧(无论是否折行),
|
||||
与左侧的「分类 / 阅读数 / 点赞数」自然形成「左 meta + 右日期」布局。
|
||||
之前用 16rpx 让日期紧跟左侧,布局上「左 meta + 右日期」不成立。*/
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,6 +956,12 @@ export default {
|
||||
}
|
||||
|
||||
// ========== style-1: 横向卡片(图左文右) ==========
|
||||
// 第 14 轮诉求:有图/无图两种 item 的「分类 / 阅读数 / 点赞数 / 日期」一行垂直对齐
|
||||
// 关键:不能破坏原先有图 item 的布局 — 保留 .info-wrap 的 justify-content: space-between
|
||||
// (title 在顶、read-wrap 在底,这是有图 item 的经典样式)。
|
||||
// 无图 item 之前没设 space-between,所以 read-wrap 默认紧跟 title/desc/tag 下方,Y 不齐。
|
||||
// 修复:无图 item 单独加 space-between + 给 .info-wrap 一个与有图场景对齐的 min-height,
|
||||
// 让无图的 read-wrap 也被推到 info-wrap 底部。有图 item 一切照旧,不破坏。
|
||||
&.style-1 {
|
||||
.item {
|
||||
display: flex;
|
||||
@@ -951,6 +987,7 @@ export default {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* 保留原布局:title 顶部、read-wrap 底部(经典 style-1 横向卡片样式) */
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -986,23 +1023,27 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 无图 item 样式:与有图视觉等高 (~280rpx) ==========
|
||||
// 背景:开启全字段(标题+图+摘要+标签+阅读区含日期)后,有图 info 自然 233rpx +
|
||||
// padding 40 = 273rpx;无图无 image 撑高,info 自然 ~233rpx,需 min-height 拉齐
|
||||
// 到 240rpx,再加 padding 40 = 280rpx 与有图一致。
|
||||
// 早期版本曾用 clamp:1 + margin:0 把无图压到 160rpx(匹配 image 高度),现 perRow
|
||||
// 提到 280 后空间足够,放开 clamp:1 让无图也能展示完整标题/摘要,跟用户「内容
|
||||
// 全显示」诉求一致;tag-list / read-wrap 的 margin 仍清零,避免无图时因
|
||||
// space-between 分布与有图节奏不同。
|
||||
// ========== 无图 item:让 read-wrap 也走 space-between 锚到 info-wrap 底部 ==========
|
||||
// 有图 item 保留原样(title 顶 / read-wrap 底,经典样式);
|
||||
// 无图 item 之前 read-wrap 紧跟内容下方,现在用 space-between + 合适的 min-height
|
||||
// 让 read-wrap 也钉到 info-wrap 底部,与有图 item 的 read-wrap 行 Y 坐标对齐。
|
||||
//
|
||||
// min-height 取值 160rpx = 与 image 高度一致。
|
||||
// 有图 item 的 info-wrap 实际高度 = max(image 160, content) = 至少 160(短内容)或更高(长内容);
|
||||
// 短内容时 image 160 撑住 .item 高度,read-wrap 用 space-between 推到 160 底部。
|
||||
// 无图 item 的 info-wrap 设 min-height: 160rpx,即使内容更短,info-wrap 仍 ≥ 160,
|
||||
// space-between 把 read-wrap 推到 160 底部 → 与有图短内容场景 read-wrap Y 一致。
|
||||
// 长内容时(标题 2 行 + 摘要 2 行 + 标签),info-wrap 实际 > 160,两种 item 各自撑高,
|
||||
// space-between 都把 read-wrap 推到 info-wrap 底部 → Y 仍一致(都贴在各自 item 底部)。
|
||||
.item.no-image {
|
||||
.info-wrap {
|
||||
min-height: 240rpx;
|
||||
/* 关键:让无图 info-wrap 至少 160rpx,匹配有图短内容场景 */
|
||||
min-height: 160rpx;
|
||||
/* 保留 tag-list margin-top: 0 的旧规则(避免与有图节奏不同),
|
||||
但不要「read-wrap margin-top: 0」 — 让 space-between 决定 read-wrap 位置 */
|
||||
.tag-list {
|
||||
margin-top: 0;
|
||||
}
|
||||
.read-wrap {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user