69 lines
2.0 KiB
Vue
69 lines
2.0 KiB
Vue
<template>
|
|
<div>
|
|
<h1 class="pixel-title" style="margin-bottom:22px;">> VIDEOS</h1>
|
|
<div class="pixel-cat-bar">
|
|
<button class="pixel-btn" style="font-size:9px;" :class="{ active: !selectedCat }" @click="selectCat(0)">ALL</button>
|
|
<button
|
|
v-for="c in categories"
|
|
:key="c.id"
|
|
class="pixel-btn pixel-btn-secondary"
|
|
style="font-size:9px;"
|
|
:class="{ active: selectedCat === c.id }"
|
|
@click="selectCat(c.id)"
|
|
>{{ c.name }}</button>
|
|
</div>
|
|
<router-link v-for="(v, i) in videos" :key="v.id" :to="`/videos/${v.id}`" class="pixel-stage-row">
|
|
<span class="pixel-stage-no">{{ String(i + 1).padStart(2, '0') }}</span>
|
|
<span class="pixel-stage-title">{{ v.title }}</span>
|
|
<span class="pixel-stage-meta">{{ duration(v) }} · {{ v.categoryName || '视频' }}</span>
|
|
</router-link>
|
|
<div v-if="!videos.length" class="pixel-info" style="padding:30px 0;">> 暂无数据</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { onMounted, ref } from 'vue'
|
|
import { fetchVideoCategories, fetchVideos, fetchVideoAlbums, type VideoCategory, type VideoItem } from '../../../services/api'
|
|
|
|
const categories = ref<VideoCategory[]>([])
|
|
const videos = ref<VideoItem[]>([])
|
|
const selectedCat = ref(0)
|
|
|
|
const load = async (catId: number) => {
|
|
const vids = await fetchVideos(catId || undefined)
|
|
videos.value = vids || []
|
|
}
|
|
|
|
const selectCat = (id: number) => {
|
|
selectedCat.value = id
|
|
load(id)
|
|
}
|
|
|
|
const duration = (v: VideoItem) => {
|
|
if (!v.duration) return '?'
|
|
return `${Math.floor(v.duration / 60)}:${String(v.duration % 60).padStart(2, '0')}`
|
|
}
|
|
|
|
onMounted(async () => {
|
|
const cats = await fetchVideoCategories()
|
|
categories.value = cats || []
|
|
const albums = await fetchVideoAlbums()
|
|
// 无分类视频时兜底用全部视频
|
|
const vids = await fetchVideos()
|
|
videos.value = vids || []
|
|
void albums
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.pixel-cat-bar {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 22px;
|
|
}
|
|
.pixel-btn.active {
|
|
outline: 3px solid var(--p-green);
|
|
}
|
|
</style>
|