uniapp侧边导航
<template> <view class="bodys"> <u-navbar :placeholder="true" title="菜单" @leftClick="backBtn"> </u-navbar> <view id="scroll_box"> <view class="scroll_box"> <!-- :style="{ height: scrollHeight + 'px' }" --> <scroll-view :style="{ height: scrollHeight + 'px' }" scroll-y='true' class="left_box" :scroll-into-view="leftIntoView"> <view class="left_item" v-for="(item,i) in leftArray" :key='i' @click="onLeft" :data-index="i" :id="'left-'+i" :class="{select:i == leftIndex}"> {{item}} </view> </scroll-view> <!-- --> <scroll-view :style="{ height: scrollHeight + 'px' }" @scroll="mainScroll" :scroll-into-view="scrollInto" scroll-y='true' style="overflow: auto;" class="right_box" scroll-with-animation="true"> <slot></slot> <view class="right_item" v-for="(item,i) in rightArray" :key='i' :id="'item-'+i"> <view class="rigth_title"> {{item.title}} </view> <view class="lis" v-for="(items,j) in item.list" :key='j'> {{items}} </view> </view> <view class="fill-last" :style="{ height: fillHeight + 'px' }"></view> </scroll-view> </view> </view> </view> </template> <script> export default { name: "side-navigation", data() { return { leftArray: [], rightArray: [], scrollHeight: 400, scrollInto: "", leftIndex: 0, topArr: [], scrollTopSize: 0, fillHeight: 0, // 填充高度,用于最后一项低于滚动区域时使用 leftIntoView:"" // 左侧滚动位置定位 } }, computed: { /* 计算左侧滚动位置定位 */ // leftIntoView() { // // return `left-${this.leftIndex > 3 ? this.leftIndex - 3 : 0}`; // } }, mounted() { /* 等待DOM挂载完成 */ this.$nextTick(() => { /* 在非H5平台,nextTick回调后有概率获取到错误的元素高度,则添加200ms的延迟来减少BUG的产生 */ setTimeout(() => { /* 等待滚动区域初始化完成 */ this.initScrollView().then(() => { /* 获取列表数据,你的代码从此处开始 */ this.getListData(); }); }, 200); }); // 获取高度 let height const res = uni.getSystemInfoSync() if(res.platform==='ios'){ height = 44+res.statusBarHeight }else if(res.platform==='android'){ height = 48+res.statusBarHeight }else{ height = 0; } uni.getSystemInfo({ success:(res=>{ // this.scrollHeight = res.windowHeight-uni.upx2px(80)-height; this.scrollHeight = res.windowHeight-height; }) }) }, methods: { /* 初始化滚动区域 */ initScrollView() { return new Promise((resolve, reject) => { let view = uni.createSelectorQuery().in(this).select('#scroll_box'); view.boundingClientRect(res => { console.log(res) this.scrollTopSize = res.top; // this.scrollHeight = res.height; this.$nextTick(() => { resolve(); }); }).exec(); }); }, // 获取数据 getListData() { new Promise((resolve, reject) => { uni.showLoading(); setTimeout(() => { let [left, main] = [ [], [] ]; for (let i = 0; i < 25; i++) { left.push(`${i + 1}类商品`); let list = []; let r = Math.floor(Math.random() * 10); r = r < 1 ? 3 : r; for (let j = 0; j < r; j++) { list.push(j); } main.push({ title: `第${i + 1}类商品标题`, list }); } // 将请求接口返回的数据传递给 Promise 对象的 then 函数。 resolve({ left, main }); }, 1000); }).then(res => { uni.hideLoading(); this.leftArray = res.left; this.rightArray = res.main; // DOM 挂载后 再调用 getElementTop 获取高度的方法。 this.$nextTick(() => { this.getElementTop(); }); }); }, // 获取元素顶部信息 getElementTop() { new Promise((resolve, reject) => { let view = uni.createSelectorQuery().in(this).selectAll('.right_item'); view.boundingClientRect(data => { resolve(data); }).exec(); }).then(res => { console.log(res); let topArr = res.map(item => { return item.top - this.scrollTopSize; /* 减去滚动容器距离顶部的距离 */ }); this.topArr = topArr; /* 获取最后一项的高度,设置填充高度。判断和填充时做了 +-20 的操作,是为了滚动时更好的定位 */ let last = res[res.length - 1].height; if (last - 20 < this.scrollHeight) { this.fillHeight = this.scrollHeight - last + 20; } }); }, // 点击左侧导航 onLeft(e) { const index = e.currentTarget.dataset.index; this.leftIndex = index this.scrollInto = `item-${index}` }, // 右侧滑动 mainScroll(e) { console.log(e) let top = e.detail.scrollTop; let index = 0; /* 查找当前滚动距离 */ for (let i = this.topArr.length - 1; i >= 0; i--) { /* 在部分安卓设备上,因手机逻辑分辨率与rpx单位计算不是整数,滚动距离与有误差,增加2px来完善该问题 */ if (top + 2 >= this.topArr[i]) { index = i; break; } } this.leftIndex = index < 0 ? 0 : index; }, }, } </script> <style> page,.bodys { height: 100%; } .scroll_box { display: flex; /* height: 100%; */ } .left_box { width: 30%; overflow: auto; } .right_box { overflow: auto; } .left_item { height: 80rpx; } .lis { height: 200rpx; border-radius: 10rpx; background: #808080; color: #FFFFFF; text-align: center; line-height: 200rpx; margin-bottom: 10rpx; } .select { background-color: #4CD964; } </style>
来源:https://blog.csdn.net/qq_45909266/article/details/120159992
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通