Vue 3 + Vite 中使用 F2 绘制移动端图表:从工程配置到自定义视图的完整指南

原创2026-09-25 16:57:101,099 阅读
文章标签:数据可视化前端

Vue 3 + Vite 中使用 F2 绘制移动端图表:从工程配置到自定义视图的完整指南

F2 是面向移动端的优雅、交互式、灵活的图表库。本文以仓库 packages/f2-vue/examples/vite 下的 Vue 3 + Vite 示例工程为主线,完整讲解如何在 Vue 3 项目中接入 F2:包括依赖安装、Vite 的 JSX 编译配置、用 <Canvas>/<Chart> 声明式组件搭建柱状图、编写自定义图形视图,以及通过 Vue 响应式数据驱动图表更新。读完本文,你可以在自己的 Vue 3 + Vite 工程中直接复刻这套可运行的图表方案。

该示例目录沿用了 Vue 3 + Vite 的标准模板结构(源码见 examples/vite),在其之上加入了 F2 图表的完整集成代码,是官方仓库中最直接的 Vue 集成样板。

示例工程目录结构

packages/f2-vue/examples/vite/
├── index.html          # 页面入口,挂载 #app
├── package.json        # 依赖与 npm 脚本
├── vite.config.js      # Vite 插件与 JSX 编译配置
└── src/
    ├── App.vue         # 根组件:声明式图表
    ├── graphic.jsx     # 自定义视图组件(绘制年份文字)
    └── main.js         # Vue 应用入口

其中核心的图表渲染逻辑全部集中在 App.vue 的 <script lang='jsx'> 中,而 graphic.jsx 则演示了如何在图表坐标系内插入自定义绘制内容。

依赖清单与安装

参考 package.json,该示例工程的核心依赖如下:

依赖 版本 作用
@antv/f2 ^5.0.0 移动端图表核心库,提供 Chart、Interval、Axis 等组件
@antv/f-engine 1.x 渲染引擎,同时也是 JSX 转换后的 importSource
@antv/f-vue 1.x F2 的 Vue 封装组件(即 <Canvas> 的出处)
vue ^3.2.25 Vue 3 运行时

开发依赖则用于解决 JSX 编译与 Vue 插件集成:

开发依赖 版本
@babel/plugin-transform-react-jsx ^7.17.3
@rollup/plugin-babel ^5.3.1
@vitejs/plugin-vue ^2.3.2
@vitejs/plugin-vue-jsx ^1.3.10
vite ^2.9.7

npm 脚本与标准 Vite 工程一致:dev 启动开发服务器、build 产出构建结果、preview 预览构建产物。

注意:示例中直接写入了具体依赖版本号(Vite 为 ^2.9.7、Vue 为 ^3.2.25),在实际新项目中可结合自身版本策略安装最新兼容版本,本示例的版本约束可作参考。

关键一步:配置 JSX 编译

F2 的声明式语法基于 JSX,因此 Vue 3 + Vite 下接入 F2 的第一道门槛是让 Vite 能正确编译图表中的 JSX 标签。示例的 vite.config.js 给出了完整答案:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { babel } from '@rollup/plugin-babel';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    babel({
      plugins: [
        [
          '@babel/plugin-transform-react-jsx',
          {
            runtime: 'automatic',
            importSource: '@antv/f-engine',
          },
        ],
      ],
    }),
    vue(),
    vueJsx(),
  ],
});

这里有三个要点需要理解:

  1. @babel/plugin-transform-react-jsx 负责转换图表 JSX:F2 图表语法中的 <Canvas>、<Chart>、<group>、<text> 等标签,本质上是渲染引擎的图元描述,必须被 Babel 插件转换为引擎调用。
  2. runtime: 'automatic' 与 importSource: '@antv/f-engine' 决定 JSX 的运行时来源:自动运行时模式下,JSX 会被转换为从 importSource 指定模块导入的 jsx 函数调用,此处指定为渲染引擎 @antv/f-engine,从而让图元标签正确落地到画布。作为对照,仓库官方文档 如何在 Vue 中使用 中展示的 Vite 配置同样采用这套写法,只是将 importSource 指向 @antv/f2——两种写法分别对应图表标签与渲染引擎两种转换目标,需与你的依赖引入方式保持一致。
  3. vue() 与 vueJsx() 负责常规 Vue 组件编译:App.vue 内部使用 render() + JSX 的写法,需要 @vitejs/plugin-vue-jsx 支持。

如果你使用的是 vue-cli / webpack 工程,仓库文档也给出了等价方案:在 vue.config.js 中用 chainWebpack 为 .jsx 规则追加 Babel loader,并配置同样的 JSX 插件与 importSource(详见 site/docs/tutorial/framework/vue.zh.md)。

声明式绘制柱状图:App.vue 逐段解析

示例根组件 App.vue 完整演示了从数据到图表的声明式映射,核心代码骨架如下:

<script lang='jsx'>
import { toRaw } from 'vue';
import Canvas from '@antv/f-vue';
import { Chart, Interval, Axis } from '@antv/f2';
import Grahpic from './graphic';

const data1 = [
  { genre: 'Sports', sold: 275 },
  { genre: 'Strategy', sold: 115 },
  { genre: 'Action', sold: 120 },
  { genre: 'Shooter', sold: 350 },
  { genre: 'Other', sold: 150 },
];

const data2 = [
  { genre: 'Sports', sold: 275 },
  { genre: 'Strategy', sold: 115 },
  { genre: 'Action', sold: 20 },
  { genre: 'Shooter', sold: 50 },
  { genre: 'Other', sold: 50 },
];

export default {
  name: 'App',
  data() {
    return {
      year: '2021',
      chartData: data1,
    };
  },
  mounted() {
    setTimeout(() => {
      this.year = '2022';
      this.chartData = data2;
    }, 1000);
  },
  render() {
    const { year, chartData } = this;
    return (
      <div className="container">
        <Canvas pixelRatio={window.devicePixelRatio}>
          <Chart data={toRaw(chartData)}>
            <Grahpic year={year} />
            <Axis field="genre" />
            <Axis field="sold" />
            <Interval x="genre" y="sold" color="genre" />
          </Chart>
        </Canvas>
      </div>
    );
  },
};
</script>

<style>
.container {
  width: 500px;
  height: 300px;
}
</style>

几个值得注意的工程细节:

  • <script lang='jsx'>:该示例直接在 .vue 单文件组件中使用 JSX 语法,这是 @vitejs/plugin-vue-jsx 支持的用法。
  • Canvas 来自 @antv/f-vue:<Canvas pixelRatio={window.devicePixelRatio}> 是画布容器,通过 pixelRatio 适配移动端的高清屏(Retina/HiDPI 场景)显示精度。
  • Chart、Axis、Interval 来自 @antv/f2:<Chart data={...}> 接收数据源;<Axis field="genre" />、<Axis field="sold" /> 声明 x 轴与 y 轴;<Interval x="genre" y="sold" color="genre" /> 声明柱形几何体,并依据 genre 字段着色,形成按类目分组的多色柱状图。
  • toRaw(chartData):这是 Vue 3 响应式系统与图表库衔接的关键。chartData 是 Vue 的响应式数据(被 Proxy 包裹),直接传给图表库可能带来 Proxy 兼容性问题,用 toRaw 取出原始对象后再交给 Chart,可以避免不必要的响应式开销与副作用。

样式方面,.container 通过固定宽高(500px × 300px)确定画布尺寸,这是 Canvas 类图表渲染的常见做法。

自定义视图组件:graphic.jsx

除了标准图表组件,F2 允许在坐标系内插入自定义绘制内容。示例的 graphic.jsx 演示了如何写一个自定义视图:

function View(props) {
  const { coord, year } = props;
  const { left, top, width, height } = coord;
  const x = left + width / 2;
  const y = top + height / 2;
  return (
    <group>
      <text
        attrs={{
          x,
          y,
          text: year,
          textAlign: 'center',
          fontSize: '80px',
          fill: '#ddd',
        }}
      />
    </group>
  );
}

export default View;

其工作原理是:组件收到 coord(当前坐标系实例)与外部传入的 year 属性,从 coord 上解构出 left、top、width、height,从而计算出坐标系中心点 (x, y),然后在 <group> 下绘制一个居中的大号文字。在 App.vue 中它被当作普通子组件使用:<Grahpic year={year} />,让图表中央始终显示当前年份,起到类似“图内标注”的效果。

这一模式说明:F2 的 JSX 语法是完整的可组合渲染模型,<group>、<text> 等图元标签可以直接在自定义组件中使用,实现图表与业务定制内容的深度混合。

数据驱动更新:响应式让图表“活”起来

App.vue 的 mounted() 钩子里,组件挂载 1 秒后修改了 year 与 chartData:

mounted() {
  setTimeout(() => {
    this.year = '2022';
    this.chartData = data2;
  }, 1000);
}

由于 year、chartData 声明在 Vue 组件的 data() 中,变更会触发 render() 重新执行:图表中央年份从 2021 变为 2022,柱状图数据从 data1 切换到 data2(其中 Action 类目的销量从 120 变为 20、Shooter 从 350 变为 50,其余类目保持或变化,便于直观观察差异)。这验证了 F2 的 Vue 集成具备完整的响应式更新链路——只需修改 Vue 数据,图表即可自动重绘,无需手动调用任何更新 API。

工程入口:main.js 与 index.html

其余两个入口文件保持了标准 Vue 3 应用的形态:

  • main.js:createApp(App).mount('#app'),无特殊改动;
  • index.html:标准 #app 挂载点,通过 <script type="module" src="/src/main.js"> 加载模块入口,并配置了移动端 viewport。

快速运行示例

在仓库根目录下,切换到示例目录安装依赖并启动:

cd packages/f2-vue/examples/vite
npm install
npm run dev        # 启动 Vite 开发服务器
npm run build      # 生产构建
npm run preview    # 预览构建产物

开发模式下修改 App.vue 或 graphic.jsx 会触发热更新,可即时验证图表效果。

小结

通过 packages/f2-vue/examples/vite 这份示例,我们掌握了在 Vue 3 + Vite 中集成 F2 的完整链路:Babel 插件 + importSource 配置解决 JSX 编译 → <Canvas>/<Chart>/<Axis>/<Interval> 声明式拼装图表 → graphic.jsx 自定义视图扩展绘制 → toRaw 与 Vue 响应式数据协同实现图表热更新。这套模板同样适用于 Vue 3 + vue-cli(webpack)工程,只需将 JSX 编译配置迁移到 vue.config.js 的 chainWebpack 即可,具体参考 site/docs/tutorial/framework/vue.zh.md。如果你还想对比 webpack 体系的 Vue 3 示例,仓库中还有一份对应的 examples/vue3 工程可供参考。

登录后查看全文
F2