一个 适用 vue3 ts h5移动端 table组件
cheerfulCoder 2024-06-11 09:33:02 阅读 72
vue3-h5-table
介绍
适用于 vue3 + ts 的 h5 移动端项目 table 组件
支持 左侧固定 滑动 每行点击回调 支持 指定列排序
链接 :https://github.com/duKD/vue3-h5-table
效果
props | 说明 |
---|---|
minTableHeight | 表格最小高度 可选 默认600 |
rowNum | 表格显示几行 可选 默认 6 |
headerHeight | 头部默认高度 可选 默认 60 |
rowHeight | 每行数据的默认高度 默认 100 |
column | 每列数据说明 见下文 |
tableDatas | 表格数据 |
fixedHeader | 是否固定表头 默认true |
export type columnItemType = { 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 }type propsType = { minTableHeight?: number; //表格最小高度 rowNum?: number; // 表格显示几行 headerHeight?: number; // 头部默认高度 rowHeight?: number; //每行数据的默认高度 column: Array<columnItemType>; tableDatas: Array<any>; isClick?: boolean; // 是否需要触发行点击事件 disable?: boolean; // 是否启用下拉加载 error?: boolean; // 数据加载失败 loading?: boolean; // 数据处于加载状态 finish?: boolean; // 数据 是否完全加载 loadingText?: string; // 加载文案 errorText?: string; // 失败文案 finishedText?: string; // 完成文案 offset?: number; //触发加载的底部距离 rootValue?: number; // };
使用 实例:
<template> <div class="position"> <section style="height: 200px"></section> <h5-table ref="h5TableRef" :column="column" :table-datas="tableDatas" @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> <section class="nameAndMarkValueTitle"> <div> <span class="name_1"> 班费 </span>/<span class="name_2"> 总和 </span> </div> </section> </template> <template #title="item"> <section class="nameAndMarkValue"> <div class="name"> { { item.select }} <span class="type">{ { item.type === 1 ? "深" : "沪" }}</span> </div> <div class="markValue">{ { item.markValue }}=={ { item.id }}</div> </section> </template> <template #positionAndUse="item"> <section class="positionAndUse"> <div class="position"> { { item.position }} </div> <div class="use">{ { item.use }}</div> </section> </template> <template #curAndCost="item"> <section class="curAndCost"> <div class="cur"> { { item.cur }} </div> <div class="cost">{ { item.cost }}</div> </section> </template> <template #floatAndProfit="item"> <section class="floatAndProfit"> <div class="float">{ { item.float }}</div> <div class="profit">{ { item.profit }}</div> </section> </template> <template #rowDownMark> <section class="rowDownMark"> <div class="rowDownMark-item" @click="handelSell">买入</div> <div class="rowDownMark-item">卖出</div> <div class="rowDownMark-item">行情</div> </section> </template> </h5-table> </div></template><script setup lang="ts">import { H5Table } from "../lib/h5-table";import type { columnItemType, sortStatusType } from "../lib/h5-table/types";import { ref, watch } from "vue";const column: 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 tableDatas = 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);const onload = () => { console.log("loading===="); setTimeout(() => { tableDatas.value = tableDatas.value.concat( Array.from({ length: 100 }).map((item, index) => { return { id: new Date().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);};const rowClick = (item: any, index: number) => { if (h5TableRef.value) { //第一个参数 即是 设计稿 插槽的高度 h5TableRef.value.handleDom(60, index); }};//处理排序const handleHeadSortClick = (propsKey: string, type: sortStatusType) => { if (type === 0) { tableDatas.value.splice(0, tableDatas.value.length, ...datas); return; } if (propsKey === "positionAndUse") { if (type === 1) { tableDatas.value.sort((a, b) => Number(b.position) - Number(a.position)); } else { tableDatas.value.sort((a, b) => Number(a.position) - Number(b.position)); } }};watch(tableDatas.value, () => { console.log("watch====", tableDatas);});const handelSell = () => { console.log("handelSell====");};</script><style>body { padding: 0; margin: 0 !important;}</style><style lang="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.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转换
}),优化一些参数命名将点击 显示操作栏目的操作 更多内置化,便于使用
2023.10.7
处理了 屏幕尺寸变化(一般生产环境 用户屏幕尺寸不会发生变化) 引发一些问题
2023.10.10
表头 固定优化 处理ios fixed 滑动问题
2023.10.20
cell组件 改为函数组件 加快渲染速度
2023.10.31
解决cloumn修改宽带导致表格宽度改变引发的空白问题
2024.1.8
修复滚动过快 无法触发load事件问题
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。