1
1
<template >
2
- <view class =" page-container bg-gray-100 min-h-screen" >
3
- <!-- 顶部导航 -->
4
- <view class =" bg-white px-4 py-3 text-center text-lg font-medium border-b border-gray-100" >
5
- 新闻列表
6
- </view >
7
-
2
+ <view class =" page-container bg-white min-h-screen" >
8
3
<!-- 分类标签 -->
9
- <view class =" bg-white px-4 py-2" >
10
- <scroll-view scroll-x class =" whitespace-nowrap" >
11
- <view
12
- v-for =" (item, index) in categories"
13
- :key =" index"
14
- @click =" selectCategory(index)"
15
- class =" inline-block mr-4"
16
- >
17
- <text
18
- class =" text-sm py-1"
19
- :class ="
20
- currentCategory === index
21
- ? 'text-blue-500 border-b-2 border-blue-500'
22
- : 'text-gray-500'
23
- "
4
+ <view class =" bg-white px-4 pt-2 pb-0 sticky top-0 z-10 shadow-sm" >
5
+ <scroll-view scroll-x class =" whitespace-nowrap" show-scrollbar =" false" enhanced >
6
+ <view class =" tabs-container flex pb-2 relative" >
7
+ <view
8
+ v-for =" (item, index) in categories"
9
+ :key =" index"
10
+ @click =" selectCategory(index)"
11
+ class =" tab-item px-4 py-2 relative"
24
12
>
25
- {{ item }}
26
- </text >
13
+ <text
14
+ class =" text-sm transition-all duration-300"
15
+ :class =" currentCategory === index ? 'text-[#06f] font-medium' : 'text-[#060b2d]'"
16
+ >
17
+ {{ item }}
18
+ </text >
19
+ <!-- 底部激活线条 -->
20
+ <view
21
+ v-if =" currentCategory === index"
22
+ class =" tab-line absolute bottom-0 left-0 right-0 mx-auto h-0.5 bg-[#06f] rounded-full transition-all duration-300"
23
+ :style =" { width: '50%', transform: 'translateX(0)' }"
24
+ ></view >
25
+ </view >
27
26
</view >
28
27
</scroll-view >
29
28
</view >
37
36
refresher-enabled
38
37
:refresher-triggered =" isRefreshing"
39
38
:refresher-threshold =" 80"
39
+ style =" height : calc (100vh - 100px )"
40
40
>
41
- <view class =" mt-3 bg-white " >
41
+ <view class =" mt-3" >
42
42
<view class =" divide-y divide-gray-100" >
43
43
<view
44
44
v-for =" (item, index) in newsList"
47
47
class =" px-4 py-3 active:bg-gray-50"
48
48
>
49
49
<view class =" flex" >
50
- <view class =" flex-1" >
51
- <view class =" text-base font-medium line-clamp-2" >{{ item.title }}</view >
50
+ <view class =" flex-1 pr-3" >
51
+ <view class =" text-base font-medium line-clamp-2 text-[#060b2d]" >
52
+ {{ item.title }}
53
+ </view >
52
54
<view class =" flex items-center mt-2" >
53
55
<view class =" flex items-center" >
54
56
<view class =" w-4 h-4 mr-1 flex items-center justify-center" >
55
- <text class =" i-ri-user-line text-xs" ></text >
57
+ <text class =" i-ri-user-line text-xs text-gray-400 " ></text >
56
58
</view >
57
59
<text class =" text-xs text-gray-500" >{{ item.author }}</text >
58
60
</view >
59
61
<view class =" flex items-center ml-4" >
60
62
<view class =" w-4 h-4 mr-1 flex items-center justify-center" >
61
- <text class =" i-ri-time-line text-xs" ></text >
63
+ <text class =" i-ri-time-line text-xs text-gray-400 " ></text >
62
64
</view >
63
65
<text class =" text-xs text-gray-500" >{{ item.time }}</text >
64
66
</view >
65
67
<view class =" flex items-center ml-4" >
66
68
<view class =" w-4 h-4 mr-1 flex items-center justify-center" >
67
- <text class =" i-ri-eye-line text-xs" ></text >
69
+ <text class =" i-ri-eye-line text-xs text-gray-400 " ></text >
68
70
</view >
69
71
<text class =" text-xs text-gray-500" >{{ item.views }}</text >
70
72
</view >
74
76
v-if =" item.image"
75
77
:src =" item.image"
76
78
mode =" aspectFill"
77
- class =" w-20 h-20 rounded ml-3 "
79
+ class =" w-20 h-20 rounded-lg ml-auto "
78
80
/>
79
81
</view >
80
82
</view >
81
83
</view >
82
84
</view >
83
85
84
86
<!-- 加载状态 -->
85
- <view class =" py-3 text-center" >
87
+ <view class =" py-4 text-center" >
86
88
<view v-if =" isLoading" class =" flex items-center justify-center" >
87
- <view class =" w-4 h-4 mr-2 animate-spin" >
88
- <text class =" i-ri-loader-4-line" ></text >
89
+ <view class =" w-8 h-8 mr-2 animate-spin" >
90
+ <text class =" i-ri-loader-4-line text-[#06f] " ></text >
89
91
</view >
90
92
<text class =" text-sm text-gray-500" >加载中...</text >
91
93
</view >
96
98
</template >
97
99
98
100
<script setup lang="ts">
99
- import { ref } from " vue"
101
+ import { ref , onMounted , nextTick } from " vue"
100
102
101
- const categories = [" 全部" , " 热点" , " 科技" , " 财经" , " 体育" , " 娱乐" , " 军事 " ]
103
+ const categories = [" 全部" , " 热点" , " 科技" , " 财经" , " 体育" , " 娱乐" ]
102
104
const currentCategory = ref (0 )
103
105
104
106
const newsList = ref ([
@@ -142,42 +144,96 @@ const newsList = ref([
142
144
const hasMore = ref (true )
143
145
const isLoading = ref (false )
144
146
const isRefreshing = ref (false )
147
+ const pageNum = ref (1 )
148
+ const pageSize = ref (10 )
145
149
146
150
const selectCategory = (index : number ) => {
151
+ if (currentCategory .value === index ) return
147
152
currentCategory .value = index
148
- loadNews ()
153
+ loadNews (true )
149
154
}
150
155
151
- const loadNews = () => {
152
- isLoading .value = true
153
- // 模拟加载数据
154
- setTimeout (() => {
155
- newsList .value = [
156
- {
157
- title: " 2024年全球科技创新大会在京召开,聚焦人工智能与可持续发展" ,
158
- author: " 科技日报" ,
159
- time: " 10分钟前" ,
160
- views: " 1.2万" ,
161
- image: " https://picsum.photos/200/200?random=1" ,
162
- },
163
- {
164
- title: " 央行发布最新货币政策报告,强调稳健货币政策取向不变" ,
165
- author: " 财经网" ,
166
- time: " 30分钟前" ,
167
- views: " 2.5万" ,
168
- image: " https://picsum.photos/200/200?random=2" ,
169
- },
170
- {
171
- title: " 中国女足晋级世界杯八强,创造历史最佳战绩" ,
172
- author: " 体育周刊" ,
173
- time: " 1小时前" ,
174
- views: " 5.8万" ,
175
- image: " https://picsum.photos/200/200?random=3" ,
176
- },
177
- ]
178
- isLoading .value = false
179
- hasMore .value = true
180
- }, 1000 )
156
+ const loadNews = (reset = false ) => {
157
+ if (reset ) {
158
+ pageNum .value = 1
159
+ isLoading .value = true
160
+
161
+ // 模拟加载数据
162
+ setTimeout (() => {
163
+ newsList .value = generateNewsItems (pageSize .value , currentCategory .value )
164
+ isLoading .value = false
165
+ hasMore .value = true
166
+ }, 800 )
167
+ }
168
+ }
169
+
170
+ // 生成新闻数据函数
171
+ const generateNewsItems = (count : number , categoryIndex : number ) => {
172
+ const category = categories [categoryIndex ]
173
+ const items = []
174
+
175
+ for (let i = 0 ; i < count ; i ++ ) {
176
+ items .push ({
177
+ title: ` ${category !== " 全部" ? ` [${category }] ` : " " }标题 ${i + 1 }: ${getRandomTitle ()} ` ,
178
+ author: getRandomAuthor (),
179
+ time: getRandomTime (),
180
+ views: ` ${Math .floor (Math .random () * 10 ) + 1 }.${Math .floor (Math .random () * 9 )}万 ` ,
181
+ image: ` https://picsum.photos/200/200?random=${i + 10 } ` ,
182
+ })
183
+ }
184
+
185
+ return items
186
+ }
187
+
188
+ // 随机标题
189
+ const getRandomTitle = () => {
190
+ const titles = [
191
+ " 人工智能技术进步迅速,专家呼吁加强伦理规范" ,
192
+ " 全球芯片供应链重组,各国竞相加码半导体产业" ,
193
+ " 新能源汽车销量持续增长,市场竞争日趋激烈" ,
194
+ " 互联网金融监管政策完善,促进行业健康发展" ,
195
+ " 电子商务平台积极拓展农村市场,带动乡村振兴" ,
196
+ " 云计算技术加速企业数字化转型,提升运营效率" ,
197
+ " 数字人民币试点范围扩大,支付方式多元化" ,
198
+ " 绿色发展理念深入人心,低碳经济成为新趋势" ,
199
+ " 元宇宙概念持续升温,相关技术研发提速" ,
200
+ " 健康科技创新不断,智能医疗设备普及率提高" ,
201
+ ]
202
+ return titles [Math .floor (Math .random () * titles .length )]
203
+ }
204
+
205
+ // 随机作者
206
+ const getRandomAuthor = () => {
207
+ const authors = [
208
+ " 科技日报" ,
209
+ " 财经网" ,
210
+ " 体育周刊" ,
211
+ " IT之家" ,
212
+ " 中国天气" ,
213
+ " 商业观察" ,
214
+ " 教育时报" ,
215
+ " 健康报道" ,
216
+ " 娱乐周刊" ,
217
+ " 科学探索" ,
218
+ ]
219
+ return authors [Math .floor (Math .random () * authors .length )]
220
+ }
221
+
222
+ // 随机时间
223
+ const getRandomTime = () => {
224
+ const times = [
225
+ " 刚刚" ,
226
+ " 5分钟前" ,
227
+ " 10分钟前" ,
228
+ " 30分钟前" ,
229
+ " 1小时前" ,
230
+ " 2小时前" ,
231
+ " 3小时前" ,
232
+ " 今天" ,
233
+ " 昨天" ,
234
+ " 前天" ,
235
+ ]
236
+ return times [Math .floor (Math .random () * times .length )]
181
237
}
182
238
183
239
const onRefresh = () => {
@@ -186,58 +242,29 @@ const onRefresh = () => {
186
242
187
243
// 模拟刷新数据
188
244
setTimeout (() => {
189
- newsList .value = [
190
- {
191
- title: " 2024年全球科技创新大会在京召开,聚焦人工智能与可持续发展" ,
192
- author: " 科技日报" ,
193
- time: " 刚刚" ,
194
- views: " 1.2万" ,
195
- image: " https://picsum.photos/200/200?random=1" ,
196
- },
197
- {
198
- title: " 央行发布最新货币政策报告,强调稳健货币政策取向不变" ,
199
- author: " 财经网" ,
200
- time: " 5分钟前" ,
201
- views: " 2.5万" ,
202
- image: " https://picsum.photos/200/200?random=2" ,
203
- },
204
- ]
245
+ newsList .value = generateNewsItems (pageSize .value , currentCategory .value )
205
246
isRefreshing .value = false
206
247
hasMore .value = true
248
+ pageNum .value = 1
207
249
}, 1000 )
208
250
}
209
251
210
252
const onLoadMore = () => {
211
253
if (isLoading .value || ! hasMore .value ) return
212
254
isLoading .value = true
255
+ pageNum .value ++
213
256
214
257
// 模拟加载更多数据
215
258
setTimeout (() => {
216
- const newItems = [
217
- {
218
- title: " 新能源汽车销量创新高,市场占有率突破30%" ,
219
- author: " 汽车之家" ,
220
- time: " 4小时前" ,
221
- views: " 2.1万" ,
222
- image: " https://picsum.photos/200/200?random=6" ,
223
- },
224
- {
225
- title: " 全国多地开展夏季旅游促销活动" ,
226
- author: " 旅游频道" ,
227
- time: " 5小时前" ,
228
- views: " 1.5万" ,
229
- image: " https://picsum.photos/200/200?random=7" ,
230
- },
231
- ]
232
-
259
+ const newItems = generateNewsItems (10 , currentCategory .value )
233
260
newsList .value .push (... newItems )
234
261
isLoading .value = false
235
262
236
- // 模拟没有更多数据的情况
237
- if (newsList .value . length >= 10 ) {
263
+ // 最多加载3页数据
264
+ if (pageNum .value >= 3 ) {
238
265
hasMore .value = false
239
266
}
240
- }, 1000 )
267
+ }, 800 )
241
268
}
242
269
243
270
const navigateTo = (url : string ) => {
@@ -248,4 +275,39 @@ const navigateTo = (url: string) => {
248
275
},
249
276
})
250
277
}
278
+
279
+ onMounted (() => {
280
+ // 初始加载
281
+ nextTick (() => {
282
+ loadNews (true )
283
+ })
284
+ })
251
285
</script >
286
+
287
+ <style >
288
+ .tabs-container {
289
+ position : relative ;
290
+ overflow : hidden ;
291
+ }
292
+
293
+ .tab-item {
294
+ position : relative ;
295
+ transition : all 0.3s ease ;
296
+ }
297
+
298
+ .tab-line {
299
+ animation : fade-in 0.3s ease ;
300
+ }
301
+
302
+ @keyframes fade-in {
303
+ from {
304
+ opacity : 0 ;
305
+ width : 0 ;
306
+ }
307
+
308
+ to {
309
+ opacity : 1 ;
310
+ width : 50% ;
311
+ }
312
+ }
313
+ </style >
0 commit comments