123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <script setup lang="ts">
- import type { PostSketch } from '@/models'
- import { computed, onMounted, ref, watch } from 'vue'
- import { api } from '@/utils/axios'
- import PostCard from '@/components/PostCard.vue'
- import { useTokenStore } from '@/stores/auth.ts'
- import { delay } from '@/utils'
- import { writeIcon } from '@/assets/icons.ts'
- import { router } from '@/router'
- const data = ref<PostSketch[]>([])
- const pageSize = 10
- const isEnd = ref(false)
- const tokenStore = useTokenStore()
- function nextDatum() {
- if (isEnd.value) {
- return
- }
- api
- .postList(pageSize, data.value.length)
- .then((res) => {
- if (res.data.length < pageSize) {
- isEnd.value = true
- }
- data.value = [...data.value, ...res.data]
- })
- .catch((err) => {
- console.error(err)
- })
- }
- onMounted(() => {
- nextDatum()
- })
- const tokenAvailable = ref(false)
- const floatBtnElementAnimationStyle = ref({
- display: 'none',
- transform: 'scale(0)',
- transition: 'all .3s',
- })
- watch(
- () => tokenStore.available,
- async (newValue) => {
- if (!tokenAvailable.value && newValue) {
- tokenAvailable.value = true
- floatBtnElementAnimationStyle.value.display = 'block'
- floatBtnElementAnimationStyle.value.transform = 'scale(0)'
- await delay(20)
- floatBtnElementAnimationStyle.value.transform = 'scale(100%)'
- } else if (tokenAvailable.value && !newValue) {
- tokenAvailable.value = false
- floatBtnElementAnimationStyle.value.transform = 'scale(0)'
- await delay(320)
- floatBtnElementAnimationStyle.value.display = 'none'
- }
- },
- { immediate: true },
- )
- const tips: { content: string, value: string }[] = [
- { content: '有新技术?', value: '技术' },
- { content: '有新鲜事?', value: '日志' },
- { content: '有新想法?', value: '随笔' },
- { content: '写点东西?', value: '其他' },
- ]
- const tipIndex = ref(0)
- const currentTip = computed(() => tips[tipIndex.value])
- const changeTip = () => {
- tipIndex.value = (tipIndex.value + 1) % tips.length
- }
- function handleWriteClick() {
- router.push(`/editor?cate=${currentTip.value.value}`)
- }
- </script>
- <template>
- <div style="position: relative">
- <div
- class="float-btn"
- @click.stop="handleWriteClick"
- :style="floatBtnElementAnimationStyle"
- @mouseenter="changeTip"
- >
- <div class="float-btn-content">
- <div class="float-btn-ico" v-html="writeIcon.template" />
- <div>{{ currentTip.content }}</div>
- </div>
- </div>
- <PostCard v-for="item of data" :key="item.id" :target="item" />
- <div
- class="post-item"
- style="padding: 8px; display: flex; justify-content: center"
- v-if="isEnd"
- >
- <div>没有更多了😭</div>
- </div>
- <div class="post-item show-more" v-else @click="nextDatum">显示更多</div>
- </div>
- </template>
- <style scoped>
- .show-more {
- color: var(--secondary-text-color);
- padding: 8px;
- display: flex;
- justify-content: center;
- cursor: pointer;
- }
- .show-more:hover {
- color: var(--text-color);
- }
- .float-btn {
- position: fixed;
- right: 48px;
- bottom: 32px;
- padding: 8px;
- width: 32px;
- height: 32px;
- border-radius: 24px;
- overflow: hidden;
- fill: var(--text-color);
- color: var(--text-color);
- background-color: var(--secondary-background-color);
- box-shadow: rgba(0, 0, 0, 0.4) 0 0 6px;
- cursor: pointer;
- z-index: 10;
- }
- .float-btn:hover {
- fill: var(--secondary-background-color);
- background-color: var(--text-color);
- color: var(--secondary-background-color);
- right: 32px;
- bottom: 24px;
- width: 150px;
- height: 48px;
- border-radius: 32px;
- }
- .float-btn-content {
- width: 256px;
- display: flex;
- gap: 8px;
- font-size: large;
- font-weight: bold;
- align-items: center;
- }
- .float-btn-ico {
- width: 32px;
- height: 32px;
- transition: all 0.3s;
- }
- .float-btn:hover .float-btn-content .float-btn-ico {
- width: 48px;
- height: 48px;
- }
- </style>
|