feat: 添加IonDatetime、IonList、IonSelect和IonSelectOption组件支持;优化新闻展示样式和数据格式化

This commit is contained in:
2026-01-20 03:32:01 +07:00
parent 9710c80a1b
commit 2b991ad26a
3 changed files with 23 additions and 8 deletions

8
components.d.ts vendored
View File

@@ -21,6 +21,7 @@ declare module 'vue' {
IonButtons: typeof import('@ionic/vue')['IonButtons']
IonCheckbox: typeof import('@ionic/vue')['IonCheckbox']
IonContent: typeof import('@ionic/vue')['IonContent']
IonDatetime: typeof import('@ionic/vue')['IonDatetime']
IonHeader: typeof import('@ionic/vue')['IonHeader']
IonIcon: typeof import('@ionic/vue')['IonIcon']
IonInfiniteScroll: typeof import('@ionic/vue')['IonInfiniteScroll']
@@ -28,12 +29,15 @@ declare module 'vue' {
IonInput: typeof import('@ionic/vue')['IonInput']
IonItem: typeof import('@ionic/vue')['IonItem']
IonLabel: typeof import('@ionic/vue')['IonLabel']
IonList: typeof import('@ionic/vue')['IonList']
IonPage: typeof import('@ionic/vue')['IonPage']
IonRefresher: typeof import('@ionic/vue')['IonRefresher']
IonRefresherContent: typeof import('@ionic/vue')['IonRefresherContent']
IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet']
IonSegment: typeof import('@ionic/vue')['IonSegment']
IonSegmentButton: typeof import('@ionic/vue')['IonSegmentButton']
IonSelect: typeof import('@ionic/vue')['IonSelect']
IonSelectOption: typeof import('@ionic/vue')['IonSelectOption']
IonSpinner: typeof import('@ionic/vue')['IonSpinner']
IonTabBar: typeof import('@ionic/vue')['IonTabBar']
IonTabButton: typeof import('@ionic/vue')['IonTabButton']
@@ -59,6 +63,7 @@ declare global {
const IonButtons: typeof import('@ionic/vue')['IonButtons']
const IonCheckbox: typeof import('@ionic/vue')['IonCheckbox']
const IonContent: typeof import('@ionic/vue')['IonContent']
const IonDatetime: typeof import('@ionic/vue')['IonDatetime']
const IonHeader: typeof import('@ionic/vue')['IonHeader']
const IonIcon: typeof import('@ionic/vue')['IonIcon']
const IonInfiniteScroll: typeof import('@ionic/vue')['IonInfiniteScroll']
@@ -66,12 +71,15 @@ declare global {
const IonInput: typeof import('@ionic/vue')['IonInput']
const IonItem: typeof import('@ionic/vue')['IonItem']
const IonLabel: typeof import('@ionic/vue')['IonLabel']
const IonList: typeof import('@ionic/vue')['IonList']
const IonPage: typeof import('@ionic/vue')['IonPage']
const IonRefresher: typeof import('@ionic/vue')['IonRefresher']
const IonRefresherContent: typeof import('@ionic/vue')['IonRefresherContent']
const IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet']
const IonSegment: typeof import('@ionic/vue')['IonSegment']
const IonSegmentButton: typeof import('@ionic/vue')['IonSegmentButton']
const IonSelect: typeof import('@ionic/vue')['IonSelect']
const IonSelectOption: typeof import('@ionic/vue')['IonSelectOption']
const IonSpinner: typeof import('@ionic/vue')['IonSpinner']
const IonTabBar: typeof import('@ionic/vue')['IonTabBar']
const IonTabButton: typeof import('@ionic/vue')['IonTabButton']

View File

@@ -105,6 +105,10 @@ function handleQuickAction(action: Action) {
function handleNewsClick(news: NewsItem) {
console.log("查看新闻:", news.title);
}
onMounted(() => {
fetchNews();
});
</script>
<template>
@@ -199,11 +203,11 @@ function handleNewsClick(news: NewsItem) {
<div
v-for="item in data"
:key="item.id"
class="bg-white rounded-2xl overflow-hidden shadow-sm cursor-pointer transition-all active:translate-y-0.5 active:shadow-sm flex"
class="bg-white rounded-2xl overflow-hidden card cursor-pointer transition-all active:translate-y-0.5 active:shadow-sm flex"
@click="handleNewsClick(item)"
>
<div class="relative w-28 h-28 shrink-0 overflow-hidden">
<img v-if="item.thumbnailId" :src="item.thumbnail" :alt="item.title" class="w-full h-full object-cover">
<img v-if="item.thumbnailId" :src="item.thumbnailId" :alt="item.title" class="w-full h-full object-cover">
<div class="news-badge absolute top-2 left-2 bg-linear-to-br from-[#c41e3a] to-[#8b1a2e] text-white px-2 py-0.5 rounded-lg text-xs font-semibold shadow-lg">
热点
</div>
@@ -220,7 +224,7 @@ function handleNewsClick(news: NewsItem) {
<div class="flex items-center gap-4 text-xs text-[#999] mt-2">
<span class="flex items-center gap-1">
<ion-icon :icon="timeOutline" class="text-sm" />
{{ item.createdAt }}
{{ useDateFormat(item.createdAt, 'YYYY-MM-DD') }}
</span>
<span class="flex items-center gap-1">
<ion-icon :icon="eyeOutline" class="text-sm" />
@@ -241,6 +245,9 @@ function handleNewsClick(news: NewsItem) {
</template>
<style lang='css' scoped>
.card {
box-shadow: 0 0 7px 4px rgba(0, 0, 0, 0.05);
}
/* 新闻标签渐变 */
.news-badge {
box-shadow: 0 2px 8px rgba(196, 30, 58, 0.3);

View File

@@ -73,22 +73,22 @@ onMounted(() => {
@click="handleNewsClick(item)"
>
<div class="relative w-full h-45 overflow-hidden">
<img v-if="item.thumbnailId" :src="item.thumbnail" :alt="item.title" class="w-full h-full object-cover">
<div class="news-badge absolute top-3 left-3 bg-linear-to-br from-[#78d0ff] to-[#1879aa] text-white px-3 py-1 rounded-xl text-xs font-semibold shadow-lg">
<img v-if="item.thumbnailId" :src="item.thumbnailId" :alt="item.title" class="w-full h-full object-cover">
<div class="news-badge absolute top-3 left-3 bg-linear-to-br from-[#ff7878] to-[#aa1818] text-white px-3 py-1 rounded-xl text-xs font-semibold shadow-lg">
热点
</div>
</div>
<div class="p-4">
<h4 class="text-base font-bold text-[#1a1a1a] mb-2 leading-snug">
<div class="text-xl font-bold text-[#1a1a1a] mb-2 leading-snug">
{{ item.title }}
</h4>
</div>
<p class="text-sm text-[#666] mb-3 leading-relaxed line-clamp-2">
{{ item.summary }}
</p>
<div class="flex items-center gap-4 text-xs text-[#999]">
<span class="flex items-center gap-1">
<ion-icon :icon="timeOutline" class="text-sm" />
{{ item.createdAt }}
{{ useDateFormat(item.createdAt, 'YYYY-MM-DD') }}
</span>
<span class="flex items-center gap-1">
<ion-icon :icon="eyeOutline" class="text-sm" />