OpenTiny NEXT 从入门到精通·第 3 篇:数据篇------表格、表单与图表的高级应用
企业级中后台系统,80% 的页面都是"增删改查"的数据处理场景。表格承载着海量数据的展示与操作,表单负责复杂业务信息的录入与校验,图表则将枯燥的报表转化为直观的洞察。TinyVue 的表格、表单和图表组件,不仅功能完备,更在性能优化、复杂交互、配置化等方面提供了企业级能力。本篇将带你深入这些核心数据组件的进阶用法,让你的数据处理如虎添翼。
你是否曾因表格加载万条数据就卡顿而头疼?是否因表单联动的层层回调写得像"面条代码"而苦恼?是否因图表主题与系统风格不统一而反复调整样式?
TinyVue 的 TinyGrid (表格)、TinyForm (表单)和 TinyChart(图表)正是为这些痛点而生。它们不仅提供了开箱即用的强大功能,更在细节上考虑到了企业级场景的各种复杂需求。
本篇文章将从以下几个方面展开:
- TinyGrid 企业级表格组件深度实战(虚拟滚动、树形表格、拖拽排序、列配置等)
- TinyForm 复杂表单场景解决方案(动态表单项、校验、联动、配置式表单)
- TinyChart 数据可视化图表应用(图表类型、主题适配、响应式)
一、TinyGrid------企业级表格组件深度实战
TinyGrid 是 TinyVue 中功能最强大的组件之一,它基于原生 Table 实现,但封装了大量企业级特性。下面我们从基础到进阶,逐一解锁。
1.1 基础表格配置与列定义
一个标准的表格通常需要配置数据源、列定义、操作列等。
vue
<template>
<tiny-grid :data="tableData" :height="500">
<tiny-grid-column type="selection" width="50"></tiny-grid-column>
<tiny-grid-column field="name" title="姓名" sortable></tiny-grid-column>
<tiny-grid-column field="age" title="年龄" width="100"></tiny-grid-column>
<tiny-grid-column field="address" title="地址" show-overflow></tiny-grid-column>
<tiny-grid-column field="createTime" title="创建时间" :formatter="dateFormatter"></tiny-grid-column>
<tiny-grid-column title="操作" width="150">
<template #default="{ row }">
<tiny-button type="text" @click="editRow(row)">编辑</tiny-button>
<tiny-button type="text" @click="deleteRow(row)">删除</tiny-button>
</template>
</tiny-grid-column>
</tiny-grid>
</template>
<script setup>
import { ref } from 'vue'
import { TinyGrid, TinyGridColumn } from '@opentiny/vue'
const tableData = ref([...]) // 数据源
const dateFormatter = ({ cellValue }) => {
return new Date(cellValue).toLocaleDateString()
}
</script>
关键属性说明:
sortable:开启列排序show-overflow:内容超出时显示省略号并 hover 显示完整内容formatter:自定义单元格格式化函数
1.2 虚拟滚动------10 万条数据渲染不卡顿
当表格数据量很大时(例如 10 万行),直接渲染所有 DOM 节点会导致页面卡顿甚至崩溃。TinyGrid 内置了 虚拟滚动 机制,只渲染可视区域内的行,滚动时动态更新。
启用虚拟滚动:
vue
<tiny-grid :data="bigData" :height="400" virtual-scroll>
<!-- 列定义 -->
</tiny-grid>
仅需添加 virtual-scroll 属性,即可轻松支持大数据量。实测 10 万行数据,滚动依然丝滑流畅。
💡 资深提示 :启用虚拟滚动时,需要给表格设置固定高度(通过
height属性),否则无法计算可视区域。
1.3 行内编辑、多级表头、树形表格
行内编辑 :通过 edit-config 配置开启行内编辑,支持输入框、选择器等编辑器。
vue
<tiny-grid :data="tableData" :edit-config="{ trigger: 'click', mode: 'row' }">
<tiny-grid-column field="name" title="姓名" :edit-render="{ name: 'input' }"></tiny-grid-column>
<tiny-grid-column field="gender" title="性别" :edit-render="{ name: 'select', options: genderOptions }"></tiny-grid-column>
</tiny-grid>
多级表头 :通过嵌套 <tiny-grid-column> 实现。
vue
<tiny-grid-column title="个人信息">
<tiny-grid-column field="name" title="姓名"></tiny-grid-column>
<tiny-grid-column field="age" title="年龄"></tiny-grid-column>
</tiny-grid-column>
树形表格 :适用于展示层级数据(如组织架构、目录树)。只需设置 tree-config 并指定 children 字段。
vue
<tiny-grid :data="treeData" :tree-config="{ children: 'children' }">
<!-- 列定义 -->
</tiny-grid>
1.4 表格拖拽排序(基于 SortableJS)
TinyGrid 集成了 SortableJS,可以轻松实现行拖拽排序。
vue
<tiny-grid :data="tableData" row-draggable @row-dragend="handleDragEnd">
</tiny-grid>
javascript
const handleDragEnd = ({ newIndex, oldIndex }) => {
const draggedItem = tableData.value.splice(oldIndex, 1)[0]
tableData.value.splice(newIndex, 0, draggedItem)
// 可调用接口保存新的排序顺序
}
1.5 列拖拽调整、列显隐控制
列拖拽调整宽度 :用户可通过拖动列边界调整列宽,表格会自动记忆(需配合 resizable 属性)。
vue
<tiny-grid :data="tableData" resizable>
列显隐控制 :通过配置列的 visible 属性,结合 UI 控制哪些列显示。
vue
<template>
<tiny-checkbox-group v-model="visibleColumns">
<tiny-checkbox label="name">姓名</tiny-checkbox>
<tiny-checkbox label="age">年龄</tiny-checkbox>
</tiny-checkbox-group>
<tiny-grid :data="tableData">
<tiny-grid-column field="name" title="姓名" :visible="visibleColumns.includes('name')"></tiny-grid-column>
<tiny-grid-column field="age" title="年龄" :visible="visibleColumns.includes('age')"></tiny-grid-column>
</tiny-grid>
</template>
二、TinyForm------复杂表单场景解决方案
表单是数据录入的核心,TinyForm 提供了校验、动态表单项、联动、布局等企业级能力。
2.1 表单校验规则配置与自定义校验器
TinyForm 内置了丰富的校验规则(required、email、url、min、max 等),也支持自定义校验函数。
vue
<template>
<tiny-form :model="formData" :rules="rules" ref="formRef">
<tiny-form-item label="用户名" prop="username">
<tiny-input v-model="formData.username"></tiny-input>
</tiny-form-item>
<tiny-form-item label="邮箱" prop="email">
<tiny-input v-model="formData.email"></tiny-input>
</tiny-form-item>
<tiny-button type="primary" @click="submit">提交</tiny-button>
</tiny-form>
</template>
<script setup>
import { ref, reactive } from 'vue'
const formData = reactive({
username: '',
email: ''
})
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
]
}
const formRef = ref()
const submit = async () => {
await formRef.value.validate()
// 校验通过,提交数据
}
</script>
自定义校验器:
javascript
const rules = {
phone: [
{ validator: (rule, value, callback) => {
if (!/^1[3-9]\d{9}$/.test(value)) {
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
}, trigger: 'blur' }
]
}
2.2 动态表单项与条件渲染
在实际业务中,表单的字段可能根据用户选择动态增减。TinyForm 配合 Vue 的响应式系统可以轻松实现。
vue
<template>
<tiny-form :model="formData">
<tiny-form-item label="类型" prop="type">
<tiny-radio-group v-model="formData.type">
<tiny-radio label="A">类型A</tiny-radio>
<tiny-radio label="B">类型B</tiny-radio>
</tiny-radio-group>
</tiny-form-item>
<!-- 类型A 才显示的字段 -->
<tiny-form-item v-if="formData.type === 'A'" label="A字段" prop="aField">
<tiny-input v-model="formData.aField"></tiny-input>
</tiny-form-item>
<!-- 类型B 才显示的字段 -->
<tiny-form-item v-if="formData.type === 'B'" label="B字段" prop="bField">
<tiny-input v-model="formData.bField"></tiny-input>
</tiny-form-item>
</tiny-form>
</template>
2.3 表单联动与数据回填
表单项之间的联动(如省市区三级联动)可以通过监听值变化实现。
vue
<template>
<tiny-form :model="formData">
<tiny-form-item label="省份" prop="province">
<tiny-select v-model="formData.province" @change="onProvinceChange">
<tiny-option v-for="p in provinces" :key="p.code" :label="p.name" :value="p.code"></tiny-option>
</tiny-select>
</tiny-form-item>
<tiny-form-item label="城市" prop="city">
<tiny-select v-model="formData.city" :disabled="!formData.province">
<tiny-option v-for="c in cities" :key="c.code" :label="c.name" :value="c.code"></tiny-option>
</tiny-select>
</tiny-form-item>
</tiny-form>
</template>
<script setup>
import { ref, reactive } from 'vue'
const formData = reactive({ province: '', city: '' })
const provinces = ref([])
const cities = ref([])
const onProvinceChange = async (provinceCode) => {
// 请求城市列表
cities.value = await fetchCities(provinceCode)
formData.city = ''
}
</script>
2.4 配置式表单------支持低代码平台可视化配置
TinyForm 支持通过 JSON 配置生成表单,这在低代码平台中非常有用。你可以定义字段列表,然后动态渲染。
vue
<template>
<tiny-form :model="formData">
<tiny-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop">
<component
:is="getComponent(field.type)"
v-model="formData[field.prop]"
v-bind="field.props"
/>
</tiny-form-item>
</tiny-form>
</template>
<script setup>
import { TinyInput, TinySelect, TinyDatePicker } from '@opentiny/vue'
const formFields = [
{ type: 'input', label: '用户名', prop: 'username', props: { placeholder: '请输入用户名' } },
{ type: 'select', label: '性别', prop: 'gender', props: { options: [{ label: '男', value: 1 }, { label: '女', value: 2 }] } },
{ type: 'date', label: '生日', prop: 'birthday' }
]
const getComponent = (type) => {
const map = { input: TinyInput, select: TinySelect, date: TinyDatePicker }
return map[type]
}
</script>
三、TinyChart------数据可视化图表应用
TinyChart 是基于 ECharts 封装的 Vue 组件,继承了 ECharts 的全部能力,同时提供了响应式、主题适配等增强功能。
3.1 基于 ECharts 的图表组件封装
安装依赖:
bash
npm install @opentiny/vue-charts
基础用法:
vue
<template>
<tiny-chart :options="chartOptions" height="400px" />
</template>
<script setup>
import { TinyChart } from '@opentiny/vue-charts'
const chartOptions = {
title: { text: '销售趋势' },
xAxis: { type: 'category', data: ['1月', '2月', '3月', '4月'] },
yAxis: { type: 'value' },
series: [{ type: 'line', data: [120, 200, 150, 80] }]
}
</script>
3.2 常用图表类型:折线图、柱状图、饼图、漏斗图
TinyChart 支持 ECharts 所有图表类型,通过 options.series.type 指定。
柱状图:
javascript
const barOptions = {
xAxis: { type: 'category', data: ['苹果', '华为', '小米'] },
yAxis: { type: 'value' },
series: [{ type: 'bar', data: [320, 280, 190] }]
}
饼图:
javascript
const pieOptions = {
series: [{ type: 'pie', data: [{ name: 'A', value: 30 }, { name: 'B', value: 50 }, { name: 'C', value: 20 }] }]
}
漏斗图(适用于销售转化场景):
javascript
const funnelOptions = {
series: [{ type: 'funnel', data: [{ name: '访问', value: 1000 }, { name: '咨询', value: 300 }, { name: '订单', value: 80 }] }]
}
3.3 图表主题适配与响应式调整
TinyChart 可以自动跟随 OpenTiny 的主题系统(亮色/暗色),无需额外配置。同时,图表容器尺寸变化时(如窗口缩放),图表会自动调用 resize 方法。
手动控制主题:
vue
<tiny-chart :options="options" theme="dark" />
响应式监听 :如果图表所在容器大小不是由窗口变化引起(例如折叠面板展开),可以手动调用 resize:
vue
<template>
<tiny-chart ref="chartRef" :options="options" />
</template>
<script setup>
import { ref } from 'vue'
const chartRef = ref()
const handleResize = () => {
chartRef.value?.resize()
}
// 在折叠面板展开等时机调用 handleResize
</script>
3.4 高阶图表:HUICharts 图表库的应用
OpenTiny 还提供了更专业的数据可视化组件库 HUICharts(商业版),包含丰富的业务图表(如仪表盘、地图、关系图等)。如果基础 TinyChart 无法满足需求,可以考虑 HUICharts。
四、实战:构建一个带图表的数据仪表盘
综合以上知识点,我们来实现一个简单的销售数据仪表盘,包含:
- 顶部 KPI 卡片
- 中间销售趋势折线图
- 底部产品销量柱状图 + 表格
vue
<template>
<div class="dashboard">
<!-- KPI 卡片 -->
<div class="kpi-row">
<tiny-card class="kpi-card">
<div class="kpi-title">总销售额</div>
<div class="kpi-value">¥{{ totalSales.toLocaleString() }}</div>
</tiny-card>
<tiny-card class="kpi-card">
<div class="kpi-title">订单数</div>
<div class="kpi-value">{{ totalOrders }}</div>
</tiny-card>
<tiny-card class="kpi-card">
<div class="kpi-title">转化率</div>
<div class="kpi-value">{{ conversionRate }}%</div>
</tiny-card>
</div>
<!-- 趋势图 -->
<tiny-card title="月度销售趋势">
<tiny-chart :options="trendOptions" height="300px" />
</tiny-card>
<!-- 产品销量榜 -->
<tiny-card title="产品销量榜">
<tiny-grid :data="productRanking" height="300">
<tiny-grid-column field="name" title="产品名称"></tiny-grid-column>
<tiny-grid-column field="sales" title="销量" sortable></tiny-grid-column>
<tiny-grid-column field="revenue" title="销售额" sortable>
<template #default="{ row }">¥{{ row.revenue.toLocaleString() }}</template>
</tiny-grid-column>
</tiny-grid>
</tiny-card>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { TinyCard, TinyGrid, TinyGridColumn, TinyChart } from '@opentiny/vue'
// 模拟数据
const totalSales = ref(1258000)
const totalOrders = ref(3245)
const conversionRate = computed(() => ((totalOrders.value / 50000) * 100).toFixed(2))
const trendOptions = {
xAxis: { type: 'category', data: ['1月', '2月', '3月', '4月', '5月', '6月'] },
yAxis: { type: 'value', name: '销售额(万)' },
series: [{ type: 'line', data: [120, 200, 150, 180, 220, 280], smooth: true }]
}
const productRanking = ref([
{ name: '智能手机', sales: 890, revenue: 3560000 },
{ name: '笔记本电脑', sales: 520, revenue: 4160000 },
{ name: '平板电脑', sales: 410, revenue: 1435000 }
])
</script>
<style scoped>
.dashboard { padding: 20px; }
.kpi-row { display: flex; gap: 20px; margin-bottom: 20px; }
.kpi-card { flex: 1; text-align: center; }
.kpi-title { font-size: 14px; color: #666; }
.kpi-value { font-size: 28px; font-weight: bold; margin-top: 8px; }
</style>
总结
本篇我们深入学习了 TinyVue 中三大核心数据组件的企业级应用:
-
TinyGrid 表格:
- 基础配置、列定义、排序、格式化
- 虚拟滚动支持 10 万+ 数据
- 行内编辑、多级表头、树形表格
- 拖拽排序、列宽调整、列显隐控制
-
TinyForm 表单:
- 内置校验与自定义校验
- 动态表单项与条件渲染
- 表单联动与数据回填
- 配置式表单(JSON 驱动)
-
TinyChart 图表:
- 基于 ECharts 的封装,支持常用图表类型
- 主题适配与响应式调整
- 实战构建数据仪表盘
掌握这些组件的高级用法,你就能应对企业级应用中 90% 的数据处理场景,大幅提升开发效率和用户体验。
下篇预告: 《智能篇------OpenTiny NEXT 智能化能力深度解析》将带你探索 OpenTiny NEXT 最核心的 AI 能力:生成式 UI、WebMCP 协议、NEXT-SDKs 以及 WebAgent 实战,开启前端智能开发的新篇章,敬请期待!
如果觉得本文对你有帮助,欢迎点赞、收藏、评论,你的支持是我持续创作的动力!