目录
本文实例为仿点餐页面左右菜单联动效果
前言
技术背景
uni-app + vue + typescript
scroll-view属性介绍
- scroll-y: 设置滚动的方向,x就是横着,y就是竖着,属性的类型是boolean值
- scroll-top:就是说scroll-top的值是距离顶部的值,你将它写在哪个scroll-view中,scroll-view就距离顶部多远,不过我们可以设置变量值,在js中按照条件更改它,这也是实现左右联动的关键步骤。
- scroll-with-animation:是在设置滚动条位置进行动画过渡
- bindscroll:绑定一个函数,由于是滚动,没有点击触发,故有一个绑定的函数,用于在滑动时执行函数内容
左右双向联动效果原理
首先获取菜单数据,数据渲染后,获取左侧菜单项的每个菜单项的滚动top值保存到数组中,同时也需要获取右侧每块菜单分类的滚动top值保存到另一个数组中,此时这两个数组的length是相等的
1.点击左边菜单项,右边菜单滚动到指定的位置
根据点击所左边菜单项的索引值,获取对应右边滚动top的数组索引值下的值,赋值给右边的scroll-top
2.滚动右边菜单,左边菜单项跳到对应的位置
右边菜单滚动时,根据当前滚动到的scrollTop值,遍历判断右边所保存的滚动top对比,如果当前值大于等于遍历值并且小于下一个遍历值,那么根据对应的索引值找出左边的滚动top数组对应的值,给左边的scroll-top赋值,并保存好当前的索引值
效果
微信小程序实现左右侧菜单联动效果
实现
index.vue
<template>
<view class="menu-wrap">
<view class="menu-header">头部内容</view>
<view class="menu-wrapper">
<view class="menu-anchor-wrapper">
<!-- 左边导航栏 -->
<scroll-view
:scroll-y="true"
:scroll-with-animation="true"
:scroll-top="scrollLeftTop"
:show-scrollbar="false"
class="menu-anchor"
>
<view
v-for="(item, index) in menuList"
:key="index"
class="menu-anchor-link"
:class="menuIndex === index ? 'active' : ''"
@click="handleClickMenuItem(index)"
>{
{item.name}}<view class="badge--top-right" v-if="item.qty">{
{ item.qty }}</view></view>
</scroll-view>
<!-- 右边内容区域 -->
<scroll-view
:scroll-y="true"
:scroll-with-animation="true"
:scroll-top="scrollRightTop"
@scroll="rightMenuScroll"
class="menu-content"
>
<view
class="menu-item"
:id="'menu' + index"
:key="index"
v-for="(menu, index) in menuList"
>
<view class="menu-title">{
{ menu.name }}</view>
<view class="menu-sub-wrap">
<menu-card
:options="{index, subIndex}"
:info="menuSub"
@click="handleClickSubItem(menuSub)"
@change="handleChangeSubItem"
:key="subIndex"
v-for="(menuSub, subIndex) in menu.menuSubList"
></menu-card>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { menuParam, menuSubParam } from '@/typings/menu'
import { resultMenuList, resultStoreData } from '@/service/menu'
import MenuCard from '@/components/menu-card.vue'
@Component({
components: {
MenuCard
}
})
export default class MenuView extends Vue {
screenHeight: number = 0
isClick: boolean = false
menuIndex: number = 0 // 左边分类栏当前的选中的项
scrollLeftTop: number = 0 // 左边分类栏项的高度
scrollRightTop: number = 0 // 当前右边栏滚动的高度
menuLeftHeightArr: Array<number> = [] // 左边栏每项高度组成的数组
menuRightHeightArr: Array<number> = [] // 右边栏每项高度组成的数组
menuList: Array<menuParam> = []
it: storeParam = {}
handleChangeSubItem({ type, index, subIndex }: any) {
const menu = this.menuList[index]
const item = menu.m