Skip to content

sk-linkage-menu 左右联动菜单 ​

左右联动菜单(分类导航):点击左侧分组,右侧内容区平滑滚动联动;右侧滚动时,左侧菜单高亮反向联动。支持分组吸顶标题、受控选中(v-model:current)、异步加载后自动重新测量,以及大数据量下的分组级虚拟渲染。

该组件来自 shukelab(uni-app 跨端组件库),以 uni_modules 目录形式分发、不发布 npm,支持 H5 / 微信小程序。安装方式见快速上手,全部组件见总览。 下方演示实时内嵌 shukelab 的 H5 在线构建,可直接交互;本地联调时 shukelab 跑 pnpm dev:h5、本站跑 pnpm docs:dev 即可热更新预览(需临时把 iframe 地址指向本地,见快速上手末节)。

在线体验 ​

演示通过手机壳 iframe 实时加载 shukelab H5 版对应页面,可直接操作。宽屏下停靠在页面右侧常驻,随正文滚动自动切换对应示例,也可点击面板内 Tab 手动切换;更宽的屏幕下面板左侧会显示本页目录,点击二维码图标可扫码在手机上打开。窄屏下展示在下方。

演示加载中…

基础用法 ​

组件默认填满父容器,尺寸由父级控制。左侧为分组菜单,右侧为内容区,通过默认插槽渲染每条数据。

vue
<template>
  <sk-linkage-menu :list="list" :virtual-menu-height="500">
    <template #default="{ data }">
      <view class="class-item">
        <image :src="data.image" class="item-image" />
        <text class="goods-title">{{ data.name }}</text>
      </view>
    </template>
  </sk-linkage-menu>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { MenuDataItem } from '@/uni_modules/sk-linkage-menu/components/sk-linkage-menu/sk-linkage-menu.types'

const list = ref<MenuDataItem[]>([])

onMounted(() => {
  for (let i = 0; i < 20; i++) {
    list.value.push({
      name: `${i} 号分类`,
      id: i,
      data: [
        { name: `商品 ${i}-A`, image: 'https://picsum.photos/seed/a/200/200' },
        { name: `商品 ${i}-B`, image: 'https://picsum.photos/seed/b/200/200' },
      ],
    })
  }
})
</script>

分组吸顶标题 ​

开启 showTitle 后,右侧滚动时当前分组名称吸顶展示,可通过 title 插槽自定义。

vue
<sk-linkage-menu :list="list" :show-title="true">
  <template #title="{ item }">
    <text class="my-title">{{ item.name }}</text>
  </template>
  <template #default="{ data }">
    <view>{{ data.name }}</view>
  </template>
</sk-linkage-menu>

受控选中 ​

通过 v-model:current 受控当前选中分组,点击/滚动/方法调用都会派发 update:current。

vue
<script setup lang="ts">
import { ref } from 'vue'

const current = ref(0)
</script>

<template>
  <sk-linkage-menu v-model:current="current" :list="list" />
</template>

自定义左侧菜单项 ​

通过 menu 插槽自定义图标 / 角标,active 表示是否选中。

vue
<sk-linkage-menu :list="list">
  <template #menu="{ item, index, active }">
    <view class="menu-item" :class="{ active }">
      <text>{{ item.name }}</text>
      <text v-if="item.badge" class="badge">{{ item.badge }}</text>
    </view>
  </template>
  <template #default="{ data }">
    <view>{{ data.name }}</view>
  </template>
</sk-linkage-menu>

程序化跳转 & 异步加载 ​

通过 ref 调用 scrollToIndex 跳转;数据异步加载完成后组件会自动重新测量布局,无需手动处理。

vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'

const menuRef = ref()
const list = ref([])

// 异步加载数据,组件会自动 refresh
onMounted(async () => {
  list.value = await fetchMenuData()
})

// 手动跳转到第 3 个分组
const jump = () => menuRef.value?.scrollToIndex(3)
</script>

<template>
  <sk-linkage-menu ref="menuRef" :list="list" />
</template>

API ​

Props ​

属性名类型默认值说明
virtualMenuHeightNumber窗口高度 - 44组件可视高度(px)
listMenuDataItem[][]菜单数据,结构见下方 MenuDataItem
virtualBooleantrue分组级虚拟渲染开关,大数据量建议保持开启
currentNumber0当前选中菜单下标,支持 v-model:current
showTitleBooleanfalse是否显示右侧分组吸顶标题
menuWidthString'180rpx'左侧菜单宽度
scrollWithAnimationBooleantrue右侧程序化滚动是否使用动画
leftBarStyleObject-左侧选中滑块样式
leftBarUnStyleObject-左侧未选中菜单项样式
itemHeightNumber130已废弃:分组高度改为自动测量,保留仅为兼容旧版

Events ​

事件名说明回调参数
change选中分类变化时触发(点击、滚动、方法调用均会触发){ ...item, index, currenIndex, source },source 为 click / scroll / method
update:current选中下标变化,配合 v-model:current 使用index: number
scrolltolower右侧内容区滚动触底,可用于分页加载原生事件对象

Slots ​

插槽名说明作用域参数
default右侧内容项,每条数据渲染一次{ data }(分组与内容项字段合并)
menu左侧菜单项,可自定义图标/角标{ item, index, active }
title右侧分组吸顶标题(需开启 showTitle){ item, index }
emptylist 为空时的占位内容-

Methods(通过 ref 调用) ​

方法名说明参数
scrollToIndex程序化跳转到指定菜单index: number
refresh重新测量布局。数据变更后组件会自动调用,插槽内容高度变化(如图片撑高)时可手动调用-
属性名类型必填说明
nameString是左侧菜单名称
dataArray是右侧内容列表
idNumber / String建议唯一标识,优先作为渲染 key

平台兼容性 ​

平台支持
H5✅
微信小程序✅
App—

相关链接 ​

Released under the MIT License.