126 lines
2.7 KiB
Vue
126 lines
2.7 KiB
Vue
<template>
|
|
<div class="favorite-page">
|
|
<div class="favorite-shell">
|
|
<section class="favorite-header">
|
|
<h2>我的收藏</h2>
|
|
<p>整理日常浏览中想反复观看的内容与专题合集。</p>
|
|
</section>
|
|
|
|
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
|
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="loadMore">
|
|
<van-cell-group v-if="favorites.length" inset>
|
|
<van-cell
|
|
v-for="fav in favorites"
|
|
:key="fav.id"
|
|
:title="fav.name"
|
|
:label="`${fav.videoCount}个视频`"
|
|
is-link
|
|
@click="goToFavorite(fav.id)"
|
|
>
|
|
<template #icon>
|
|
<van-icon name="star" class="fav-icon" />
|
|
</template>
|
|
</van-cell>
|
|
</van-cell-group>
|
|
<van-empty v-else description="暂无收藏夹" />
|
|
</van-list>
|
|
</van-pull-refresh>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { showToast } from 'vant'
|
|
import { favoriteApi, type Favorite } from '@/api/favorite.ts'
|
|
|
|
const router = useRouter()
|
|
const favorites = ref<Favorite[]>([])
|
|
const loading = ref(false)
|
|
const finished = ref(false)
|
|
const refreshing = ref(false)
|
|
const currentPage = ref(1)
|
|
|
|
const loadFavorites = async (isRefresh = false) => {
|
|
if (isRefresh) {
|
|
currentPage.value = 1
|
|
favorites.value = []
|
|
finished.value = false
|
|
}
|
|
|
|
loading.value = true
|
|
try {
|
|
const data = await favoriteApi.getFavoriteList()
|
|
favorites.value = data
|
|
finished.value = true
|
|
} catch (error) {
|
|
showToast('加载失败')
|
|
} finally {
|
|
loading.value = false
|
|
refreshing.value = false
|
|
}
|
|
}
|
|
|
|
const loadMore = () => {
|
|
if (!finished.value) loadFavorites()
|
|
}
|
|
|
|
const onRefresh = () => {
|
|
loadFavorites(true)
|
|
}
|
|
|
|
const goToFavorite = (id: number) => {
|
|
router.push(`/my/favorites/${id}`)
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadFavorites()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.favorite-page {
|
|
min-height: 100vh;
|
|
background: #f6f7fb;
|
|
padding-bottom: 60px;
|
|
}
|
|
|
|
.favorite-shell {
|
|
max-width: 980px;
|
|
margin: 0 auto;
|
|
padding: 20px 12px 28px;
|
|
}
|
|
|
|
.favorite-header {
|
|
padding: 24px 26px;
|
|
border-radius: 28px;
|
|
background: linear-gradient(135deg, #fb7185, #8b5cf6);
|
|
color: #fff;
|
|
margin-bottom: 18px;
|
|
|
|
h2 {
|
|
margin: 0 0 8px;
|
|
font-size: 28px;
|
|
}
|
|
|
|
p {
|
|
margin: 0;
|
|
color: rgba(255, 255, 255, 0.82);
|
|
}
|
|
}
|
|
|
|
.favorite-shell :deep(.van-cell-group) {
|
|
margin: 0;
|
|
border-radius: 24px;
|
|
overflow: hidden;
|
|
box-shadow: 0 18px 42px rgba(15, 23, 42, 0.08);
|
|
}
|
|
|
|
.fav-icon {
|
|
color: #f7ba2a;
|
|
margin-right: 8px;
|
|
font-size: 20px;
|
|
}
|
|
</style>
|