zyronon 1 year ago
parent
commit
373d088812
  1. 20
      pnpm-lock.yaml
  2. 88
      src/pages/home/slide/Community.vue
  3. 92
      src/pages/other/AlbumDetail.vue
  4. 360
      src/pages/other/AlbumDetail2.vue

20
pnpm-lock.yaml

@ -11,6 +11,9 @@ dependencies:
axios: axios:
specifier: 1.6.0 specifier: 1.6.0
version: 1.6.0 version: 1.6.0
axios-mock-adapter:
specifier: ^1.22.0
version: 1.22.0(axios@1.6.0)
core-js: core-js:
specifier: 3.21.1 specifier: 3.21.1
version: 3.21.1 version: 3.21.1
@ -61,9 +64,6 @@ devDependencies:
'@vitejs/plugin-vue-jsx': '@vitejs/plugin-vue-jsx':
specifier: 3.0.0 specifier: 3.0.0
version: 3.0.0(vite@4.5.2)(vue@3.4.21) version: 3.0.0(vite@4.5.2)(vue@3.4.21)
axios-mock-adapter:
specifier: ^1.22.0
version: 1.22.0(axios@1.6.0)
less: less:
specifier: 4.1.3 specifier: 4.1.3
version: 4.1.3 version: 4.1.3
@ -1432,6 +1432,7 @@ packages:
/asynckit@0.4.0: /asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: false
/axios-mock-adapter@1.22.0(axios@1.6.0): /axios-mock-adapter@1.22.0(axios@1.6.0):
resolution: {integrity: sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==} resolution: {integrity: sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==}
@ -1441,7 +1442,7 @@ packages:
axios: 1.6.0 axios: 1.6.0
fast-deep-equal: 3.1.3 fast-deep-equal: 3.1.3
is-buffer: 2.0.5 is-buffer: 2.0.5
dev: true dev: false
/axios@1.6.0: /axios@1.6.0:
resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==}
@ -1451,6 +1452,7 @@ packages:
proxy-from-env: 1.1.0 proxy-from-env: 1.1.0
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
dev: false
/balanced-match@1.0.2: /balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@ -1717,6 +1719,7 @@ packages:
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
dependencies: dependencies:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: false
/commander@1.1.1: /commander@1.1.1:
resolution: {integrity: sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==} resolution: {integrity: sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==}
@ -1970,6 +1973,7 @@ packages:
/delayed-stream@1.0.0: /delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: false
/delegates@1.0.0: /delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
@ -2445,7 +2449,7 @@ packages:
/fast-deep-equal@3.1.3: /fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true dev: false
/fast-glob@3.3.2: /fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
@ -2570,6 +2574,7 @@ packages:
peerDependenciesMeta: peerDependenciesMeta:
debug: debug:
optional: true optional: true
dev: false
/form-data@4.0.0: /form-data@4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
@ -2578,6 +2583,7 @@ packages:
asynckit: 0.4.0 asynckit: 0.4.0
combined-stream: 1.0.8 combined-stream: 1.0.8
mime-types: 2.1.35 mime-types: 2.1.35
dev: false
/from2@2.3.0: /from2@2.3.0:
resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==}
@ -3037,7 +3043,7 @@ packages:
/is-buffer@2.0.5: /is-buffer@2.0.5:
resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: false
/is-core-module@2.13.1: /is-core-module@2.13.1:
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
@ -3445,6 +3451,7 @@ packages:
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
dependencies: dependencies:
mime-db: 1.52.0 mime-db: 1.52.0
dev: false
/mime@1.6.0: /mime@1.6.0:
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
@ -4003,6 +4010,7 @@ packages:
/proxy-from-env@1.1.0: /proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/prr@1.0.1: /prr@1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}

88
src/pages/home/slide/Community.vue

@ -15,7 +15,7 @@
<WaterfallList :list="list" class="list"> <WaterfallList :list="list" class="list">
<template v-slot="{item}"> <template v-slot="{item}">
<div class="card" <div class="card"
@click="test" @click="e=>test(e,item)"
> >
<img class="poster" v-lazy="_checkImgUrl(item.note_card?.cover?.url_default)"/> <img class="poster" v-lazy="_checkImgUrl(item.note_card?.cover?.url_default)"/>
<div class="bottom"> <div class="bottom">
@ -40,23 +40,30 @@
</ScrollList> </ScrollList>
<div class="shadow"> <div class="shadow">
<div class="wrap"></div>
<AlbumDetail v-if="state.d"
:detail="state.current"
@close="close"/>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import {reactive, watch} from "vue"; import {reactive, ref, watch} from "vue";
import {$no, _checkImgUrl} from "@/utils"; import {$no, _checkImgUrl, cloneDeep} from "@/utils";
import {recommendedPost} from "@/api/user"; import {recommendedPost} from "@/api/user";
import {useNav} from "@/utils/hooks/useNav"; import {useNav} from "@/utils/hooks/useNav";
import {Icon} from "@iconify/vue"; import {Icon} from "@iconify/vue";
import WaterfallList from "@/components/WaterfallList.vue"; import WaterfallList from "@/components/WaterfallList.vue";
import ScrollList from "@/components/ScrollList.vue"; import ScrollList from "@/components/ScrollList.vue";
import {useBaseStore} from "@/store/pinia";
import AlbumDetail from "@/pages/other/AlbumDetail.vue";
import Mock from "mockjs";
//@click="nav('album-detail',{},item)" //@click="nav('album-detail',{},item)"
const nav = useNav() const nav = useNav()
const baseStore = useBaseStore()
const props = defineProps({ const props = defineProps({
active: { active: {
type: Boolean, type: Boolean,
@ -65,8 +72,22 @@ const props = defineProps({
}) })
const state = reactive({ const state = reactive({
show: false show: false,
current: {
"id": "",
"note_card": {
"interact_info": {},
"cover": {},
"image_list": [],
"display_title": "",
"user": {},
comment_list: [],
createTime: ''
}
},
d: false,
}) })
let rect = ref({})
watch(() => props.active, n => { watch(() => props.active, n => {
if (n && !state.show) { if (n && !state.show) {
@ -74,29 +95,59 @@ watch(() => props.active, n => {
} }
}, {immediate: true}) }, {immediate: true})
function test(e) { function close() {
let rect = e.currentTarget.getBoundingClientRect() let s = $('.shadow ')
console.log('e', rect) let domRect = rect.value
let s = $('.shadow') s.css('transition', 'all .3s')
s.empty() s.css('top', domRect.top)
s.append($(e.currentTarget).clone()) s.css('left', domRect.left)
s.css('width', domRect.width)
s.css('height', domRect.height)
// state.d = false
}
function test(e, item) {
let data = Mock.mock({
'comment_list|3-50': [{
name: '@cname',
text: '@cparagraph(3)'
}]
})
item.note_card.comment_list = data.comment_list
item.note_card.createTime = Mock.Random.date('MM-dd')
item.note_card.interact_info.collect_count = Mock.Random.integer(60, 3000)
item.note_card.interact_info.share_count = Mock.Random.integer(60, 3000)
state.current = cloneDeep(item)
console.log(state.current)
state.d = true
let domRect = e.currentTarget.getBoundingClientRect()
console.log('e', domRect)
let s = $('.shadow ')
let w = $('.shadow .wrap')
// w.empty()
// w.append($(e.currentTarget).clone())
s.css('transition', '0s') s.css('transition', '0s')
s.css('top', rect.top) s.css('top', domRect.top)
s.css('left', rect.left) s.css('left', domRect.left)
s.css('width', rect.width) s.css('width', domRect.width)
s.css('height', domRect.height)
rect.value = domRect
setTimeout(() => { setTimeout(() => {
s.css('transition', 'all .3s') s.css('transition', 'all .3s')
s.css('top', 0) s.css('top', 0)
s.css('left', 0) s.css('left', 0)
s.css('width', '100vw') s.css('width', '100vw')
s.css('height', '100vh')
}) })
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
#Community { #Community {
font-size: 14rem; font-size: 14rem;
color: white; color: white;
@ -196,7 +247,12 @@ function test(e) {
top: 0; top: 0;
width: 100vw; width: 100vw;
transition: all .3s; transition: all .3s;
} overflow: hidden;
.wrap {
position: absolute;
z-index: 9999;
}
}
} }
</style> </style>

92
src/pages/other/AlbumDetail.vue

@ -1,8 +1,8 @@
<template> <template>
<div class="goods-detail base-page"> <div class="goods-detail base-page1">
<header> <header>
<Icon <Icon
@click="$back()" @click="$emit('close')"
icon="material-symbols-light:arrow-back-ios-new"/> icon="material-symbols-light:arrow-back-ios-new"/>
<div class="option" @click="nav('/home/search')"> <div class="option" @click="nav('/home/search')">
<Icon icon="jam:search"/> <Icon icon="jam:search"/>
@ -11,42 +11,45 @@
<div class="slide-imgs"> <div class="slide-imgs">
<SlideHorizontal v-model:index="state.index"> <SlideHorizontal v-model:index="state.index">
<SlideItem v-for="item in state.detail.note_card?.image_list"> <SlideItem v-for="item in props.detail.note_card?.image_list">
<img :src="_checkImgUrl(item.info_list?.[0]?.url)" alt=""> <img :src="_checkImgUrl(item.info_list?.[0]?.url)" alt="">
</SlideItem> </SlideItem>
</SlideHorizontal> </SlideHorizontal>
<div class="indicator-bar" v-if="state.detail.note_card?.image_list?.length > 1"> <div class="indicator-bar" v-if="props.detail.note_card?.image_list?.length > 1">
<div class="indicator" <div class="indicator"
:class="[i <= state.index+1 && 'active']" :class="[i <= state.index+1 && 'active']"
v-for="i in state.detail.note_card?.image_list?.length"></div> v-for="i in props.detail.note_card?.image_list?.length"></div>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<div class="shop"> <div class="shop">
<header> <header>
<img class="avatar" :src="_checkImgUrl(state.detail.note_card?.user?.avatar)"/> <img class="avatar" :src="_checkImgUrl(props.detail.note_card?.user?.avatar)"/>
<div class="right"> <div class="right">
<div class="name">{{ state.detail.note_card.user.nick_name }}</div> <div class="name">{{ props.detail.note_card.user.nick_name }}</div>
<div class="r">关注</div> <div class="r" @click="$emit('close')">关注</div>
</div> </div>
</header> </header>
<div class="desc"> <div class="desc">
{{ state.detail.note_card?.display_title }} {{ props.detail.note_card?.display_title }}
</div> </div>
<div class="date">{{ state.detail.note_card.createTime }}</div> <div class="date">{{ props.detail.note_card.createTime }}</div>
</div> </div>
<div class="card comments"> <div class="card comments">
<header> <header>
<span class="l">评论 {{ state.detail.note_card.comment_list.length }}</span> <span class="l">评论 {{ props.detail.note_card.comment_list.length }}</span>
<div class="r"> <div class="r">
<span>查看全部</span> <span>查看全部</span>
<Icon class="arrow" icon="mingcute:right-line"/> <Icon class="arrow" icon="mingcute:right-line"/>
</div> </div>
</header> </header>
<div class="comment" v-for="i in state.detail.note_card.comment_list.slice(0,2)"> <div class="comment"
@click="$emit('close')"
v-for="i in props.detail.note_card.comment_list.slice(0,2)">
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar"> <img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
<span> <span>
{{ i.name }}{{ i.text }} {{ i.name }}{{ i.text }}
@ -62,19 +65,19 @@
<div class="options"> <div class="options">
<div class="option"> <div class="option">
<Icon icon="solar:heart-linear"/> <Icon icon="solar:heart-linear"/>
<div class="text">{{ state.detail.note_card?.interact_info?.liked_count }}</div> <div class="text">{{ props.detail.note_card?.interact_info?.liked_count }}</div>
</div> </div>
<div class="option"> <div class="option">
<Icon icon="mage:message-dots-round" class="icon"/> <Icon icon="mage:message-dots-round" class="icon"/>
<div class="text">{{ state.detail.note_card.comment_list.length }}</div> <div class="text">{{ props.detail.note_card.comment_list.length }}</div>
</div> </div>
<div class="option"> <div class="option">
<Icon icon="mage:star"/> <Icon icon="mage:star"/>
<div class="text">{{ state.detail.note_card?.interact_info?.collect_count }}</div> <div class="text">{{ props.detail.note_card?.interact_info?.collect_count }}</div>
</div> </div>
<div class="option"> <div class="option">
<Icon icon="ph:share-fat-light"/> <Icon icon="ph:share-fat-light"/>
<div class="text">{{ state.detail.note_card?.interact_info?.share_count }}</div> <div class="text">{{ props.detail.note_card?.interact_info?.share_count }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -84,12 +87,11 @@
<script setup> <script setup>
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue"; import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
import SlideItem from "@/components/slide/SlideItem.vue"; import SlideItem from "@/components/slide/SlideItem.vue";
import {onMounted, reactive} from "vue"; import {reactive} from "vue";
import {useNav} from "@/utils/hooks/useNav"; import {useNav} from "@/utils/hooks/useNav";
import {Icon} from "@iconify/vue"; import {Icon} from "@iconify/vue";
import {useBaseStore} from "@/store/pinia"; import {useBaseStore} from "@/store/pinia";
import {_checkImgUrl, cloneDeep} from "@/utils"; import {_checkImgUrl} from "@/utils";
import Mock from 'mockjs'
const nav = useNav() const nav = useNav()
const store = useBaseStore() const store = useBaseStore()
@ -98,36 +100,30 @@ defineOptions({
name: 'Album-Detail' name: 'Album-Detail'
}) })
const state = reactive({ const props = defineProps({
detail: { detail: {
"id": "", type: Object,
"note_card": { default() {
"interact_info": {}, return {
"cover": {}, "id": "",
"image_list": [], "note_card": {
"display_title": "", "interact_info": {},
"user": {}, "cover": {},
comment_list: [], "image_list": [],
createTime: '' "display_title": "",
"user": {},
comment_list: [],
createTime: ''
}
}
} }
}, }
index: 0,
}) })
onMounted(() => { const state = reactive({
state.detail = cloneDeep(store.routeData) index: 0,
let data = Mock.mock({
'comment_list|3-50': [{
name: '@cname',
text: '@cparagraph(3)'
}]
})
state.detail.note_card.comment_list = data.comment_list
state.detail.note_card.createTime = Mock.Random.date('MM-dd')
state.detail.note_card.interact_info.collect_count = Mock.Random.integer(60, 3000)
state.detail.note_card.interact_info.share_count = Mock.Random.integer(60, 3000)
console.log('sta', state.detail)
}) })
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@ -142,10 +138,10 @@ onMounted(() => {
@red: rgb(248, 38, 74); @red: rgb(248, 38, 74);
& > header { & > header {
position: fixed; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
width: 100vw; width: 100%;
z-index: 9; z-index: 9;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -163,7 +159,7 @@ onMounted(() => {
.slide-imgs { .slide-imgs {
position: relative; position: relative;
height: 55vh; max-height: 55vh;
img { img {
height: 100%; height: 100%;
@ -176,7 +172,7 @@ onMounted(() => {
position: absolute; position: absolute;
bottom: 5rem; bottom: 5rem;
left: 3vw; left: 3vw;
width: 94vw; width: 94%;
display: flex; display: flex;
gap: 5rem; gap: 5rem;

360
src/pages/other/AlbumDetail2.vue

@ -0,0 +1,360 @@
<template>
<div class="goods-detail base-page1">
<header>
<Icon
@click="$back()"
icon="material-symbols-light:arrow-back-ios-new"/>
<div class="option" @click="nav('/home/search')">
<Icon icon="jam:search"/>
</div>
</header>
<div class="slide-imgs">
<SlideHorizontal v-model:index="state.index">
<SlideItem v-for="item in state.detail.note_card?.image_list">
<img :src="_checkImgUrl(item.info_list?.[0]?.url)" alt="">
</SlideItem>
</SlideHorizontal>
<div class="indicator-bar" v-if="state.detail.note_card?.image_list?.length > 1">
<div class="indicator"
:class="[i <= state.index+1 && 'active']"
v-for="i in state.detail.note_card?.image_list?.length"></div>
</div>
</div>
<div class="content">
<div class="shop">
<header>
<img class="avatar" :src="_checkImgUrl(state.detail.note_card?.user?.avatar)"/>
<div class="right">
<div class="name">{{ state.detail.note_card.user.nick_name }}</div>
<div class="r">关注</div>
</div>
</header>
<div class="desc">
{{ state.detail.note_card?.display_title }}
</div>
<div class="date">{{ state.detail.note_card.createTime }}</div>
</div>
<div class="card comments">
<header>
<span class="l">评论 {{ state.detail.note_card.comment_list.length }}</span>
<div class="r">
<span>查看全部</span>
<Icon class="arrow" icon="mingcute:right-line"/>
</div>
</header>
<div class="comment" v-for="i in state.detail.note_card.comment_list.slice(0,2)">
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
<span>
{{ i.name }}{{ i.text }}
</span>
</div>
</div>
</div>
<div class="toolbar">
<div class="input-wrap">
说点什么...
</div>
<div class="options">
<div class="option">
<Icon icon="solar:heart-linear"/>
<div class="text">{{ state.detail.note_card?.interact_info?.liked_count }}</div>
</div>
<div class="option">
<Icon icon="mage:message-dots-round" class="icon"/>
<div class="text">{{ state.detail.note_card.comment_list.length }}</div>
</div>
<div class="option">
<Icon icon="mage:star"/>
<div class="text">{{ state.detail.note_card?.interact_info?.collect_count }}</div>
</div>
<div class="option">
<Icon icon="ph:share-fat-light"/>
<div class="text">{{ state.detail.note_card?.interact_info?.share_count }}</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
import SlideItem from "@/components/slide/SlideItem.vue";
import {onMounted, reactive} from "vue";
import {useNav} from "@/utils/hooks/useNav";
import {Icon} from "@iconify/vue";
import {useBaseStore} from "@/store/pinia";
import {_checkImgUrl, cloneDeep} from "@/utils";
import Mock from 'mockjs'
const nav = useNav()
const store = useBaseStore()
defineOptions({
name: 'Album-Detail'
})
const state = reactive({
detail: {
"id": "",
"note_card": {
"interact_info": {},
"cover": {},
"image_list": [],
"display_title": "",
"user": {},
comment_list: [],
createTime: ''
}
},
index: 0,
})
onMounted(() => {
state.detail = cloneDeep(store.routeData)
let data = Mock.mock({
'comment_list|3-50': [{
name: '@cname',
text: '@cparagraph(3)'
}]
})
state.detail.note_card.comment_list = data.comment_list
state.detail.note_card.createTime = Mock.Random.date('MM-dd')
state.detail.note_card.interact_info.collect_count = Mock.Random.integer(60, 3000)
state.detail.note_card.interact_info.share_count = Mock.Random.integer(60, 3000)
console.log('sta', state.detail)
})
</script>
<style scoped lang="less">
@import "@/assets/less/index.less";
.goods-detail {
background: var(--color-message);
color: white;
font-size: 14rem;
@c: #a2a2a2;
@c2: #c0c0c0;
@red: rgb(248, 38, 74);
& > header {
position: fixed;
left: 0;
top: 0;
width: 100vw;
z-index: 9;
display: flex;
justify-content: space-between;
padding: 15rem;
box-sizing: border-box;
svg {
font-size: 20rem;
background: rgba(176, 176, 176, 0.4);
padding: 5rem;
color: white;
border-radius: 50%;
}
}
.slide-imgs {
position: relative;
height: 55vh;
img {
height: 100%;
width: 100%;
object-fit: cover;
touch-action: none;
}
.indicator-bar {
position: absolute;
bottom: 5rem;
left: 3vw;
width: 94vw;
display: flex;
gap: 5rem;
.indicator {
background: rgba(162, 160, 160, 0.5);
height: 3rem;
flex: 1;
border-radius: 2rem;
}
.active {
background: rgba(250, 246, 246, 0.58);
}
}
.index {
font-size: 12rem;
position: absolute;
padding: 3rem 10rem;
border-radius: 15rem;
background: rgba(91, 89, 89, 0.5);
right: 10rem;
bottom: 30rem;
color: white;
}
}
.card {
margin-top: 15rem;
border-radius: 10rem;
padding: 10rem 15rem;
background: black;
}
.arrow {
font-size: 16rem;
}
.content {
padding: 15rem;
padding-bottom: 10vh;
border-radius: 16rem 16rem 0 0;
.comments {
& > header {
margin-bottom: 16rem;
display: flex;
justify-content: space-between;
align-items: center;
.l {
font-size: 15rem;
}
.r {
color: gray;
font-size: 12rem;
display: flex;
align-items: center;
}
}
.comment {
margin-bottom: 16rem;
display: flex;
align-items: center;
gap: 5rem;
span {
display: inline-block;
white-space: nowrap;
flex: 1;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
}
img {
border-radius: 50%;
width: 20rem;
height: 20rem;
}
&:last-child {
margin-bottom: 0;
}
}
}
.shop {
& > header {
display: flex;
align-items: center;
gap: 10rem;
img {
width: 36rem;
height: 36rem;
border-radius: 50%;
}
.right {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
.name {
font-size: 16rem;
}
.r {
border-radius: 4rem;
padding: 6rem 16rem;
background: var(--primary-btn-color);
font-size: 12rem;
color: white;
}
}
}
.desc {
margin-top: 10rem;
}
.date {
font-size: 12rem;
margin-top: 10rem;
color: gray;
}
}
}
.toolbar {
position: fixed;
bottom: 0;
width: 100vw;
left: 0;
background: var(--color-message);
border-top: 1px solid rgba(white, .1);
display: flex;
align-items: center;
padding: 8rem 10rem;
padding-right: 0;
box-sizing: border-box;
gap: 6rem;
.input-wrap {
width: 110rem;
padding-left: 15rem;
height: 34rem;
border-radius: 30rem;
background: var(--second-btn-color-tran);
color: gray;
display: flex;
align-items: center;
}
.options {
flex: 1;
display: flex;
.option {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 13rem;
color: white;
svg {
font-size: 24rem;
}
}
}
}
}
</style>
Loading…
Cancel
Save