You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
6.2 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 商品详情商品/评价/详情的 nav -->
<template>
<su-fixed alway :bgStyles="{ background: '#fff' }" :val="0" noNav opacity :placeholder="false">
<su-status-bar />
<view
class="ui-bar ss-flex ss-col-center ss-row-between ss-p-x-20"
:style="[{ height: sys_navBar - sys_statusBar + 'px' }]"
>
<!-- -->
<view class="icon-box ss-flex">
<view class="icon-button icon-button-left ss-flex ss-row-center" @tap="onClickLeft">
<text class="sicon-back" v-if="hasHistory" />
<text class="sicon-home" v-else />
</view>
<view class="line"></view>
<view class="icon-button icon-button-right ss-flex ss-row-center" @tap="onClickRight">
<text class="sicon-more" />
</view>
</view>
<!-- 中 -->
<view class="detail-tab-card ss-flex-1" :style="[{ opacity: state.tabOpacityVal }]">
<view class="tab-box ss-flex ss-col-center ss-row-around">
<view
class="tab-item ss-flex-1 ss-flex ss-row-center ss-col-center"
v-for="item in state.tabList"
:key="item.value"
@tap="onTab(item)"
>
<view class="tab-title" :class="state.curTab === item.value ? 'cur-tab-title' : ''">
{{ item.label }}
</view>
<view v-show="state.curTab === item.value" class="tab-line"></view>
</view>
</view>
</view>
<!-- #ifdef MP -->
<view :style="[capsuleStyle]"></view>
<!-- #endif -->
</view>
</su-fixed>
</template>
<script setup>
import { reactive } from 'vue';
import { onPageScroll } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import throttle from '@/sheep/helper/throttle.js';
import { showMenuTools, closeMenuTools } from '@/sheep/hooks/useModal';
const sys_statusBar = sheep.$platform.device.statusBarHeight;
const sys_navBar = sheep.$platform.navbar;
const capsuleStyle = {
width: sheep.$platform.capsule.width + 'px',
height: sheep.$platform.capsule.height + 'px',
};
const state = reactive({
tabOpacityVal: 0,
curTab: 'goods',
tabList: [
{
label: '商品',
value: 'goods',
to: 'detail-swiper-selector',
},
{
label: '评价',
value: 'comment',
to: 'detail-comment-selector',
},
{
label: '详情',
value: 'detail',
to: 'detail-content-selector',
},
],
});
const emits = defineEmits(['clickLeft']);
const hasHistory = sheep.$router.hasHistory();
function onClickLeft() {
if (hasHistory) {
sheep.$router.back();
} else {
sheep.$router.go('/pages/index/index');
}
emits('clickLeft');
}
function onClickRight() {
showMenuTools();
}
let commentCard = {
top: 0,
bottom: 0,
};
function getCommentCardNode() {
return new Promise((res, rej) => {
uni.createSelectorQuery()
.select('.detail-comment-selector')
.boundingClientRect((data) => {
if (data) {
commentCard.top = data.top;
commentCard.bottom = data.top + data.height;
res(data);
} else {
res(null);
}
})
.exec();
});
}
function onTab(tab) {
let scrollTop = 0;
if (tab.value === 'comment') {
scrollTop = commentCard.top - sys_navBar + 1;
} else if (tab.value === 'detail') {
scrollTop = commentCard.bottom - sys_navBar + 1;
}
uni.pageScrollTo({
scrollTop,
duration: 200,
});
}
onPageScroll((e) => {
state.tabOpacityVal = e.scrollTop > sheep.$platform.navbar ? 1 : e.scrollTop * 0.01;
if (commentCard.top === 0) {
throttle(() => {
getCommentCardNode();
}, 50);
}
if (e.scrollTop < commentCard.top - sys_navBar) {
state.curTab = 'goods';
} else if (
e.scrollTop >= commentCard.top - sys_navBar &&
e.scrollTop <= commentCard.bottom - sys_navBar
) {
state.curTab = 'comment';
} else {
state.curTab = 'detail';
}
});
</script>
<style lang="scss" scoped>
.icon-box {
box-shadow: 0px 0px 4rpx rgba(51, 51, 51, 0.08), 0px 4rpx 6rpx 2rpx rgba(102, 102, 102, 0.12);
border-radius: 30rpx;
width: 134rpx;
height: 56rpx;
margin-left: 8rpx;
border: 1px solid rgba(#fff, 0.4);
.line {
width: 2rpx;
height: 24rpx;
background: #e5e5e7;
}
.sicon-back {
font-size: 32rpx;
color: #000;
}
.sicon-home {
font-size: 32rpx;
color: #000;
}
.sicon-more {
font-size: 32rpx;
color: #000;
}
.icon-button {
width: 67rpx;
height: 56rpx;
&-left:hover {
background: rgba(0, 0, 0, 0.16);
border-radius: 30rpx 0px 0px 30rpx;
}
&-right:hover {
background: rgba(0, 0, 0, 0.16);
border-radius: 0px 30rpx 30rpx 0px;
}
}
}
.left-box {
position: relative;
width: 60rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
.circle {
position: absolute;
left: 0;
top: 0;
width: 60rpx;
height: 60rpx;
background: rgba(#fff, 0.6);
border: 1rpx solid #ebebeb;
border-radius: 50%;
box-sizing: border-box;
z-index: -1;
}
}
.right {
position: relative;
width: 60rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
.circle {
position: absolute;
left: 0;
top: 0;
width: 60rpx;
height: 60rpx;
background: rgba(#ffffff, 0.6);
border: 1rpx solid #ebebeb;
box-sizing: border-box;
border-radius: 50%;
z-index: -1;
}
}
.detail-tab-card {
width: 50%;
.tab-item {
height: 80rpx;
position: relative;
z-index: 11;
.tab-title {
font-size: 30rpx;
}
.cur-tab-title {
font-weight: $font-weight-bold;
}
.tab-line {
width: 60rpx;
height: 6rpx;
border-radius: 6rpx;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 10rpx;
background-color: var(--ui-BG-Main);
z-index: 12;
}
}
}
</style>