vue3-h5-table
介绍
适用于 vue3 + ts 的 h5 移动端项目 table 组件
支持 左侧固定 滑动 每行点击回调 支持 指定列排序
链接 :https://github.com/duKD/vue3-h5-table
效果
props说明minTableHeight表格最小高度 可选 默认600rowNum表格显示几行 可选 默认 6headerHeight头部默认高度 可选 默认 60rowHeight每行数据的默认高度 默认 100column每列数据说明 见下文tableDates表格数据fixedHeader是否固定表头 默认true
exporttypecolumnItemType={
title:string// 列名
dataIndex?:string// table data key 值
width?:number// 列 宽度
slotKey?:string// 插槽作用域 id
sortable?:boolean//是否 支持排序
align?:'left'|'center'|'right'// 布局
key?:string// 哪个列数据 作为 唯一key 值 默认 index
render?:(h:renderType,row:any)=>void// 自定义render}typepropsType={
minTableHeight?:number;//表格最小高度
rowNum?:number;// 表格显示几行
headerHeight?:number;// 头部默认高度
rowHeight?:number;//每行数据的默认高度
column:Array<columnItemType>;
tableDates:Array<any>;
fixedHeader?:boolean;// 是否固定表头
isClick?:boolean;// 是否需要触发行点击事件
disable?:boolean;// 是否启用下拉加载
error?:boolean;// 数据加载失败
loading?:boolean;// 数据处于加载状态
finish?:boolean;// 数据 是否完全加载
loadingText?:string;// 加载文案
errorText?:string;// 失败文案
finishedText?:string;// 完成文案
offset?:number;//触发加载的底部距离
rootValue?:number;//
optimized?:boolean;// 是否开启优化};
使用 实例:
<template><divclass="position"><sectionstyle="height: 200px"></section><h5-tableref="h5TableRef":fixed-header="true":column="column":table-dates="tableDates"@row-click="rowClick"@handle-head-sort-click="handleHeadSortClick"v-model:error="error":is-click="true"v-model:loading="loading":finish="finish"@load="onload"><template#titleSlot><sectionclass="nameAndMarkValueTitle"><div><spanclass="name_1"> 班费 </span>/<spanclass="name_2">
总和
</span></div></section></template><template#title="item"><sectionclass="nameAndMarkValue"><divclass="name">
{{ item.select }}
<spanclass="type">{{ item.type === 1 ? "深" : "沪" }}</span></div><divclass="markValue">{{ item.markValue }}=={{ item.id }}</div></section></template><template#positionAndUse="item"><sectionclass="positionAndUse"><divclass="position">
{{ item.position }}
</div><divclass="use">{{ item.use }}</div></section></template><template#curAndCost="item"><sectionclass="curAndCost"><divclass="cur">
{{ item.cur }}
</div><divclass="cost">{{ item.cost }}</div></section></template><template#floatAndProfit="item"><sectionclass="floatAndProfit"><divclass="float">{{ item.float }}</div><divclass="profit">{{ item.profit }}</div></section></template><template#rowDownMark><sectionclass="rowDownMark"><divclass="rowDownMark-item"@click="handelSell">买入</div><divclass="rowDownMark-item">卖出</div><divclass="rowDownMark-item">行情</div></section></template></h5-table></div></template><scriptsetuplang="ts">import{ H5Table }from"../lib/h5-table";import type { columnItemType, sortStatusType }from"../lib/h5-table/types";import{ ref, watch }from"vue";constcolumn: Array<columnItemType>=[{title:"班费/总值",key:"id",dataIndex:"nameAndMarkValue",width:250,slotKey:"title",slotTitleKey:"titleSlot",align:"left",},{title:"持仓/可用",slotKey:"positionAndUse",dataIndex:"positionAndUse",sortable:true,width:200,align:"right",},{title:"现价/成本",slotKey:"curAndCost",dataIndex:"curAndCost",// sortable: true,width:200,align:"right",},{title:"浮动/盈亏",width:200,slotKey:"floatAndProfit",align:"right",},{title:"账户资产",dataIndex:"count",width:200,},];const datas =[{id:0,select:"三年二班",type:1,position:"27000",use:"5,000",markValue:"500,033.341",cur:"30.004",cost:"32.453",newPrice:20,float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:1,select:"四年一班",type:1,markValue:"23,933.341",position:"28000",use:"5,000",newPrice:20,cur:"30.004",cost:"32.453",float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:2,select:"三年二班",markValue:"500,033,341",newPrice:20,cur:"30.004",cost:"32.453",position:"27300",use:"5,000",float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:3,select:"五年二班",markValue:"500,033,341",position:"27000",use:"5,000",cur:"30.004",cost:"32.453",newPrice:20,float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:4,select:"一年二班",markValue:"500,033,341",position:"27000",use:"5,000",newPrice:20,cur:"30.004",cost:"32.453",float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:5,select:"六年三班",markValue:"500,033,341",position:"37000",use:"5,000",newPrice:20,cur:"30.004",cost:"32.453",float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:6,select:"六年二班",markValue:"500,033,341",position:"37000",use:"5,000",newPrice:20,cur:"30.004",cost:"32.453",float:"+18,879.09",profit:"-5.45%",count:"120,121",},{id:7,select:"六年五班",markValue:"500,033,341",position:"37000",use:"5,000",newPrice:20,cur:"30.004",cost:"32.453",float:"+18,879.09",profit:"-5.45%",count:"120,121",},];const temp = Array.from({length:300}).map((item, index)=>{return{id: index,select:"三年二班",type:1,position:"27000",use:"5,000",markValue:"500,033.341",cur:"30.004",cost:"32.453",newPrice:20,float:"+18,879.09",profit:"-5.45%",count:"120,121",};});const tableDates = ref<Array<any>>(JSON.parse(JSON.stringify(temp)));const h5TableRef = ref<typeof H5Table |null>(null);const loading = ref<boolean>(false);const error = ref<boolean>(false);const finish = ref<boolean>(false);constonload=()=>{
console.log("loading====");setTimeout(()=>{
tableDates.value = tableDates.value.concat(
Array.from({length:100}).map((item, index)=>{return{id:newDate().getTime()+ index,select:"三年二班",type:1,position:"27000",use:"5,000",markValue:"500,033.341",cur:"30.004",cost:"32.453",newPrice:20,float:"+18,879.09",profit:"-5.45%",count:"120,121",};}));
loading.value =false;},1000);// setTimeout(() => {// error.value = true;// }, 1000);// setTimeout(() => {// finish.value = true;// }, 1000);};constrowClick=(item: any,index: number)=>{if(h5TableRef.value){//第一个参数 即是 设计稿 插槽的高度
h5TableRef.value.handleDom(60, index);}};//处理排序consthandleHeadSortClick=(propsKey: string,type: sortStatusType)=>{if(h5TableRef.value){
h5TableRef.value.handleDom(60,-1);}if(type ===0){
tableDates.value.splice(0, tableDates.value.length,...datas);return;}if(propsKey ==="positionAndUse"){if(type ===1){
tableDates.value.sort((a, b)=>Number(b.position)-Number(a.position));}else{
tableDates.value.sort((a, b)=>Number(a.position)-Number(b.position));}}};watch(tableDates.value,()=>{
console.log("watch====", tableDates);});consthandelSell=()=>{
console.log("handelSell====");};</script><style>body{padding: 0;margin: 0 !important;}</style><stylelang="scss"scoped>.position{font-size: 24px;.nameAndMarkValueTitle{display: flex;}.nameAndMarkValue{padding: 10px;.name{display: inline-block;position: relative;color: #222;font-size: 32px;.type{position: absolute;top: 50%;transform:translateY(-50%);right: -40px;display: inline-block;font-size: 24px;border: 1px solid #ff858d;padding: 0 4px;color: #ff858d;}}.markValue{color: #999;font-size: 24px;}}.positionAndUse{font-size: 28px;.position{color: #222;}.use{color: #999;}}.curAndCost{font-size: 28px;.cur{color: #222;}.cost{color: #999;}}.floatAndProfit{color: red;}.rowDownMark{width: 100%;display: flex;height: 60px;background-color: #fcfcfc;align-items: center;.rowDownMark-item{flex-grow: 1;color: #309fea;text-align: center;}}}</style>
具体使用参考 github 项目中 app.vue 文件
更新日志
2023.9.7 更新
表格性能优化 支持设置最多同时显示多少条数据优化。(开启下拉加载时不支持)
optimized 开启优化 默认时 30+ 40 + 30 超过 100 部分 会动态的计算 是否隐藏掉 核心逻辑在 useHandleScroll 里面
2023.9.27
- 修改transform 渲染方式 不经过 vue 派发更新(数据量过大 会有卡顿),直接用原生js 去控制 具体表现如下图(1000条列表数据) 在左右滑动1s内 有300多ms 消耗到 vue3 的派发更新上,但是我们人为是知道只有组件样式需要改变,所以可以考虑优化 ,将更新的操作用原声js 实现 ,不走vue 响应更新
vue派发更新时间就省略了,响应速度提高了200多ms。就基本不会卡顿了
- 增加 rootValue 配置 默认75(基于rootValue 去将 props 中的 一些 长度单位 传化成 rem) 修复pad 样式问题(保持和 postCssPxToRem 插件配置一致 ) postCssPxToRem({ // 自适应,px>rem转换 rootValue: 75, // 75表示750设计稿,37.5表示375设计稿 propList: [“*”], // 需要转换的属性,这里选择全部都进行转换 selectorBlackList: [“norem”], // 过滤掉norem-开头的class,不进行rem转换 }),
- 优化一些参数命名
- 将点击 显示操作栏目的操作 更多内置化,便于使用
版权归原作者 我叫卷卷卷呀 所有, 如有侵权,请联系我们删除。