OpenTiny NEXT 从入门到精通·第 3 篇

OpenTiny NEXT 从入门到精通·第 3 篇:数据篇------表格、表单与图表的高级应用

企业级中后台系统,80% 的页面都是"增删改查"的数据处理场景。表格承载着海量数据的展示与操作,表单负责复杂业务信息的录入与校验,图表则将枯燥的报表转化为直观的洞察。TinyVue 的表格、表单和图表组件,不仅功能完备,更在性能优化、复杂交互、配置化等方面提供了企业级能力。本篇将带你深入这些核心数据组件的进阶用法,让你的数据处理如虎添翼。

你是否曾因表格加载万条数据就卡顿而头疼?是否因表单联动的层层回调写得像"面条代码"而苦恼?是否因图表主题与系统风格不统一而反复调整样式?

TinyVue 的 TinyGrid (表格)、TinyForm (表单)和 TinyChart(图表)正是为这些痛点而生。它们不仅提供了开箱即用的强大功能,更在细节上考虑到了企业级场景的各种复杂需求。

本篇文章将从以下几个方面展开:

  1. TinyGrid 企业级表格组件深度实战(虚拟滚动、树形表格、拖拽排序、列配置等)
  2. TinyForm 复杂表单场景解决方案(动态表单项、校验、联动、配置式表单)
  3. 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 中三大核心数据组件的企业级应用:

  1. TinyGrid 表格

    • 基础配置、列定义、排序、格式化
    • 虚拟滚动支持 10 万+ 数据
    • 行内编辑、多级表头、树形表格
    • 拖拽排序、列宽调整、列显隐控制
  2. TinyForm 表单

    • 内置校验与自定义校验
    • 动态表单项与条件渲染
    • 表单联动与数据回填
    • 配置式表单(JSON 驱动)
  3. TinyChart 图表

    • 基于 ECharts 的封装,支持常用图表类型
    • 主题适配与响应式调整
    • 实战构建数据仪表盘

掌握这些组件的高级用法,你就能应对企业级应用中 90% 的数据处理场景,大幅提升开发效率和用户体验。

下篇预告: 《智能篇------OpenTiny NEXT 智能化能力深度解析》将带你探索 OpenTiny NEXT 最核心的 AI 能力:生成式 UI、WebMCP 协议、NEXT-SDKs 以及 WebAgent 实战,开启前端智能开发的新篇章,敬请期待!

如果觉得本文对你有帮助,欢迎点赞、收藏、评论,你的支持是我持续创作的动力!

相关推荐
lly2024062 小时前
Node.js 文件系统
开发语言
asyxchenchong8882 小时前
农业系统模拟APSIM全流程详解(气象/土壤/碳氮平衡/NG版本)附R批量处理代码
开发语言·r语言
跟着珅聪学java2 小时前
在 Java 中处理 JSON 去除空 children数组,可以使用 Jackson 库。这里有几种实现方式
开发语言·windows·python
计算机安禾2 小时前
【数据结构与算法】第33篇:交换排序(二):快速排序
c语言·开发语言·数据结构·数据库·算法·矩阵·排序算法
William Dawson2 小时前
Java 后端高频 20 题超详细解析 ①
java·开发语言
lly2024062 小时前
PHP 魔术常量
开发语言
Evand J2 小时前
【MATLAB例程分享】三维非线性目标跟踪,观测为:距离+方位角+俯仰角,使用无迹卡尔曼滤波(UKF)与RTS平滑,高精度定位
开发语言·matlab·目标跟踪
编程之升级打怪2 小时前
Java NIO的简单封装
java·开发语言·nio
Chase_______2 小时前
【Python基础 | 第5章】面向对象与异常处理:一文搞懂类、对象、封装、继承、多态
开发语言·python