文件
OmniCard/mpuniapp/pages/template/waterflow-perf/waterflow-perf.uvue

279 行
6.1 KiB
Plaintext

<template>
<view class="page">
<!-- #ifndef MP -->
<fps />
<!-- #endif -->
<view class="header">
<text class="header-info">{{ listData.length }}项 | 瀑布流动态列数 | 圆角边框阴影</text>
</view>
<waterflow class="waterflow-container" :max-cross-axis-extent="200" :main-axis-gap="4" :cross-axis-gap="4" @scrolltolower="onScrollToLower">
<flow-item v-for="(item, index) in listData" :key="item.id" :type="item.type">
<!-- ========== Type 1: 单图配文 ========== -->
<view v-if="item.type == 1" class="card card-type1">
<view class="card-header">
<text class="card-title" @click.stop="onTitleClick(item.id + 1)">#{{ item.id + 1 }}</text>
<text class="tag-sm">单图</text>
</view>
<view class="card-image-area">
<image class="card-image" :src="item.image" mode="aspectFill" @click.stop="onImageClick([item.image], 0)"></image>
</view>
<view class="card-content">
<text class="content-title">{{ item.title }}</text>
<text class="content-desc">{{ item.desc }}</text>
<view class="meta-info">
<text class="author-text">{{ item.author }}</text>
</view>
</view>
</view>
<!-- ========== Type 2: 三图配文 ========== -->
<view v-else-if="item.type == 2" class="card card-type2">
<view class="card-header">
<text class="card-title" @click.stop="onTitleClick(item.id + 1)">#{{ item.id + 1 }}</text>
<text class="tag-sm">三图</text>
</view>
<view class="card-images-row">
<image class="card-image-sm" :src="item.images[0]" mode="aspectFill" @click.stop="onImageClick(item.images, 0)"></image>
<image class="card-image-sm" :src="item.images[1]" mode="aspectFill" @click.stop="onImageClick(item.images, 1)"></image>
<image class="card-image-sm" :src="item.images[2]" mode="aspectFill" @click.stop="onImageClick(item.images, 2)"></image>
</view>
<view class="card-content">
<text class="content-title">{{ item.title }}</text>
<view class="meta-info">
<text class="author-text">{{ item.author }}</text>
<text class="view-count">1024阅读</text>
</view>
</view>
</view>
<!-- ========== Type 3: 视频 ========== -->
<view v-else-if="item.type == 3" class="card card-type5">
<view class="card-header">
<text class="card-title" @click.stop="onTitleClick(item.id + 1)">#{{ item.id + 1 }}</text>
<text class="tag-sm">视频</text>
</view>
<view class="video-area">
<video
class="card-video"
:src="item.videoUrl"
:poster="item.videoPoster"
:controls="true"
object-fit="cover"
></video>
</view>
<view class="card-content">
<view class="meta-info">
<text class="info-text">播放:{{ item.playCount }}</text>
<text class="info-text">弹幕:99+</text>
</view>
</view>
</view>
</flow-item>
<flow-item slot="load-more">
<text style="line-height: 50px; text-align: center; font-size: 12px; color: #999999;">{{ hasMore ? '加载中...' : '没有更多' }}</text>
</flow-item>
</waterflow>
</view>
</template>
<script setup lang="uts">
import { generateMockList, type ListItemData } from './mock-data.uts'
const fullData = generateMockList()
const pageSize = 20
function getPageData(pageIndex: number): ListItemData[] {
const start = pageIndex * pageSize
return fullData.slice(start, start + pageSize)
}
// 使用预生成的数据
const listData = ref<ListItemData[]>([])
const hasMore = ref(true)
let cucurrentPage = 0
onMounted(() => {
listData.value = getPageData(cucurrentPage)
})
function onScrollToLower() {
// 模拟加载更多数据
setTimeout(() => {
cucurrentPage++
const newData = getPageData(cucurrentPage)
if (newData.length > 0) {
listData.value = listData.value.concat(newData)
} else {
hasMore.value = false
}
}, 200)
}
function onTitleClick(index: number) {
uni.showToast({
title: `序号: ${index}`,
icon: 'none'
})
}
function onImageClick(urls: string[], current: number) {
uni.previewImage({
urls: urls,
current: current
})
}
</script>
<style>
.page {
flex: 1;
background-color: #f5f5f5;
}
.header {
padding: 10px 15px;
background-color: #333;
}
.header-info {
font-size: 10px;
color: #aaa;
margin-top: 2px;
}
.waterflow-container {
flex: 1;
}
/* ===== 卡片基础样式 ===== */
.card {
background-color: #fff;
border-radius: 8px;
padding: 10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.card-header {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
padding-bottom: 4px;
border-bottom-width: 0.5px;
border-bottom-color: #eee;
border-bottom-style: solid;
}
.card-title {
font-size: 12px;
font-weight: bold;
color: #333;
flex: 1;
}
.tag-sm {
font-size: 8px;
color: #fff;
background-color: #3498db;
padding: 2px 6px;
border-radius: 3px;
margin-left: 4px;
}
.card-content {
padding-top: 4px;
}
.content-title {
font-size: 12px;
font-weight: bold;
color: #333;
margin-bottom: 4px;
text-overflow: ellipsis;
}
.content-desc {
font-size: 10px;
color: #666;
margin-bottom: 4px;
text-overflow: ellipsis;
}
.meta-info {
flex-direction: row;
align-items: center;
margin-top: 4px;
}
.author-text {
font-size: 8px;
color: #999;
}
.view-count {
font-size: 8px;
color: #aaa;
margin-left: 6px;
}
.info-text {
font-size: 8px;
color: #666;
margin-right: 4px;
}
.status-text {
font-size: 8px;
color: #2ecc71;
margin-left: 6px;
font-weight: bold;
}
/* ===== Type 1: 单图配文 ===== */
.card-image-area {
margin: 6px 0;
height: 100px;
border-radius: 4px;
overflow: hidden;
}
.card-image {
width: 100%;
height: 100%;
}
/* ===== Type 2: 三图配文 ===== */
.card-images-row {
flex-direction: row;
justify-content: space-between;
margin: 6px 0;
height: 70px;
}
.card-image-sm {
flex: 1;
height: 70px;
border-radius: 3px;
overflow: hidden;
}
/* ===== Type 5: 视频 ===== */
.video-area {
margin: 6px 0;
}
.video-area {
margin: 6px 0;
height: 240px;
border-radius: 4px;
overflow: hidden;
}
.card-video {
width: 100%;
height: 240px;
}
</style>