Files
sociology_app/pages/component/commonComponents/anchorLink.vue

716 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view
class="wrapper"
:style="`width:100%;top: ${45 + statusBarHeight}px !important;`"
>
<view
class="tabs"
id="tabs"
:style="{
top: `${45 + statusBarHeight}px !important`,
}"
>
<slot name="tabs" :showTabs="showTabs"></slot>
<view
:style="{ display: showTabs ? 'block' : 'none', ...tabStyle }"
class="wrapper_tab"
>
<view
:class="`${
currentTab == i ? 'hot wrapper_tab_item' : 'wrapper_tab_item'
}`"
v-for="(v, i) in tabList"
@click="clickItem(v, i)"
>
{{ v.title }}
<slot name="labelSlot" :data="v"></slot>
</view>
</view>
<!-- <u-tabs
keyName="title"
:current="currentTab"
:list="tabList"
@click="clickItem"
lineColor="#00BB84"
lineWidth="46rpx"
lineHeight="10"
class="tabsStyle"
:inactiveStyle="{
color: '#666666',
fontSize: '30rpx',
fontWeight: 400,
}"
:activeStyle="{
color: '#333333',
fontSize: '30rpx',
fontWeight: 'bold',
}"
>
<template slot="labelSlot" slot-scope="slotProps">
<slot name="labelSlot" :data="slotProps.data"></slot>
</template>
</u-tabs> -->
</view>
<slot name="otherContent" :showTabs="showTabs"></slot>
<view class="section_box" :style="`padding-top:${45 + statusBarHeight}px;`">
<view
class="section"
v-for="(v, i) in allDataList"
:style="`${i == 0 ? `padding-top:${Number(baseHeight)}px;` : ''}`"
>
<view class="section">
<view
:id="v[titleKey]"
style="padding: 20rpx"
:class="`${currentTab == i ? 'hot section_top' : 'section_top'}`"
>
<slot
name="label"
:title="v[titleKey]"
:data="v"
:dataIndex="i"
></slot>
<!-- <view class="title" :style="{...titleStyle}">{{ v[titleKey] }}</view> -->
</view>
<view class="content section_content_progress">
<view class="content_list">
<slot
:name="slotName ? slotName + '_' + v.slotName : 'contentList'"
:showTabs="showTabs"
:dataList="v[dataListKey]"
:data="v"
:index="i"
></slot>
</view>
</view>
</view>
</view>
</view>
<slot name="tjProList" :showTabs="showTabs"></slot>
</view>
</template>
<script>
export default {
components: {},
props: [
"allDataList",
"dataListKey",
"tabStyle",
"titleKey",
"titleStyle",
"baseHeight",
"allTabList",
"slotName",
"defaultShowTabs",
],
data() {
return {
indexList: [],
itemArr: [],
distanceList: [],
tabList: [],
timer: null,
isLeftClick: false,
isOpenRightButton: true,
viewid: "cont0",
viewidIndex: 0,
openCollapseList: [],
cateIconList: [],
fdButtonStyle: {
width: "120rpx",
"border-color": "$themeColor",
color: "$themeColor",
float: "right",
"margin-right": "20rpx",
"margin-left": "30rpx",
},
modalInfo: {},
vip: {},
show: false,
options: {},
showTabs: this.defaultShowTabs ? this.defaultShowTabs : false, // 默认吸顶的tab不显示
currentTab: 0, // 由于初始化的uview的代码有bug所以默认是-1在第一次显示的时候设置0自动复位防止错误
distanceArr: [], // 每一个ID对应的scrollTop值
isTabChange: false, // 防止在点击tab的时候页面的滚动导致重复计算、抖动问题
};
},
// 监听页面滚动
watch: {
currentTab: {
immediate: true,
handler(newRoute) {
// console.log(this.currentTab,'8777777777777');
// this.$emit('currentTab',this.currentTab)
},
},
},
async onLoad(options) {
this.options = options;
await this.handleselectCate(
{
...this.cateList[0],
index: 0,
},
0,
);
},
async onShow() {},
methods: {
pageScroll(event) {
// console.log("event at line 213:", event);
// const _this = this;
if (this.isTabChange) {
return false;
}
const scrollTop = event.scrollTop;
const skewY =
Number(this.baseHeight) + 45 + +Number(this.statusBarHeight); // 偏移量由于吸顶的tab、头部的显示信息也有高度素以做了偏移量
// // console.log('skewY at line 130:',this.baseHeight,this.statusBarHeight, skewY)
if (scrollTop >= skewY) {
if (!this.showTabs && this.currentTab <= 0) {
// 在未显示tab并且 currentTab <= 0时防止uview ui抖动bug设置默认复位值
this.currentTab = 0;
}
this.showTabs = true;
// console.log('this.showTabs at line 141:', this.showTabs)
this.$nextTick(() => {
// this.currentTab = null;
const length = this.distanceArr.length;
const index = this.distanceArr.findIndex(
(el) => el.top - skewY - scrollTop - 40 > 0,
);
// console.log('index at line 15911111111111111:', index)
// 当index == -1 的时候实际当前滚动的距离超出了最大值也就是在最后一个tab显示的内容
// 当index > 0 的时候说明能在当前的scrollTop值找到即index的前一位
this.currentTab = index > 0 ? index - 1 : length - 1;
});
this.$forceUpdate();
} else {
this.showTabs = this.defaultShowTabs ? this.defaultShowTabs : false;
this.currentTab = 0;
}
},
backClick() {
if (this.options.backType == "order") {
uni.switchTab({
url: "/pages/homePage/index/index",
});
} else {
uni.navigateBack({
delta: 1,
});
}
},
// 获取所有元素在当前页面所处的位置信息
getDistanceArr() {
this.distanceArr = [];
if (this.allTabList && this.allTabList.length > 0) {
console.log("子组件获取tabList", this.allTabList);
this.tabList = [...this.allTabList];
} else {
this.tabList = [];
this.allDataList.forEach((e) => {
this.tabList.push({
title: e.title,
...e,
});
});
}
const _this = this;
this.$nextTick(() => {
_this.tabList.forEach((el) => {
uni
.createSelectorQuery()
.select(".wrapper")
.boundingClientRect((data) => {
//目标位置的节点类class或者id
uni
.createSelectorQuery()
.select("#" + el.title)
.boundingClientRect((res) => {
el.scrollTop =
//最外层盒子的节点类class或者id
_this.distanceArr.push({
title: el.title,
top: Number(res.top.toFixed(0)),
});
})
.exec();
})
.exec();
this.currentTab = 0;
// uni
// .createSelectorQuery()
// .select("#" + el.title)
// .boundingClientRect((data) => {
// console.log("data at line 785:", data);
// // 获取当前ID距离顶部的top值
// _this.distanceArr.push(data.top.toFixed(0));
// console.log(
// "_this.distanceArr.push at line 176:",
// _this.distanceArr
// );
// })
// .exec();
});
});
},
clickItem(item, index) {
var that = this;
// uni
// .createSelectorQuery()
// .select(".wrapper")
// .boundingClientRect((data) => {
// //目标位置的节点类class或者id
// uni
// .createSelectorQuery()
// .select("#" + item.title)
// .boundingClientRect((res) => {
// console.log("res at line 219:", res);
// //最外层盒子的节点类class或者id
// })
// .exec();
// })
// .exec();
const skewY =
Number(this.baseHeight) + 45 + +Number(this.statusBarHeight);
this.isTabChange = true;
this.$nextTick(() => {
this.currentTab = index;
var data = this.distanceArr.find((e) => e.title == item.title);
console.log(
"111111111111111111111111111111111111111at line 258:",
data,
);
uni.pageScrollTo({
// duration: 100, //过渡时间
scrollTop: data.top - skewY, //到达距离顶部的top值
duration: 300,
complete: function () {
const timer = setTimeout(() => {
that.isTabChange = false; // 关闭
clearTimeout(timer);
}, 1000); // 解决ios和安卓、鸿蒙系统兼容性问题
},
//scrollTop:data.top - res.top,//如果置顶
});
});
// const _this = this;
// // this.$nextTick 保证当前isTabChange 为true后执行代码
// // 避免在istabChange变为true的时候执行代码监听事件还是会继续执行重新计算currenTab值
// this.$nextTick(() => {
// _this.currentTab = item.index;
// uni
// .createSelectorQuery()
// .select("#" + item.title)
// .boundingClientRect((data) => {
// uni
// .createSelectorQuery()
// .select(".wrapper")
// .boundingClientRect((res) => {
// const scrollTop = data.top - res.top; // 获取差值
// const skewY = 200; // 偏移
// // 页面开始进行滚动到目标位置
// uni.pageScrollTo({
// scrollTop:
// scrollTop > 0 ? scrollTop - skewY : scrollTop + skewY,
// duration: 300,
// complete: function () {
// const timer = setTimeout(() => {
// _this.isTabChange = false; // 关闭
// clearTimeout(timer);
// }, 500); // 解决ios和安卓、鸿蒙系统兼容性问题
// },
// });
// })
// .exec();
// })
// .exec();
// });
},
},
};
</script>
<style lang="scss">
.wrapper {
background: white;
position: absolute;
min-height: 100vh;
.header {
height: 100rpx;
background: orange;
.bg {
width: 100vw;
height: 200rpx;
}
}
.tabs {
position: fixed !important;
z-index: 970;
// top: 0;
background-color: #fff;
width: 100vw;
.tabsStyle {
box-shadow: 0 2rpx 6rpx 0 rgba(153, 153, 153, 0.2);
/deep/ {
.u-tabs {
box-shadow: 0px 4px 6px 0 rgba(153, 153, 153, 0.2);
}
}
}
}
.section {
width: 100%;
padding: 0 0rpx;
box-sizing: border-box;
.section_top {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
.title {
font-size: 40rpx;
font-family:
PingFangSC-Semibold,
PingFang SC;
font-weight: 600;
color: #333333;
margin-left: 30rpx;
position: relative;
&::before {
position: absolute;
content: "";
left: -30rpx;
width: 14rpx;
height: 77%;
top: 10%;
border-radius: 14rpx;
background: #00bb84;
}
}
.right {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 20rpx;
.dots {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 33rpx;
width: 26rpx;
align-items: center;
padding: 10rpx 20rpx;
margin-right: 4rpx;
.dot {
width: 9rpx;
height: 9rpx;
background: #000000;
border-radius: 50%;
}
}
.more_menu {
position: absolute;
top: 70rpx;
right: 0;
z-index: 99;
background: white;
padding: 0 20rpx;
box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.2);
border-radius: 4rpx;
.more_menu_item {
font-size: 30rpx;
padding: 24rpx 180rpx 24rpx 16rpx;
white-space: nowrap;
}
.more_menu_item:not(:last-child) {
border-bottom: 1rpx solid #dddddd;
}
}
}
}
.content {
background: #f8f8f9;
border-radius: 30rpx;
padding: 32rpx;
margin-top: 20rpx;
&_top {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin-bottom: 24rpx;
&_name {
font-weight: bold;
color: #333333;
font-size: 32rpx;
}
&_ismySelf {
background: #eeeeee;
font-weight: 500;
color: #999999;
font-size: 24rpx;
margin-left: 12rpx;
padding: 6rpx 18rpx;
border-radius: 10rpx;
}
}
&_Info {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
padding-bottom: 20rpx;
margin-top: 20rpx;
&_item {
display: flex;
flex-direction: column;
flex: 1;
text-align: center;
&_label {
text-align: center;
font-size: 24rpx;
font-weight: 300;
color: #999999;
}
&_value {
font-size: 34rpx;
font-weight: bold;
color: #333333;
margin-top: 14rpx;
}
}
&_item:not(:last-child) {
position: relative;
&::after {
position: absolute;
content: "";
width: 1rpx;
height: 70rpx;
top: 20rpx;
right: 0;
background: #d8d8d8;
}
}
}
&_Info:not(:last-child) {
border-bottom: 1rpx solid #d8d8d8;
}
&_remark {
font-weight: 400;
color: #333333;
font-size: 24rpx;
padding-top: 20rpx;
text-align: justify;
min-height: 40rpx;
}
&_list {
&_item {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
padding: 20rpx 0;
border-bottom: 1rpx solid #d8d8d8;
&_label {
font-size: 30rpx;
font-weight: 500;
color: #00bb84;
white-space: nowrap;
width: 180rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
&_value {
font-size: 30rpx;
font-weight: 400;
color: #666666;
flex: 1;
margin-left: 40rpx;
align-self: center;
word-break: break-all;
text-align: justify;
}
}
&_empty {
height: 180rpx;
background: #f8f8f9;
border-radius: 10rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&_tip {
font-size: 20rpx;
font-weight: 400;
color: #999999;
margin-top: 20rpx;
line-height: 30rpx;
}
image {
width: 64rpx;
height: 50rpx;
}
}
&_emptyResult {
height: 240rpx;
image {
width: 166rpx;
height: 166rpx;
}
&_tip {
margin-top: 0;
}
}
}
&.reset {
padding: 0;
}
&_reportList {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20rpx;
&_pack {
width: 100%;
height: calc(25vw - 30rpx);
border-radius: 20rpx;
}
&_addImage {
width: 100%;
height: calc(25vw - 30rpx);
background: #f8f8f9;
border-radius: 20rpx;
// border: 2rpx dashed #bbbbbb;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&_icon {
width: 60rpx;
height: 48rpx;
}
&_tip {
font-size: 20rpx;
font-weight: 400;
line-height: 30rpx;
color: #999999;
margin-top: 14rpx;
}
}
}
}
.section_content_progress {
background: initial;
padding: 0 15rpx;
}
.content_result {
background: initial;
font-size: 30rpx;
font-weight: 400;
color: #666666;
word-wrap: break-word;
word-break: normal;
line-height: 60rpx;
letter-spacing: 2rpx;
text-align: justify;
}
.content_report {
background: initial;
padding: 12rpx 0;
}
}
.section:not(:first-child) {
margin-top: 20rpx;
}
}
.hot {
color: #00bb84 !important;
font-weight: bold;
}
.wrapper_tab {
width: 100%;
display: flex;
align-items: center;
justify-content: space-around;
font-size: 34rpx;
}
.wrapper_tab_item {
width: auto;
display: inline-block;
line-height: 60rpx;
padding: 10rpx 20rpx;
}
</style>