Taro-支付宝小程序使用Antv/F2

Taro - 支付宝小程序

使用Antv/F2

前言

一开始我就有一个困惑,我用taro vue3去写支付宝小程序,那我究竟是看如何在Vue中使用还是如何在小程序中使用的文档呢❓

随即我开始了踩坑之旅,通过实践发现F2的vue版本是针对web端的,因此当我在小程序跑起来的时候直接报了一个node.parentNode获取不到的错误

上面说的是4.x版本。但从一开始我并没有直接用4.x,因为4.x开始,F2都是以jsx的方式去使用组件;我在vue3使用script setup去编写代码,所以暂时无法编写jsx。还有一个很重要的是旧项目(微信小程序)那边的F2用的是3.x

这两个版本在使用方式上改变还是挺大的,3.x用起来没有那么的挑;也正如所愿,我成功的跑起了示例,不曾想用安卓机一看,人都麻了,出现了以下的情况

  • 图表有时候满屏(我设置的宽度100%),有时候又变成了4分之一小
  • 使用v-if控制,有概率渲染不了,canvas节点在,就是没有渲染,使用v-show直接就不渲染了

上诉情况没有任何的报错,无从解决;因此我只能转向4.x继续踩坑

p.s. IOS啥毛病都没有,动画还贼丝滑

支付宝小程序接入Antv/F2 4.x版本

正式开始

1. 安装 F2 依赖

bash 复制代码
 # 安装 F2 依赖
 npm i @antv/f2 --save
 ​
 # 安装f2-context
 npm i @antv/f2-context --save

2. 配置 jsx transform

如果项目已有 jsx 编译,可忽略此步骤

bash 复制代码
 npm i @babel/plugin-transform-react-jsx -D

config/index.js增加配置

js 复制代码
 mini: {
   webpackChain(chain) {
     chain
       .merge({
       module: {
         rule: {
           F2: {
             test: /.jsx$/,
             use: {
               babelLoader: {
                 loader: require.resolve('babel-loader'),
                 options: {
                   plugins: [
                     [
                       '@babel/plugin-transform-react-jsx',
                       {
                         runtime: 'automatic',
                         importSource: '@antv/f2',
                       },
                     ],
                   ],
                 },
               },
             },
           },
         },
       },
     })
   }
 }

3.下载f2-my的源码

点击上面的地址把src文件夹的内容下载到本地,假设放到了项目的 /src/components/F2Chart下面将以这个路径举例

这也是为什么我在第一步的时候没有说安装@antv/f2-my,这里有两个坑,我们需要改一下源码

位置: /src/components/F2Chart/index.js

  • 文档得知,我们等下在使用组件的时候需要传递onRender这个props,但是在实践过程中,通过这个props名称我无法把我们自己的函数传递过去,我尝试新加一个props,从而解决了问题

    js 复制代码
     Component({
       props: {
         onRender: function onRender(_props) {},
         // 上面的onrender无法执行到,因此写了一个新的自定义prop
         render: function onRender(_props) {},
         // width height 会作为元素兜底的宽高使用
         width: null,
         height: null,
         type: '2d', // canvas 2d, 基础库 2.7 以上支持
       },
     })

    首先在props选项中增加了render,接着把原来调用props.onRender的地方改为props.render;

    分别是在didUpdatecanvasRender这两个地方

  • 还有就是他的click函数,从源码可以看到是点击canvas时触发的,但是一点击控制台就收到一个报错,说事件的Eventdetailundefined,我打印了整个Event对象,确实如此,连同源码中的target.offsetLeft也是没有的,我怀疑这部分是复制了web的过来然后没改;因此我的click函数改成了如下,我暂时用不到

    js 复制代码
     click: function click(e) {
       // 支付宝的点击event对象没有detail,这里只能改造一下不执行了
       var canvasEl = this.canvasEl;
       if (!canvasEl) {
         return;
       }
       var event = wrapEvent(e);
       canvasEl.dispatchEvent('click', event);
     }

    补充一下:在真机上有源码需要的e.detail.x,但是e.target.offsetLeft还是没有

4.编写我们的业务代码

下面举例写一个官方的上手例子

和官方一样,先写一个Chart.jsx

jsx 复制代码
 import { Chart, Interval, Axis } from '@antv/f2';
 ​
 export default (props) => {
   const { data } = props;
   return (
     <Chart data={data}>
       <Axis field="genre" />
       <Axis field="sold" />
       <Interval x="genre" y="sold" color="genre" />
     </Chart>
   );
 };
 ​

接着我们写一个taro的vue页面,F2.vue

vue 复制代码
 <template>
   <view>
     <button @click="show = !show">change</button>
     <view class="container" v-show="show">
       <gh-canvas :render="onRenderChart"></gh-canvas>
     </view>
   </view>
 </template>
 ​
 <script lang="tsx">
   import { reactive, toRefs } from 'vue';
   import Chart from './Chart';
   import { createElement } from '@antv/f2';
 ​
   definePageConfig({
     usingComponents: {
       'gh-canvas': '../../components/F2Chart',
     },
   });
 ​
   export default {
     setup() {
       const state = reactive({
         show: true,
       });
       const data = [
         { genre: 'Sports', sold: 275 },
         { genre: 'Strategy', sold: 115 },
         { genre: 'Action', sold: 120 },
         { genre: 'Shooter', sold: 350 },
         { genre: 'Other', sold: 150 },
       ];
       function onRenderChart() {
         return createElement(Chart, {
           data: data,
         });
       }
       return {
         ...toRefs(state),
         onRenderChart,
       };
     },
   };
 </script>
 ​
 <style lang="scss">
   .container {
     width: 100%;
     height: 600px;
   }
 </style>
 ​

这里有个注意点,在页面先注册一下我们下载到本地的antv/F2组件;这个时候如果你直接跑起来你会收到一个警告,虽然是个警告,但是你的代码是不行的。

[Vue warn]: Failed to resolve component: gh-canvas If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

这个提示很明显了,我们自己取的这个组件名,gh-canvas,在构建的时候把他当做vue组件去解析了;解决办法就是配置一下vue-loader让他跳过我们的组件

但是吧,又不能在webpackchain中直接配置覆盖,于是我一顿找,终于找到了一个老哥的贡献

github.com/NervJS/taro...

接下来就简单了,让我们再次来到config/index.js增加以下配置

js 复制代码
 plugins: [
   // 你的其他插件
   // https://github.com/NervJS/taro/pull/11694
   [
     '@tarojs/plugin-framework-vue3',
     {
       vueLoaderOption: {
         compilerOptions: {
           isCustomElement: (tag) => tag.startsWith('gh-'),
         },
       },
     },
   ],
 ],

这个组件名前缀你喜欢改什么就改什么,记得在vue的template的引用同步更改就行

重新运行pnpm dev:alipay,大功告成~🎉 4.x版本在安卓上已经没有上面提到的两个问题了

总结

这里踩坑主要还是配置问题,因为我不熟悉webpackwebpackchain因此废了很大劲。还有找资料还是优先到github查找一下有没有类似的issue或者贡献,什么chatGPT没啥用,不停的说谎给出错误答案

相关推荐
白兰地空瓶11 小时前
🚀 10 分钟吃透 CSS position 定位!从底层原理到避坑实战,搞定所有布局难题
前端·css
onthewaying11 小时前
在Android平台上使用Three.js优雅的加载3D模型
android·前端·three.js
冴羽11 小时前
能让 GitHub 删除泄露的苹果源码还有 8000 多个相关仓库的 DMCA 是什么?
前端·javascript·react.js
悟能不能悟11 小时前
jsp怎么拿到url参数
java·前端·javascript
程序猿小蒜12 小时前
基于SpringBoot的企业资产管理系统开发与设计
java·前端·spring boot·后端·spring
Mapmost12 小时前
零代码+三维仿真!实现自然灾害的可视化模拟与精准预警
前端
程序猿_极客12 小时前
JavaScript 的 Web APIs 入门到实战全总结(day7):从数据处理到交互落地的全链路实战(附实战案例代码)
开发语言·前端·javascript·交互·web apis 入门到实战
suzumiyahr12 小时前
用awesome-digital-human-live2d创建属于自己的数字人
前端·人工智能·后端
萧曵 丶12 小时前
Python 字符串、列表、元组、字典、集合常用函数
开发语言·前端·python
申阳12 小时前
Day 10:08. 基于Nuxt开发博客项目-关于我页面开发
前端·后端·程序员