<template> <Head> <Title>寄托天下 - 面经分享</Title> <Meta name="keyword" content="留学资讯,留学交流论坛,留学面经,面试经验,寄托天下" /> </Head> <TopHead></TopHead> <div class="search-result flexacenter" v-if="keyword"> <div class="keyword flexacenter" @click="clearKeyword">{{ keyword }} <img class="keyword-icon" src="@/assets/img/cross-circle-icon.png" /></div> <div class="halving-line"></div> <div class="total">共 {{ count }} 条搜索数据</div> </div> <div class="content" ref="gridContainer"> <div class="empty-box flexcenter" v-if="list.length == 0 && page == 0"> <empty hint="没有找到相关结果,请更换搜索关键词"></empty> </div> <template v-else> <Item v-for="(item, index) in list" :key="index" :item="item" @handleLike="handleLike"></Item> </template> </div> <div class="in-end" v-if="page == 0 && list.length > 0">- 到底了 -</div> <div class="right-returnTop" v-if="returnTopState" @click="returnTop()"> <img src="@/assets/img/returnTop-icon.png" style="width: 24px; height: 24px;" /> </div> </template> <script setup> import { ElMessage } from "element-plus" let isNeedLogin = inject("isNeedLogin") const goLogin = inject("goLogin") useHead({ script: [{ src: "https://app.gter.net/bottom?tpl=header&menukey=mj" }, { src: "https://app.gter.net/bottom?tpl=footer", body: true }] }) const gridContainer = ref(null) let masonryInstance = null const route = useRoute() let keyword = ref("") // 搜索 keyword.value = route.query["keyword"] watchEffect(() => { if (keyword.value != route.query["keyword"]) { list.value = [] page.value = 1 keyword.value = route.query["keyword"] getList(route.query["keyword"]) } }) onMounted(async () => { let Masonry = await import("masonry-layout") masonryInstance = new Masonry.default(gridContainer.value, { itemSelector: ".box", gutter: 22.5, }) // masonryInstance.reloadItems() // masonryInstance.layout() window.addEventListener("scroll", handleScroll) getList() }) const handleScroll = () => { const scrollTop = document.documentElement.scrollTop || document.body.scrollTop if (scrollTop > 200) returnTopState.value = true else returnTopState.value = false const scrollHeight = document.documentElement.scrollHeight const clientHeight = document.documentElement.clientHeight // 列表下 滑动到底部 获取新数据 if (scrollTop + clientHeight >= scrollHeight - 40) getList() } let page = ref(1) let count = ref(0) let list = ref([]) // 列表数据 let loading = false // 加载中 const getList = () => { if (page.value == 0 || loading) return loading = true getListHttp({ page: page.value, keyword: keyword.value }) .then(res => { if (res.code != 200) { page.value = 0 ElMessage({ message: res.message, type: "error", }) return } let data = res.data // list.value = data.data list.value = list.value.concat(data.data || []) if (data.count > list.value.length) page.value++ else page.value = 0 count.value = data["count"] nextTick(() => { if (masonryInstance) { masonryInstance.reloadItems() masonryInstance.layout() } }) }) .finally(() => (loading = false)) } const handleLike = token => { if (isNeedLogin.value) { goLogin() return } operateLikeHttp({ token }).then(res => { if (res.code != 200) return let data = res.data list.value.forEach(element => { if (element["token"] == token) { element["islike"] = data["status"] element["likenum"] = data["count"] } }) ElMessage.success(res.message) }) } onUnmounted(() => { window.removeEventListener("scroll", handleScroll) }) const router = useRouter() // 清除搜索 // const clearKeyword = () => router.push(`/index.html`) const clearKeyword = () => goToURL(`/index.html`, false) try { if (process.server) { await getListHttp({ page: 1, keyword: keyword.value }).then(res => { if (res.code != 200) { page.value = 0 ElMessage({ message: res.message, type: "error", }) return } let data = res.data list.value = list.value.concat(data.data || []) }) } } catch (error) {} let returnTopState = ref(false) const returnTop = () => { window.scrollTo({ top: 0, behavior: "smooth", }) } </script> <style scoped lang="less"> .search-result { width: 1200px; margin: 0 auto 30px; .keyword { color: #fa6b11; font-size: 14px; cursor: pointer; .keyword-icon { width: 14px; height: 14px; margin-left: 9px; } } .halving-line { width: 1px; height: 13px; background: #d7d7d7; margin: 0 20px; } .total { font-size: 13px; color: #7f7f7f; } } .content { min-height: calc(100vh - 250px); width: 1200px; // height: 1000px; margin: 0 auto 93px; display: flex; flex-wrap: wrap; // justify-content: space-between; align-items: flex-start; .empty-box { width: 1200px; height: 540px; background-color: rgba(255, 255, 255, 1); border-radius: 16px; } } .in-end { font-size: 12px; color: #7f7f7f; text-align: center; margin-bottom: 88px; } .right-returnTop { position: fixed; right: calc((100vw - 1200px) / 2 - 75px); width: 50px; height: 50px; background-color: #323232; bottom: 85px; display: flex; justify-content: center; align-items: center; border-radius: 50%; z-index: 10; cursor: pointer; } @media screen and (max-width: 1360px) { .right-returnTop { right: 0 !important; } } </style>