Skip to content

Commit 1c54c63

Browse files
committed
feat: ✨新闻列表
1 parent e275f15 commit 1c54c63

File tree

7 files changed

+381
-228
lines changed

7 files changed

+381
-228
lines changed

env/.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ VITE_APP_TITLE = 'uni-vue3'
22
VITE_APP_PORT = 8080
33

44
VITE_UNI_APPID = ''
5-
VITE_WX_APPID = 'wx75c65ec54d3f83ed'
5+
VITE_WX_APPID = 'wx5d9163b7af511b7a'
66

77
VITE_APP_PUBLIC_BASE=/
88

src/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
},
5353
"quickapp": {},
5454
"mp-weixin": {
55-
"appid": "wx75c65ec54d3f83ed",
55+
"appid": "wx5d9163b7af511b7a",
5656
"setting": {
5757
"urlCheck": false,
5858
"minified": true

src/pages-sub/news/index.vue

+164-102
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
<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">
83
<!-- 分类标签 -->
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"
2412
>
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>
2726
</view>
2827
</scroll-view>
2928
</view>
@@ -37,8 +36,9 @@
3736
refresher-enabled
3837
:refresher-triggered="isRefreshing"
3938
:refresher-threshold="80"
39+
style="height: calc(100vh - 100px)"
4040
>
41-
<view class="mt-3 bg-white">
41+
<view class="mt-3">
4242
<view class="divide-y divide-gray-100">
4343
<view
4444
v-for="(item, index) in newsList"
@@ -47,24 +47,26 @@
4747
class="px-4 py-3 active:bg-gray-50"
4848
>
4949
<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>
5254
<view class="flex items-center mt-2">
5355
<view class="flex items-center">
5456
<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>
5658
</view>
5759
<text class="text-xs text-gray-500">{{ item.author }}</text>
5860
</view>
5961
<view class="flex items-center ml-4">
6062
<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>
6264
</view>
6365
<text class="text-xs text-gray-500">{{ item.time }}</text>
6466
</view>
6567
<view class="flex items-center ml-4">
6668
<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>
6870
</view>
6971
<text class="text-xs text-gray-500">{{ item.views }}</text>
7072
</view>
@@ -74,18 +76,18 @@
7476
v-if="item.image"
7577
:src="item.image"
7678
mode="aspectFill"
77-
class="w-20 h-20 rounded ml-3"
79+
class="w-20 h-20 rounded-lg ml-auto"
7880
/>
7981
</view>
8082
</view>
8183
</view>
8284
</view>
8385

8486
<!-- 加载状态 -->
85-
<view class="py-3 text-center">
87+
<view class="py-4 text-center">
8688
<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>
8991
</view>
9092
<text class="text-sm text-gray-500">加载中...</text>
9193
</view>
@@ -96,9 +98,9 @@
9698
</template>
9799

98100
<script setup lang="ts">
99-
import { ref } from "vue"
101+
import { ref, onMounted, nextTick } from "vue"
100102
101-
const categories = ["全部", "热点", "科技", "财经", "体育", "娱乐", "军事"]
103+
const categories = ["全部", "热点", "科技", "财经", "体育", "娱乐"]
102104
const currentCategory = ref(0)
103105
104106
const newsList = ref([
@@ -142,42 +144,96 @@ const newsList = ref([
142144
const hasMore = ref(true)
143145
const isLoading = ref(false)
144146
const isRefreshing = ref(false)
147+
const pageNum = ref(1)
148+
const pageSize = ref(10)
145149
146150
const selectCategory = (index: number) => {
151+
if (currentCategory.value === index) return
147152
currentCategory.value = index
148-
loadNews()
153+
loadNews(true)
149154
}
150155
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)]
181237
}
182238
183239
const onRefresh = () => {
@@ -186,58 +242,29 @@ const onRefresh = () => {
186242
187243
// 模拟刷新数据
188244
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)
205246
isRefreshing.value = false
206247
hasMore.value = true
248+
pageNum.value = 1
207249
}, 1000)
208250
}
209251
210252
const onLoadMore = () => {
211253
if (isLoading.value || !hasMore.value) return
212254
isLoading.value = true
255+
pageNum.value++
213256
214257
// 模拟加载更多数据
215258
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)
233260
newsList.value.push(...newItems)
234261
isLoading.value = false
235262
236-
// 模拟没有更多数据的情况
237-
if (newsList.value.length >= 10) {
263+
// 最多加载3页数据
264+
if (pageNum.value >= 3) {
238265
hasMore.value = false
239266
}
240-
}, 1000)
267+
}, 800)
241268
}
242269
243270
const navigateTo = (url: string) => {
@@ -248,4 +275,39 @@ const navigateTo = (url: string) => {
248275
},
249276
})
250277
}
278+
279+
onMounted(() => {
280+
// 初始加载
281+
nextTick(() => {
282+
loadNews(true)
283+
})
284+
})
251285
</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

Comments
 (0)