# t-slider-menu
SliderMenu 侧边分类
t-slider-menu 组件介绍
t-slider-menu 是侧边分类联动组件,整个界面(含滚动、惯性滑行与联动动画)均由 Canvas 自绘实现。左侧为分类菜单,右侧为对应分类内容列表;点击左侧菜单平滑滚动到右侧对应分组,拖动右侧列表时左侧高亮与居中位置自动跟随。绘制采用虚拟分段方案,只渲染可视区元素,数据量再大也不影响滚动流畅度。
组件本身不解析列表布局,而是把 list 数据交给内部渲染指令通道(slider-store 经服务端模板渲染接口生成 Canvas 绘制指令),组件负责指令的拉取、缓存与执行,点击商品行时再通过 id 区间命中原数据并抛出。
t-slider-menu 平台兼容
| Harmony | H5 | Android | iOS | 小程序 | UTS |
|---|---|---|---|---|---|
| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
t-slider-menu 基础用法
基础用法参考 demo/slider-menu/slider-menu.uvue。通过 list 属性传入分类数据,组件放入具有确定高度的容器中(class="f" 占满剩余高度或显式设置高度),渲染数据会自动拉取。
vue
<template>
<t-page :class="[`p-15 tpg`]">
<t-card class='mb-15'
title="侧边分类"
sub-title="自研canvas flex布局渲染引擎实现(整个界面和滚动动画都是canvas绘制),虚拟滚动原理,只绘制可视区元素,联动动画流畅,canvas绘制跨平台兼容适配好"></t-card>
<t-section title="插槽用法"
class="mb-15"></t-section>
<t-slider-menu class="f"
:list="LIST"
@itemTap="onItemTap"></t-slider-menu>
</t-page>
</template>
<script setup>
const LIST : UTSJSONObject[] = [{
id: 1,
title: '为你推荐',
data: [{
goods_name: 'iphone15钢化膜 全屏覆盖',
goods_id: 368,
goods_img: 'https://cbu01.alicdn.com/img/ibank/O1CN01go0a6Z1PV3PYozGWd_!!2814831845-0-cib.jpg',
shop_price: '6.99',
sortKey: 'ac86eece-a01c-468d-9189-91e4c6474331'
}, {
goods_name: '便携折叠电煮锅',
goods_id: 580,
goods_img: 'https://cbu01.alicdn.com/img/ibank/O1CN01sIB82T1JaecYg06Mx_!!29504198-0-cib.jpg',
shop_price: '209.99',
sortKey: 'ccccd175-dff9-4abb-a787-ab1ab36f0ad6'
}]
}, {
id: 2,
title: '会员专区',
data: [{
goods_name: '透明玻璃保温杯',
goods_id: 533,
goods_img: 'https://cbu01.alicdn.com/img/ibank/O1CN01IgQtDN25X58qhi4DA_!!2210317187535-0-cib.jpg',
shop_price: '88.99',
sortKey: 'a4d9c887-7b8c-49f7-ab00-81e81613ecf8'
}]
}]
// 点击右侧商品行:抛出该条原始数据,可在此跳转商品详情
function onItemTap(item : UTSJSONObject) {
console.log('itemTap 原始数据: ' + JSON.stringify(item))
}
</script>渲染数据说明
组件渲染右侧内容区与左侧菜单所需的 Canvas 绘制指令由服务端模板渲染产生,流程封装在 uni_modules/tui-drawer/common/slider-store.uts:
- 组件挂载后按当前可用宽度自动请求:右侧走
getTemplateCollection(category-head分组头模板 +goods-row商品行模板),左侧走getTemplateRender(menu-item菜单模板); - 请求结果写入模块级缓存与
storage持久缓存,缓存 key 以窗口宽度 - 30 - menuWidth规范化。再次进入页面(如首页预取后跳转)命中缓存直接渲染,不重复请求;并发同参请求自动合并; list中各分组title渲染为左侧菜单项,data内每条的goods_name/goods_img/shop_price渲染为右侧商品行,其余字段原样保留并在点击时通过itemTap抛回。
t-slider-menu Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
list | 分类分组数据。结构:[{ title: string, data: [{ goods_name, goods_img, shop_price, ... }] }] | Array | [] |
menuWidth | 左侧菜单栏宽度(逻辑像素),右侧内容宽度自动为容器宽度减去该值 | number | 100 |
t-slider-menu Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
itemTap | 点击右侧商品行时触发,返回该行对应的原始数据条目 | UTSJSONObject |
注意事项
- 组件需要在具备明确高度的容器中使用(
flex: 1或固定高度),画布视口高度取自容器实际高度; - 组件为全 Canvas 绘制,内部
view仅用作触摸命中区,无需也不支持自定义渲染插槽; - 首次渲染依赖服务端模板渲染接口,请确认对应的模板服务已配置(未命中缓存时内部以当前宽度兜底请求,失败会
console.log提示); - 分类项较多、内容超长时可自由滚动,组件内置惯性滑行、边界回弹与轻点命中判定。