uniapp 滚动tab
uniapp + woui +unibest
<route lang="json5">{style: {navigationBarTitleText: '知识产权',navigationBarBackgroundColor: '#C80F06',navigationBarTextStyle: 'white',backgroundColorTop: '#C80F06',},}
</route>
<template><view class="bgc-b w100"><!-- 导航栏 --><NavTabScroll:tabs="tabs":current-tab="currentTab":scroll-left="scrollLeft":show-nav-bar="showNavBar"@update:currentTab="handleTabClick"/><scroll-viewclass="content-scroll"id="my-scroll":scroll-y="true":scroll-x="false":scroll-into-view="currentAnchor":scroll-top="scrollTop":scroll-with-animation="true"@scroll="handleScroll"><view class="section" id="patent"><SubTitle:title="tabs[0].title":toggleName="tabs[0].key":show="patentParam.show"ref="title1"@toggle="handleToggle('patent')"></SubTitle><viewclass="sec_item"v-for="(item, index) in patentList":key="index"v-show="patentParam.show"><Patent :data="item"></Patent></view><view class="load-more-list"><!-- v-if="+patentParam.totalCount > patentList.length" --><view class="load-more-btn" @click="handleViewMore('patent')"><text>查看更多</text></view><view class="is-loading" v-if="patentParam.loading"><text>加载中</text></view></view></view><view class="section" id="brand"><SubTitle:title="tabs[1].title":toggleName="tabs[1].key":show="brandParam.show"ref="title1"@toggle="handleToggle('brand')"></SubTitle><viewclass="sec_item"v-for="(item, index) in brandList":key="index"v-show="brandParam.show"><Brand :data="item"></Brand></view><view class="load-more-list"><!-- v-if="+brandParam.totalCount > brandList.length" --><view class="load-more-btn" @click="handleViewMore('brand')"><text>查看更多</text></view><view class="is-loading" v-if="brandParam.loading"><text>加载中</text></view></view></view><view class="section" id="softwareCopyright"><SubTitle:title="tabs[2].title":toggleName="tabs[2].key":show="showBrand"ref="title1"@toggle="handleToggle('softwareCopyright')"></SubTitle><viewclass="sec_item"v-for="(item, index) in softwareCopyrightList":key="index"v-show="softwareCopyrightParam.show"><SoftwareCopyright :data="item"></SoftwareCopyright></view><view class="load-more-list"><!-- v-if="+softwareCopyrightParam.totalCount > softwareCopyrightParam.length" --><view class="load-more-btn" @click="handleViewMore('softwareCopyright')"><text>查看更多</text></view><view class="is-loading" v-if="softwareCopyrightParam.loading"><text>加载中</text></view></view></view><view class="section" id="workCopyright"><SubTitle:title="tabs[3].title":toggleName="tabs[3].key":show="workCopyrightParam.show"ref="title1"@toggle="handleToggle('workCopyright')"></SubTitle><viewclass="sec_item"v-for="(item, index) in workCopyrightList":key="index"v-show="workCopyrightParam.show"><WorkCopyright :data="item"></WorkCopyright></view><view class="load-more-list"><!-- v-if="+workCopyrightParam.totalCount > workCopyrightList.length" --><view class="load-more-btn" @click="handleViewMore('workCopyright')"><text>查看更多</text></view><view class="is-loading" v-if="workCopyrightParam.loading"><text>加载中</text></view></view></view><view class="section" id="network"><SubTitle:title="tabs[4].title":toggleName="tabs[4].key":show="networkParam.show"ref="title1"@toggle="handleToggle('network')"></SubTitle><viewclass="sec_item"v-for="(item, index) in networkList":key="index"v-show="networkParam.show"><Network :data="item"></Network></view><view class="load-more-list"><!-- <viewclass="load-more-btn"v-if="+networkParam.totalCount > networkList.length"@click="handleViewMore('network')"><text>查看更多</text></view> --><view class="is-loading" v-if="networkParam.loading"><text>加载中</text></view></view></view></scroll-view></view>
</template><script lang="ts" setup>
import { ref, onMounted, nextTick, onUnmounted, computed } from 'vue'
import { debounce } from '@/uni_modules/wot-design-uni/components/common/util'
import {listPatentApplicationListAll,listTrademarkListAll,listSoftwareCopyrightInfoAll,listCopyrightInfoAll,listWebsiteInfoAll,
} from '@/api/enterprise'
import NavTabScroll from '@/components/NavTabScroll/NavTabScroll.vue' //滚动锚点组件
import SubTitle from '@/components/Property/title.vue'
import Patent from '@/components/Property/patent.vue'
import Brand from '@/components/Property/brand.vue'
import SoftwareCopyright from '@/components/Property/softwareCopyright.vue'
import WorkCopyright from '@/components/Property/workCopyright.vue'
import Network from '@/components/Property/network.vue'const tabs = [{ key: 'patent', title: '专利', top: 0 },{ key: 'brand', title: '商标', top: 0 },{ key: 'softwareCopyright', title: '软件著作权', top: 0 },{ key: 'workCopyright', title: '作品著作权', top: 0 },{ key: 'network', title: '网络备案', top: 0 },
]
const scrollLeft = ref(0)
const showNavBar = ref(true)
const currentTab = ref('patent')
const currentAnchor = ref('')
const scrollTop = ref(0)const id = ref(null)const topList = ref([])const patentList = ref([])
const patentParam = ref({applicationDate: '',applicationNumber: [],companyId: '960f87c242e8ad867a066cbaa5f78e1',companyName: '',name: '',pageNo: 0,pageSize: 0,publicationDate: '',totalCount: 0,totalPage: 0,loading: false,show: true,
})const brandList = ref([])
const brandParam = ref({appDate: '',companyId: '960cf87c242e8ad867a066cbaa5f78e1',companyName: '',flowStatusDesc: '',intClsDesc: '',name: '',pageNo: 1,pageSize: 5,regDate: '',totalCount: 0,totalPage: 0,loading: false,show: true,
})const softwareCopyrightList = ref([])
const softwareCopyrightParam = ref({companyId: '848f94014224e0999b52c45e02ad1164',companyName: '',name: '',pageNo: 1,pageSize: 5,registerAperDate: '',totalCount: 0,totalPage: 0,loading: false,show: true,
})
const workCopyrightList = ref([])
const workCopyrightParam = ref({companyId: 'a6faee7453d06561b7e6bb6cc3235c4f',companyName: '',pageNo: 1,pageSize: 5,registerDate: '',totalCount: 0,totalPage: 0,loading: false,show: true,
})const networkList = ref([])
const networkParam = ref({companyId: '95113c19bd54fee0155438311aac5af6',companyName: '',pageNo: 1,pageSize: 5,totalCount: 0,totalPage: 0,loading: false,show: true,
})onLoad((options) => {id.value = options.companyId// 如果有 currentTab 参数,设置初始标签并滚动if (options.currentTab) {currentTab.value = options.currentTab}// networkParam.value.companyId = id.valuePromise.all([getPatent(), getBrand(), getSoftware(), getWorkCopyright(), getNetwork()]).then((res) => {setTimeout(() => {calcPosition()currentAnchor.value = options.currentTab}, 400)},)
})
function getPatent() {return new Promise((resolve) => {const params = JSON.parse(JSON.stringify(patentParam.value))delete params.totalCountdelete params.totalPagedelete params.loadingdelete params.showpatentParam.value.loading = truelistPatentApplicationListAll(params).then((res) => {if (res.status === '0') {if (res.data && res.data.length) {patentList.value = [...patentList.value, ...res.data]}patentParam.value.totalCount = +res.totalCount || 0patentParam.value.totalPage = +res.totalPage || 0}resolve(patentList.value)}).finally(() => {patentParam.value.loading = false})})
}
function getBrand() {return new Promise((resolve) => {const params = JSON.parse(JSON.stringify(brandParam.value))delete params.totalCountdelete params.totalPagedelete params.loadingdelete params.showbrandParam.value.loading = truelistTrademarkListAll(params).then((res) => {if (res.status === '0') {if (res.data && res.data.length) {brandList.value = [...brandList.value, ...res.data]}brandParam.value.totalCount = +res.totalCount || 0brandParam.value.totalPage = +res.totalPage || 0}resolve(brandList.value)}).finally(() => {brandParam.value.loading = false})})
}
function getSoftware() {return new Promise((resolve) => {const params = JSON.parse(JSON.stringify(softwareCopyrightParam.value))delete params.totalCountdelete params.totalPagedelete params.loadingdelete params.showsoftwareCopyrightParam.value.loading = truelistSoftwareCopyrightInfoAll(params).then((res) => {if (res.status === '0') {if (res.data && res.data.length) {softwareCopyrightList.value = [...softwareCopyrightList.value, ...res.data]}softwareCopyrightParam.value.totalCount = +res.totalCount || 0softwareCopyrightParam.value.totalPage = +res.totalPage || 0}resolve(softwareCopyrightList.value)}).finally(() => {softwareCopyrightParam.value.loading = false})})
}
function getWorkCopyright() {return new Promise((resolve) => {const params = JSON.parse(JSON.stringify(workCopyrightParam.value))delete params.totalCountdelete params.totalPagedelete params.loadingdelete params.showworkCopyrightParam.value.loading = truelistCopyrightInfoAll(params).then((res) => {if (res.status === '0') {if (res.data && res.data.length) {workCopyrightList.value = [...workCopyrightList.value, ...res.data]}workCopyrightParam.value.totalCount = +res.totalCount || 0workCopyrightParam.value.totalPage = +res.totalPage || 0}resolve(workCopyrightList.value)}).finally(() => {workCopyrightParam.value.loading = false})})
}function getNetwork() {return new Promise((resolve) => {const params = JSON.parse(JSON.stringify(networkParam.value))delete params.totalCountdelete params.totalPagedelete params.loadingdelete params.shownetworkParam.value.loading = truelistWebsiteInfoAll(params).then((res) => {if (res.status === '0') {if (res.data && res.data.length) {networkList.value = [...networkList.value, ...res.data]}networkParam.value.totalCount = +res.totalCount || 0networkParam.value.totalPage = +res.totalPage || 0}resolve(networkList.value)}).finally(() => {networkParam.value.loading = false})})
}function handleToggle(type) {if (type === 'patent') {patentParam.value.show = !patentParam.value.show} else if (type === 'brand') {brandParam.value.show = !brandParam.value.show} else if (type === 'softwareCopyright') {softwareCopyrightParam.value.show = !softwareCopyrightParam.value.show} else if (type === 'workCopyright') {workCopyrightParam.value.show = !workCopyrightParam.value.show} else if (type === 'network') {networkParam.value.show = !networkParam.value.show}setTimeout(() => {calcPosition()}, 300)
}async function handleTabClick(key: string, index: number) {currentTab.value = keycurrentAnchor.value = key
}// 一进入页面且数据渲染完成后 或 展开收起的时候判断 页面元素的高度
function calcPosition() {const query = uni.createSelectorQuery()query.select('.content-scroll').boundingClientRect()tabs.forEach((key) => {query.select(`#${key.key}`).boundingClientRect()})query.exec((res) => {// 第一个参数是外层滚动框距离顶部的高度topList.value = res.map((item) => {return item.top})tabs.map((item, index) => {item.top = topList.value[index + 1] - topList.value[0]})})
}// 滚动判断高度
function handleScroll(e: any) {debouncedScrollEnd(e)
}const debouncedScrollEnd = debounce(async (e) => {const scrollTop = e.detail.scrollTop// 遍历sectionTops,找到当前所在的sectionfor (let i = 0; i < tabs.length; i++) {if (scrollTop >= tabs[i].top && scrollTop <= tabs[i + 1].top && i < tabs.length - 1) {currentTab.value = tabs[i].keybreak} else if (i === tabs.length - 1) {// 最后一个元素currentTab.value = tabs[i - 1].keybreak}}
}, 500)// 随机颜色生成
function getRandomColor(index: number): string {const colors = ['#53C89C','#4EBCDE','#2E8AF0','#588BEA','#6875E4','#9370DB','#FC9682','#F5A882','#F8BF7F','#F5D678','#63D5D2',]return colors[index % colors.length]
}function handleViewMore(type) {uni.navigateTo({url: `/pages-sub/property/${type}?companyId=${id.value}`,})
}
</script>
<style lang="scss" scoped>
.section {background: #fff;margin-bottom: 16rpx;
}
.content-scroll {height: calc(100vh - 30rpx);
}
</style>