uniapp锚点定位 、自动吸顶、滚动自动选择对应的锚点
uniapp锚点定位 、自动吸顶、滚动自动选择对应的锚点
·
vue3+uniapp+uview
vue3 uview框架:https://vkuviewdoc.fsq.pub/components/picker.html
<template>
<view class="main">
<view class="mt25 all-menu box-shadow border-radius5">
<text class="title mb10">全部菜单</text>
<view class="x-p-titleList">
<u-sticky>
<!-- 只能有一个根元素 -->
<view class="sticky">
<u-tabs :list="dataList" :is-scroll="true" v-model="current" @change="change">
</u-tabs>
</view>
</u-sticky>
<scroll-view class="scroller mt5" :scroll-into-view="toView" scroll-y="true"
scroll-with-animation="true">
<view class="x-p-listItem" v-for="item in dataList" :key="item.id" :id="item.id">
<u-line color="#bbbbbb" />
<view class="mt5 mb5">{{item.name}}</view>
<view v-for="info in item.moduleList" :key="info.moduleId"
class="listItem-dtl u-icon-wrap u-row-between">
<view class="u-flex">
<image :src="info.icon"></image>
<text>{{info.label}}</text>
</view>
<view>
<u-button type="primary" class="add-btn" v-if="isAdd">添加</u-button>
<u-button class="add-btn" v-else>已添加</u-button>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script lang="ts">
import {
ref,
reactive,
onMounted,
} from 'vue'
export default {
setup() {
const keyword = ref('')
// ----------------------------------------
const current = ref(0)
const dataList = reactive([{
id: 'item1',
name: '办公OA',
moduleList: [{
moduleId: '5001',
label: '出差申请',
icon: '../../static/logo.png'
},
{
moduleId: '5002',
label: '加班申请',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '5003',
label: '请假申请',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '5004',
label: '办公用品申请',
icon: '../../static/images/nav_car_apply.png'
}
]
}, {
id: 'item2',
name: '生产管理',
moduleList: [{
moduleId: '6001',
label: '生产',
icon: '../../static/logo.png'
},
{
moduleId: '6002',
label: '领料',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6003',
label: '销售出库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
}
]
}, {
id: 'item3',
name: '进销存管理',
moduleList: [{
moduleId: '5001',
label: '出差申请',
icon: '../../static/logo.png'
},
{
moduleId: '5002',
label: '加班申请',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '5003',
label: '请假申请',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '5004',
label: '办公用品申请',
icon: '../../static/images/nav_car_apply.png'
}
]
}, {
id: 'item4',
name: '供应商管理',
moduleList: [{
moduleId: '6001',
label: '生产',
icon: '../../static/logo.png'
},
{
moduleId: '6002',
label: '领料',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6003',
label: '销售出库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
}
]
}, {
id: 'item5',
name: '实验室管理',
moduleList: [{
moduleId: '6001',
label: '生产',
icon: '../../static/logo.png'
},
{
moduleId: '6002',
label: '领料',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6003',
label: '销售出库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
}
]
}, {
id: 'item6',
name: '生产管理',
moduleList: [{
moduleId: '6001',
label: '生产',
icon: '../../static/logo.png'
},
{
moduleId: '6002',
label: '领料',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6003',
label: '销售出库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
},
{
moduleId: '6004',
label: '销售入库',
icon: '../../static/images/nav_car_apply.png'
}
]
}])
let toView = ref('')
// 锚点
function change(index) {
// var id = event.currentTarget.dataset.id;
var id = 'item' + (index + 1)
toView = id;
uni.createSelectorQuery().select('#' + toView).boundingClientRect(data => { //目标位置的节点:类或者id
uni.createSelectorQuery().select(".x-p-titleList").boundingClientRect(
res => { //最外层盒子的节点:类或者id
uni.pageScrollTo({
duration: 100, //过渡时间
// scrollTop: data.top - res.top - 10 //到达距离顶部的top值
scrollTop: data.top - res.top + 45 //到达距离顶部的top值
})
}).exec()
}).exec();
}
let isAdd = ref(true)
// --------------------------------------
let distanceArr = reactive([]) // 每一个ID对应的scrollTop值
// 获取所有元素在当前页面所处的位置信息
function getDistanceArr() {
dataList.map(el => {
uni.createSelectorQuery().select('#' + el.id).boundingClientRect(data => { //目标位置的节点:类或者id
// 获取当前ID距离顶部的top值
distanceArr.push(data.top)
}).exec();
})
}
// 生命周期
onMounted(() => {
getDistanceArr()
})
return {
keyword,
current,
dataList,
toView,
change,
isAdd,
distanceArr,
getDistanceArr
}
},
// onShow() {
// this.getDistanceArr()
// },
// 监听页面滚动
onPageScroll(event) {
const _this = this
if (this.isTabChange) {
return
}
const {
scrollTop
} = event;
const skewY =100 // 偏移量,由于吸顶的tab、头部的显示信息也有高度,素以做了偏移量
if (scrollTop >= skewY) {
if (!this.showTabs && this.current <= 0) { // 在未显示tab并且 current <= 0时,防止uview ui抖动bug,设置默认复位值
this.current = 0
}
this.showTabs = true
this.$nextTick(() => {
const length = this.distanceArr.length
const index = this.distanceArr.findIndex(el => el - skewY - scrollTop > 0)
// 当index == -1 的时候,实际当前滚动的距离超出了最大值,也就是在最后一个tab显示的内容
// 当index > 0 的时候,说明能在当前的scrollTop值找到,即index的前一位
// this.current = index > 0 ? index - 1 : length - 1
this.current = index > 0 ? index - 1 : 0
})
}
// else {
// this.showTabs = false
// }
}
}
</script>
<style lang="scss">
.main {
padding: 20rpx;
}
.all-menu {
padding: 10rpx;
.title {
font-size: 16px;
// font-weight: bold;
}
}
// --------------------
.list-cell {
display: flex;
box-sizing: border-box;
width: 100%;
padding: 10px 24rpx;
color: #323233;
font-size: 14px;
line-height: 24px;
background-color: #fff;
}
.listItem-dtl {
height: 100rpx;
image {
height: 80rpx;
width: 80rpx;
margin-right: 16rpx;
}
}
.search {
position: fixed;
}
.scroller {
box-sizing: border-box;
padding: 0 15rpx;
}
</style>
调用接口使用过程中的问题及解决
1.使用vue3赋值问题:
let dataList=reactive([])改成let obj=reactive({dataList:[]})
html部分修改:obj.dataList
<u-tabs :list="obj.dataList" :is-scroll="true" v-model="current" @change="change">
</u-tabs>
<view class="x-p-listItem" v-for="(item,idxBlock) in obj.dataList" :key="item.menuId"
:id="'item'+idxBlock">
2.js
import {
ref,
reactive,
onMounted,
nextTick
} from 'vue'
export default {
setup() {
let obj = reactive({
dataList: []
})
// 获取全部菜单列表
function getAllMenuList() {
listMenu(queryParams).then(res => {
let data = res.data.data.map(s => {
s.visible = false
return s
})
let arr = handleTree(data, 'menuId')
let newArr = []
arr.forEach(item => {
item.name = item.menuName
item.id = item.menuId
if (item.menuType != 'C') {
newArr.push(item)
}
})
obj.dataList = newArr
// 记录每个模块节点位置,请求到数据挂在完成后执行,去掉原来的getDistanceArr方法
nextTick(() => {
obj.dataList.map((el, index) => {
uni.createSelectorQuery().select('#item' + index).boundingClientRect(
data => { //目标位置的节点:类或者id
// 获取当前ID距离顶部的top值
distanceArr.push(data.top)
}).exec();
})
})
})
}
// 生命周期
onMounted(() => {
getAllMenuList()
// getDistanceArr()
})
return {
keyword,
current,
obj,
toView,
change,
isAdd,
distanceArr,
addOrCancelMenu,
}
},
更多推荐
已为社区贡献4条内容
所有评论(0)