企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
> 双联动属于一个常见的需求组件,左右的元素可进行联动定位 ![](https://img.kancloud.cn/cc/55/cc55284ab5466d4064136a833422f479_646x368.png) > 主要用到了scroll-view一下特性 > 1. scroll-into-view 滚动到指定id的元素位置 > 2. scroll-with-animation 滚动使用动画效果 > 3. @scrolltolower 滚动至底部 > 4. @scroll 滚动事件(~~当滚动时,定位的scrollTop在元素区间位置进行联动定位,逻辑实现~~) > 官网文档:https://uniapp.dcloud.io/component/scroll-view ``` <template> <view class="m-conatiner"> <view class="left"> <view :class="{activeClass:currentIndex == index}" v-for="(item,index) in list" :key="index" @click="setViewId(index)">{{item.title}}</view> </view> <view class="right"> <scroll-view scroll-y="true" :scroll-into-view="viewId" scroll-with-animation @scroll="scroll" @scrolltolower="scrolltolower" style="white-space: nowrap;height: 400rpx;" > <view v-for="(item, index) in list" :key="index"> <view class="title" :id="'title'+index">{{item.title}}</view> <view v-for="(it,idx) in item.alist" :key="idx">{{it}}</view> </view> </scroll-view> </view> </view> </template> <script> export default { data() { return { list: [ {title:'中餐',alist: ['馒头','包子','盖饭','炒面','饺子','鸡排饭']}, {title:'西餐',alist: ['牛排','意大利面','披萨','汉堡']}, {title:'法餐',alist: ['鹅肝1','鹅肝2','鹅肝3','鹅肝4','鹅肝5','鹅肝6','鹅肝7','鹅肝8','鹅肝9','鹅肝10']} ], viewId: '', currentIndex: 0, topList: [] } }, onLoad() { }, onReady(){ this.getNodeInfo(); }, methods: { setViewId(index) { // 点击左边标题 触发事件 动态改变左边标题的id this.viewId = 'title'+index; this.currentIndex = index; }, scroll(e) { // 右边滚动触发事件 获取每个标题间的距离,判断滚动的高度在哪个区间内 let scrollTop = e.target.scrollTop+1; for(let i=0; i<this.topList.length; i++) { const h1 = this.topList[i]; let h2 = this.topList[i+1]; if (scrollTop >= h1 && scrollTop < h2){ this.currentIndex = i; } } }, scrolltolower(){ // 滚动到底部触发 setTimeout(()=> { this.currentIndex = this.list.length -1; },80) }, getNodeInfo(){ // 获取DOM 取得每个标题间的高度。exec执行 let query = uni.createSelectorQuery().in(this); query.selectAll('.title').boundingClientRect(data => { console.log("得到布局位置信息",data,); let arr = []; data.map(item=>{ arr.push(item.top) }) this.topList = arr; }).exec(); } } } </script> <style lang="scss"> .m-conatiner{ width: 100%; height: 400rpx; border: 2rpx solid #ddd; display: flex; justify-content: space-between; align-items: center; box-sizing: border-box; } .left{ flex: 0 0 200rpx; height: 100%; border: 2rpx solid red; .activeClass{ background: pink; } } .right{ flex: 1; height: 100%; border: 2rpx solid red; .title{ font-size: 40rpx; font-weight: bold; background: pink; } } </style> ```