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事件问题
2024.7.26
修复一个页面使用多次组件 导致的滑动问题
发表评论