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

View File

@@ -105,6 +105,10 @@ function handleQuickAction(action: Action) {
function handleNewsClick(news: NewsItem) { function handleNewsClick(news: NewsItem) {
console.log("查看新闻:", news.title); console.log("查看新闻:", news.title);
} }
onMounted(() => {
fetchNews();
});
</script> </script>
<template> <template>
@@ -199,11 +203,11 @@ function handleNewsClick(news: NewsItem) {
<div <div
v-for="item in data" v-for="item in data"
:key="item.id" :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)" @click="handleNewsClick(item)"
> >
<div class="relative w-28 h-28 shrink-0 overflow-hidden"> <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 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> </div>
@@ -220,7 +224,7 @@ function handleNewsClick(news: NewsItem) {
<div class="flex items-center gap-4 text-xs text-[#999] mt-2"> <div class="flex items-center gap-4 text-xs text-[#999] mt-2">
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<ion-icon :icon="timeOutline" class="text-sm" /> <ion-icon :icon="timeOutline" class="text-sm" />
{{ item.createdAt }} {{ useDateFormat(item.createdAt, 'YYYY-MM-DD') }}
</span> </span>
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<ion-icon :icon="eyeOutline" class="text-sm" /> <ion-icon :icon="eyeOutline" class="text-sm" />
@@ -241,6 +245,9 @@ function handleNewsClick(news: NewsItem) {
</template> </template>
<style lang='css' scoped> <style lang='css' scoped>
.card {
box-shadow: 0 0 7px 4px rgba(0, 0, 0, 0.05);
}
/* 新闻标签渐变 */ /* 新闻标签渐变 */
.news-badge { .news-badge {
box-shadow: 0 2px 8px rgba(196, 30, 58, 0.3); box-shadow: 0 2px 8px rgba(196, 30, 58, 0.3);

View File

@@ -73,22 +73,22 @@ onMounted(() => {
@click="handleNewsClick(item)" @click="handleNewsClick(item)"
> >
<div class="relative w-full h-45 overflow-hidden"> <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"> <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-[#78d0ff] to-[#1879aa] text-white px-3 py-1 rounded-xl text-xs font-semibold shadow-lg"> <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> </div>
<div class="p-4"> <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 }} {{ item.title }}
</h4> </div>
<p class="text-sm text-[#666] mb-3 leading-relaxed line-clamp-2"> <p class="text-sm text-[#666] mb-3 leading-relaxed line-clamp-2">
{{ item.summary }} {{ item.summary }}
</p> </p>
<div class="flex items-center gap-4 text-xs text-[#999]"> <div class="flex items-center gap-4 text-xs text-[#999]">
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<ion-icon :icon="timeOutline" class="text-sm" /> <ion-icon :icon="timeOutline" class="text-sm" />
{{ item.createdAt }} {{ useDateFormat(item.createdAt, 'YYYY-MM-DD') }}
</span> </span>
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<ion-icon :icon="eyeOutline" class="text-sm" /> <ion-icon :icon="eyeOutline" class="text-sm" />