refactor(article): 重构diy文章组件,支持非滚动模式与样式增强
1. 新增非滚动列表模式,适配scrollMode配置,兼容旧版swiperConfig参数 2. 重构样式系统,使用CSS变量统一管理主题与圆角,对齐ns-newform实现逻辑 3. 新增文章标签、阅读数、点赞数显示配置 4. 新增查看更多按钮,支持按分类/标签跳转列表页 5. 优化空值处理与图片加载失败逻辑 6. 修复computed class编译为逗号分隔字符串的样式错误 7. 重构响应式样式计算,支持自动适配不同布局的高度
This commit is contained in:
@@ -1,28 +1,48 @@
|
||||
<template>
|
||||
<x-skeleton data-component-name="diy-article" type="list" :loading="loading" :configs="skeletonConfig">
|
||||
<view class="article-wrap" :style="warpCss">
|
||||
<view :class="listClass" :style="warpCss">
|
||||
<!-- 自动垂直滚动 -->
|
||||
<swiper v-if="list.length > 0" class="auto-scroll-swiper" :style="swiperStyle"
|
||||
<view class="article-wrap" :style="warpWrapStyle">
|
||||
<!-- 注: :class 用内联数组,与 ns-newform 对齐;computed listClass/itemClass 已移除(避免数组 toString 用逗号 join 的问题) -->
|
||||
<view :class="['list-wrap', value.style || 'style-1']">
|
||||
<!-- 自动垂直滚动(默认开启,兼容老数据:无 scrollMode/swiperConfig 字段也走这里) -->
|
||||
<swiper v-if="list.length > 0 && useScroll" class="auto-scroll-swiper"
|
||||
:style="swiperWrapStyle"
|
||||
:vertical="swiperConfig.vertical !== false"
|
||||
:autoplay="swiperConfig.autoplay !== false" :circular="swiperConfig.circular !== false"
|
||||
:interval="swiperConfig.interval || 3000" :duration="swiperConfig.duration || 500"
|
||||
:autoplay="swiperConfig.autoplay !== false"
|
||||
:circular="swiperConfig.circular !== false"
|
||||
:interval="swiperConfig.interval || 3000"
|
||||
:duration="swiperConfig.duration || 500"
|
||||
:display-multiple-items="safeDisplayMultipleItems">
|
||||
<swiper-item v-for="(item, index) in list" :key="index" @tap.stop="toDetail(item)">
|
||||
<view class="swiper-item-content">
|
||||
<view :class="itemClass" :style="itemCss">
|
||||
<view class="article-img">
|
||||
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix"
|
||||
<view :class="['item', value.ornament && value.ornament.type]" :style="itemStyle">
|
||||
<!-- 封面图:无图时隐藏图位;style-4 纯文字始终不显示 -->
|
||||
<view class="article-img" v-if="item.cover_img && value.style !== 'style-4'">
|
||||
<image class="cover-img" :src="$util.img(item.cover_img)" mode="aspectFill"
|
||||
@error="imgError(index)" show-menu-by-longpress></image>
|
||||
</view>
|
||||
<view class="info-wrap">
|
||||
<text class="title">{{ item.article_title }}</text>
|
||||
<text class="desc">{{ item.article_abstract }}</text>
|
||||
<text class="desc"
|
||||
v-if="abstractStyle.support && abstractStyle.control && item.article_abstract">
|
||||
{{ item.article_abstract }}
|
||||
</text>
|
||||
<view class="tag-list"
|
||||
v-if="tagStyle.support && tagStyle.control && item.tag_names">
|
||||
<text class="tag" v-for="(tn, ti) in tagArr(item.tag_names)" :key="ti">{{ tn }}</text>
|
||||
</view>
|
||||
<view class="read-wrap">
|
||||
<block v-if="item.category_name">
|
||||
<text class="category-icon"></text>
|
||||
<text class="category-name">{{ item.category_name }}</text>
|
||||
</block>
|
||||
<view class="num" v-if="readNumStyle.support && readNumStyle.control">
|
||||
<text class="iconfont iconchakan"></text>
|
||||
<text>{{ item.read_num || 0 }}</text>
|
||||
</view>
|
||||
<view class="num" v-if="dianzanStyle.support && dianzanStyle.control">
|
||||
<text class="iconfont icondianzan"></text>
|
||||
<text>{{ item.dianzan_num || 0 }}</text>
|
||||
</view>
|
||||
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -30,6 +50,48 @@
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 非滚动模式(scrollMode==='none')时的普通列表 -->
|
||||
<template v-if="!useScroll">
|
||||
<view v-for="(item, index) in list" :key="index" :class="['item', value.ornament && value.ornament.type]" :style="itemStyle"
|
||||
@tap.stop="toDetail(item)">
|
||||
<view class="article-img" v-if="item.cover_img && value.style !== 'style-4'">
|
||||
<image class="cover-img" :src="$util.img(item.cover_img)" mode="aspectFill"
|
||||
@error="imgError(index)" show-menu-by-longpress></image>
|
||||
</view>
|
||||
<view class="info-wrap">
|
||||
<text class="title">{{ item.article_title }}</text>
|
||||
<text class="desc"
|
||||
v-if="abstractStyle.support && abstractStyle.control && item.article_abstract">
|
||||
{{ item.article_abstract }}
|
||||
</text>
|
||||
<view class="tag-list"
|
||||
v-if="tagStyle.support && tagStyle.control && item.tag_names">
|
||||
<text class="tag" v-for="(tn, ti) in tagArr(item.tag_names)" :key="ti">{{ tn }}</text>
|
||||
</view>
|
||||
<view class="read-wrap">
|
||||
<block v-if="item.category_name">
|
||||
<text class="category-icon"></text>
|
||||
<text class="category-name">{{ item.category_name }}</text>
|
||||
</block>
|
||||
<view class="num" v-if="readNumStyle.support && readNumStyle.control">
|
||||
<text class="iconfont iconchakan"></text>
|
||||
<text>{{ item.read_num || 0 }}</text>
|
||||
</view>
|
||||
<view class="num" v-if="dianzanStyle.support && dianzanStyle.control">
|
||||
<text class="iconfont icondianzan"></text>
|
||||
<text>{{ item.dianzan_num || 0 }}</text>
|
||||
</view>
|
||||
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 查看更多(仅非滚动模式显示) -->
|
||||
<view class="view-more" v-if="viewMore.support && viewMore.control && list.length > 0"
|
||||
:style="viewMoreStyle" @tap.stop="toListPage">
|
||||
<text>{{ viewMore.text || '查看更多' }}</text>
|
||||
<text class="iconfont icondiy-right-arrow"></text>
|
||||
</view>
|
||||
</template>
|
||||
<view v-if="list.length === 0 && !loading" class="empty-placeholder">
|
||||
<text class="empty-text">暂无相关文章</text>
|
||||
</view>
|
||||
@@ -68,78 +130,143 @@ export default {
|
||||
this.getList();
|
||||
},
|
||||
watch: {
|
||||
// 组件刷新监听(来自 DiyMinx mixin)
|
||||
// 组件刷新监听
|
||||
componentRefresh() {
|
||||
this.getList();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 获取swiper配置,默认空对象
|
||||
// ========== 容器样式(与 ns-newform 对齐: $util.objToStyle + CSS 变量) ==========
|
||||
// 根容器:背景 + CSS 变量(向下传递,H5/MP/Harmony 均支持继承)
|
||||
// 注: 用 objToStyle 自动过滤 undefined/空值,避免输出 background-color:; 这类脏 CSS
|
||||
warpWrapStyle() {
|
||||
const v = this.value || {};
|
||||
const r = (val, fb) => this._num(val, fb);
|
||||
const isRootRound = v.componentAngle === 'round';
|
||||
const isItemRound = v.elementAngle === 'round';
|
||||
return this.$util.objToStyle({
|
||||
'background-color': v.componentBgColor || 'transparent',
|
||||
// CSS 变量(向下传递给所有子元素,通过 var() 读取)
|
||||
'--article-component-bg-color': v.componentBgColor || 'transparent',
|
||||
'--article-element-bg-color': v.elementBgColor || 'transparent',
|
||||
'--article-top-around-radius': isRootRound ? `${r(v.topAroundRadius, 0) * 2}rpx` : '0rpx',
|
||||
'--article-bottom-around-radius': isRootRound ? `${r(v.bottomAroundRadius, 0) * 2}rpx` : '0rpx',
|
||||
'--article-top-element-around-radius': isItemRound ? `${r(v.topElementAroundRadius, 0) * 2}rpx` : '0rpx',
|
||||
'--article-bottom-element-around-radius': isItemRound ? `${r(v.bottomElementAroundRadius, 0) * 2}rpx` : '0rpx'
|
||||
});
|
||||
},
|
||||
// 单项容器样式:背景 + 装饰(box-shadow / border)
|
||||
// 注: 单项的 border-radius 由 CSS 变量向下传递(无需重复声明)
|
||||
itemStyle() {
|
||||
const v = this.value || {};
|
||||
const ornament = v.ornament || {};
|
||||
const style = {
|
||||
'background-color': v.elementBgColor || 'transparent'
|
||||
};
|
||||
if (ornament.type === 'shadow') {
|
||||
style['box-shadow'] = `0 0 10rpx ${ornament.color || 'rgba(0, 0, 0, 0.1)'}`;
|
||||
}
|
||||
if (ornament.type === 'stroke') {
|
||||
style['border'] = `2rpx solid ${ornament.color || 'transparent'}`;
|
||||
}
|
||||
return this.$util.objToStyle(style);
|
||||
},
|
||||
// swiper 容器高度(由 swiperHeight 计算属性驱动)
|
||||
swiperWrapStyle() {
|
||||
return this.$util.objToStyle({
|
||||
height: `${this.swiperHeight}rpx`
|
||||
});
|
||||
},
|
||||
// 查看更多样式(颜色由 viewMore.color 控制)
|
||||
viewMoreStyle() {
|
||||
return this.$util.objToStyle({
|
||||
color: (this.viewMore && this.viewMore.color) || '#999999'
|
||||
});
|
||||
},
|
||||
// ========== 字段显示配置(带默认值,避免老数据缺字段时报错) ==========
|
||||
abstractStyle() {
|
||||
return Object.assign({ support: true, control: true }, this.value.abstractStyle || {});
|
||||
},
|
||||
readNumStyle() {
|
||||
return Object.assign({ support: true, control: true }, this.value.readNumStyle || {});
|
||||
},
|
||||
dianzanStyle() {
|
||||
return Object.assign({ support: true, control: false }, this.value.dianzanStyle || {});
|
||||
},
|
||||
tagStyle() {
|
||||
return Object.assign({ support: true, control: true }, this.value.tagStyle || {});
|
||||
},
|
||||
viewMore() {
|
||||
return Object.assign({ support: true, control: false, text: '查看更多', color: '#999999' },
|
||||
this.value.viewMore || {});
|
||||
},
|
||||
// ========== 滚动配置(同时兼容老数据 swiperConfig 和新字段 scrollMode) ==========
|
||||
// 老数据 swiperConfig 字段:{ vertical, autoplay, circular, interval, duration, displayMultipleItems, swiperHeight }
|
||||
// 新数据 scrollMode 字段:'none' | 'vertical'(默认 vertical,与老行为一致)
|
||||
swiperConfig() {
|
||||
return this.value.swiperConfig || {};
|
||||
},
|
||||
// 安全的display-multiple-items值,确保不大于swiper-item数量
|
||||
scrollMode() {
|
||||
return this.value.scrollMode || 'vertical';
|
||||
},
|
||||
// 是否使用滚动模式
|
||||
useScroll() {
|
||||
return this.scrollMode !== 'none' && this.list.length > 1;
|
||||
},
|
||||
// 安全的 display-multiple-items(确保不大于实际 list 长度,避免 swiper 报错)
|
||||
safeDisplayMultipleItems() {
|
||||
const displayCount = this.swiperConfig.displayMultipleItems || 3;
|
||||
const actualCount = this.list.length;
|
||||
var displayCount = this.swiperConfig.displayMultipleItems || 3;
|
||||
var actualCount = this.list.length;
|
||||
return actualCount > 0 ? Math.min(displayCount, actualCount) : 1;
|
||||
},
|
||||
// 列表容器 class
|
||||
listClass() {
|
||||
return ['list-wrap', this.value.style];
|
||||
},
|
||||
// 单项 class
|
||||
itemClass() {
|
||||
return ['item', (this.value.ornament || {}).type];
|
||||
},
|
||||
warpCss() {
|
||||
var obj = '';
|
||||
obj += 'background-color:' + (this.value.componentBgColor || 'transparent') + ';';
|
||||
if (this.value.componentAngle == 'round') {
|
||||
obj += 'border-top-left-radius:' + (this.value.topAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-top-right-radius:' + (this.value.topAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-bottom-left-radius:' + (this.value.bottomAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-bottom-right-radius:' + (this.value.bottomAroundRadius || 0) * 2 + 'rpx;';
|
||||
// swiper 高度(rpx)优先级:
|
||||
// 1. 老/新数据显式设置了 swiperConfig.swiperHeight(>0) → 用配置值
|
||||
// 2. 否则按 style 算单行高度 × 实际显示行数 + 行间距
|
||||
swiperHeight() {
|
||||
// 1. 显式设置了 swiperHeight (>0)
|
||||
var configHeight = parseInt(this.swiperConfig.swiperHeight) || 0;
|
||||
if (configHeight > 0) return configHeight;
|
||||
// 2. 自动算:每行高度 × 显示行数 + 间距
|
||||
// 注:swiper 内 item 已去掉 margin-bottom,swiper-item 高度 = perRow
|
||||
var perRow;
|
||||
switch (this.value.style) {
|
||||
case 'style-1': perRow = 200; break; // 图160 + padding 上下20*2 = 200
|
||||
case 'style-2': perRow = 540; break; // 图320 + info 220
|
||||
case 'style-3': perRow = 300; break; // 图200 + info 100
|
||||
case 'style-4': perRow = 120; break; // 纯文字
|
||||
default: perRow = 200; break;
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
// swiper容器样式
|
||||
swiperStyle() {
|
||||
var height = parseInt(this.swiperConfig.swiperHeight) || 600;
|
||||
return {
|
||||
height: height + 'rpx',
|
||||
width: '100%'
|
||||
};
|
||||
},
|
||||
// 子项样式
|
||||
itemCss() {
|
||||
var obj = '';
|
||||
obj += 'background-color:' + (this.value.elementBgColor || 'transparent') + ';';
|
||||
if (this.value.elementAngle == 'round') {
|
||||
obj += 'border-top-left-radius:' + (this.value.topElementAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-top-right-radius:' + (this.value.topElementAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-bottom-left-radius:' + (this.value.bottomElementAroundRadius || 0) * 2 + 'rpx;';
|
||||
obj += 'border-bottom-right-radius:' + (this.value.bottomElementAroundRadius || 0) * 2 + 'rpx;';
|
||||
}
|
||||
var ornament = this.value.ornament || {};
|
||||
if (ornament.type == 'shadow') {
|
||||
obj += 'box-shadow:0 0 10rpx ' + (ornament.color || 'rgba(0, 0, 0, 0.1)') + ';';
|
||||
}
|
||||
if (ornament.type == 'stroke') {
|
||||
obj += 'border:2rpx solid ' + (ornament.color || 'transparent') + ';';
|
||||
}
|
||||
return obj;
|
||||
return perRow * this.safeDisplayMultipleItems + 30; // N 行 + 30rpx 行间距总空间
|
||||
}
|
||||
// 注: :class 一律在模板里用 :class="['static', dynamic]" 内联数组写法
|
||||
// 不再用 listClass/itemClass computed (computed 返回 array 时,uni-app WXML 编译
|
||||
// 输出 {{[listClass]}},运行时 toString 用逗号 join,产生 "list-wrap,style-1" 错误 class)
|
||||
},
|
||||
methods: {
|
||||
// 数字保底:与 diy-form._num 对齐(undefined/空串/非数字时返回兜底值)
|
||||
_num(v, fb) {
|
||||
if (v === '' || v === null || v === undefined) return fb;
|
||||
var n = parseInt(v);
|
||||
return isNaN(n) ? fb : n;
|
||||
},
|
||||
// 把逗号分隔的 tag_names 转为数组(过滤空)
|
||||
tagArr(str) {
|
||||
return (str || '').split(',').filter(Boolean);
|
||||
},
|
||||
getList() {
|
||||
this.loading = true;
|
||||
var data = {
|
||||
num: this.value.count || 0
|
||||
num: this.value.count || 8,
|
||||
sort_way: this.value.sortWay || 'latest'
|
||||
};
|
||||
if (this.value.sources == 'diy') {
|
||||
var sources = this.value.sources || 'initial';
|
||||
if (sources === 'diy') {
|
||||
data.num = 0;
|
||||
data.article_id_arr = (this.value.articleIds || []).toString();
|
||||
} else if (sources === 'category' && this.value.categoryId) {
|
||||
data.category_id = this.value.categoryId;
|
||||
} else if (sources === 'tag' && this.value.tagId) {
|
||||
data.tag_id = this.value.tagId;
|
||||
}
|
||||
|
||||
this.$api.sendRequest({
|
||||
@@ -160,13 +287,23 @@ export default {
|
||||
article_id: item.article_id
|
||||
});
|
||||
},
|
||||
// "查看更多" 跳列表页(若按分类/按标签则带筛选参数)
|
||||
toListPage() {
|
||||
var query = {};
|
||||
var sources = this.value.sources || 'initial';
|
||||
if (sources === 'category' && this.value.categoryId) {
|
||||
query.category_id = this.value.categoryId;
|
||||
} else if (sources === 'tag' && this.value.tagId) {
|
||||
query.tag_id = this.value.tagId;
|
||||
}
|
||||
this.$util.redirectTo('/pages_tool/article/list', query);
|
||||
},
|
||||
imgError(index) {
|
||||
// 图加载失败 → 清空 cover_img 触发 v-if 隐藏图位(无图就隐藏策略)
|
||||
if (!this.list[index]) return;
|
||||
var defaultImg = (this.$util.getDefaultImage() || {}).article;
|
||||
// 使用 $set 保证响应式更新
|
||||
this.$set(this.list, index, {
|
||||
...this.list[index],
|
||||
cover_img: defaultImg
|
||||
cover_img: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -174,35 +311,130 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 与 ns-newform 对齐: 在 .article-wrap 上通过内联 style 写入 CSS 变量,
|
||||
子元素通过 var() 读取。CSS 变量在 H5 / 微信小程序 WXSS / 鸿蒙元服务均支持继承。 */
|
||||
.article-wrap {
|
||||
/* CSS 变量默认值兜底(老数据 / 静态预览场景下用以下值) */
|
||||
--article-component-bg-color: transparent;
|
||||
--article-element-bg-color: transparent;
|
||||
--article-top-around-radius: 0rpx;
|
||||
--article-bottom-around-radius: 0rpx;
|
||||
--article-top-element-around-radius: 0rpx;
|
||||
--article-bottom-element-around-radius: 0rpx;
|
||||
|
||||
/* 根容器圆角:由 --article-top/bottom-around-radius 驱动 */
|
||||
border-top-left-radius: var(--article-top-around-radius, 0);
|
||||
border-top-right-radius: var(--article-top-around-radius, 0);
|
||||
border-bottom-left-radius: var(--article-bottom-around-radius, 0);
|
||||
border-bottom-right-radius: var(--article-bottom-around-radius, 0);
|
||||
|
||||
.list-wrap {
|
||||
// 垂直滚动 swiper
|
||||
.auto-scroll-swiper {
|
||||
height: 600rpx;
|
||||
width: 100%;
|
||||
|
||||
// swiper-item-content 占满 swiper-item,不另加 padding(避免与 item padding 叠加导致裁切)
|
||||
.swiper-item-content {
|
||||
padding: 10rpx 20rpx;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// swiper 内 item 去掉 margin-bottom,避免被 swiper-item 高度裁切;
|
||||
// 行间距由 swiperHeight 多余空间制造(perRow × 3 + 30)
|
||||
.item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
margin: 0;
|
||||
margin-bottom: 24rpx;
|
||||
/* 背景 / 圆角通过 CSS 变量从 .article-wrap 继承(由 warpWrapStyle 注入) */
|
||||
background-color: var(--article-element-bg-color, transparent);
|
||||
border-top-left-radius: var(--article-top-element-around-radius, 0);
|
||||
border-top-right-radius: var(--article-top-element-around-radius, 0);
|
||||
border-bottom-left-radius: var(--article-bottom-element-around-radius, 0);
|
||||
border-bottom-right-radius: var(--article-bottom-element-around-radius, 0);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.style-1 .item {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
margin-top: 10rpx;
|
||||
line-height: 1;
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
background: #f0f9ff;
|
||||
color: #1e6bb8;
|
||||
border: 2rpx solid #b3d8ff;
|
||||
border-radius: 20rpx;
|
||||
padding: 2rpx 14rpx;
|
||||
margin: 0 8rpx 8rpx 0;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.read-wrap {
|
||||
display: flex;
|
||||
color: #999ca7;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
line-height: 1;
|
||||
flex-wrap: wrap;
|
||||
font-size: $font-size-tag;
|
||||
|
||||
.category-icon {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: $base-color;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.category-name {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.num {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-left: 16rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 24rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.view-more {
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
|
||||
.iconfont {
|
||||
font-size: 24rpx;
|
||||
margin-left: 8rpx;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== style-1: 横向卡片(图左文右) ==========
|
||||
&.style-1 {
|
||||
.item {
|
||||
display: flex;
|
||||
margin-top: 0;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
padding: 20rpx;
|
||||
|
||||
.article-img {
|
||||
margin-right: 20rpx;
|
||||
@@ -212,9 +444,11 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
image {
|
||||
.cover-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,6 +457,7 @@ export default {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
@@ -233,7 +468,7 @@ export default {
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
font-size: 30rpx;
|
||||
line-height: 1.5;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.desc {
|
||||
@@ -245,40 +480,130 @@ export default {
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== style-2: 大图卡片(上图下文) ==========
|
||||
&.style-2 {
|
||||
.item {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.article-img {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.cover-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
padding: 20rpx;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 30rpx;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 10rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #888;
|
||||
font-size: 24rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== style-3: 三列网格 ==========
|
||||
&.style-3 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 32%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.article-img {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.cover-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
padding: 10rpx 14rpx;
|
||||
|
||||
.title {
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
line-height: 1.3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.read-wrap {
|
||||
display: flex;
|
||||
color: #999ca7;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
line-height: 1;
|
||||
|
||||
text {
|
||||
font-size: $font-size-tag;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 36rpx;
|
||||
vertical-align: bottom;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: $base-color;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.category-icon,
|
||||
.category-name {
|
||||
margin-right: 10rpx;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== style-4: 纯文字列表(无封面) ==========
|
||||
&.style-4 {
|
||||
.item {
|
||||
padding: 20rpx;
|
||||
margin-bottom: 0;
|
||||
border-bottom: 2rpx dashed #eee;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user