具体项目下解决Echarts多端同步开发和维护的问题

2023-09-18 10:33:47

具体问题场景

        PC端和移动端需要同时上线图表功能(没有多余工时)

        之后的版本迭代(功能、样式、配置等)默认双端同步,开发人员只希望维护一套代码

        Echarts在移动端有部分功能不兼容不支持

         

Echarts在移动端的坑

        ① 移动端页面使用echarts4 中的地图组件,并添加省份的点击事件,响应click无效,eharts也不支持tap事件。

        解决方法:自己代理echarts组件实例的click事件。或更新到echarts5版本

        ②地图组件有数据的省份高亮状态点击后消失。

        解决方法:劫持点击事件做判断

        ③dataZoom失效

dataZoom:{
  type: 'inside',
  start: 0,
  end: 50,
},

        解决方法:把传入的对象参数改成数组

dataZoom:[
   {
      type: 'inside',
      start: 0,
      end: 50,
    }
],

        ④ 图表组件的datazoom会阻碍页面的原生滑动事件,导致页面没办法正确上下滑。

        解决方法:添加preventDefaultMouseMove属性为false

        ⑤datazoom为inside时,多个图表在移动端上滑动失效

        解决方法:更新到最新版本echarts,但是还是会有部分机型存在这个问题

多端合一是比较理想的解决方案

        我们可以看到Echarts在移动端上还是存在很多不兼容的地方。而且Echarts官网时挂着的example都是PC端上的。为了避免各种坑爹问题,我在项目中还是选择了多端为一端的开发方案。

        核心思想就是通过Iframe让移动端的页面直接渲染PC的网页,同时微调一些样式以适配移动端的小屏。

图表部分

        这部分不是重点,因为页面用的还是PC端的页面。只需要调整部分样式大小就好。主要解决一个留存问题就是Iframe里面图表的内部滑动会影响移动端的页面滑动。

<mobileTouchView @touchInfo="updateTouchInfo" :touchRecord="true">
        <...>
          <m-dashboard-runtime-item
            v-for="item in layout"
            :key="item.pkId"
            :layout="item"
            :field="fieldMap[item.pkId]"
          />
        </...>
 </mobileTouchView>

        解决方法是套了个自定义的滑动层,并监听会出问题的几个操作

<!--mobileTouchView-->
<template>
  <div
    :class="$style.mobileTouchView"
    @touchstart="proxyStart"
    @touchmove="proxyMove"
    @touchend="proxyEnd"
    @touchcancel="proxyCancel"
  >
    <slot></slot>
  </div>
</template>

        核心思想是计算touch起点和终点的screenY/screenX的偏离来确定用户手势。具体可以看我的另外一篇推文。

通讯部分  

        代码分为两部分

 移动端部分

        主体

  <view class="dashboard-page">
      ....
      <!-- 内容 -->
      <view class="content" :class="{ showFilter: filterFields.length > 0 }">
        <iframe
          v-if="iframeUrl"
          ref="iframe"
          class="webview"
          :src="iframeUrl"
        ></iframe>
        <!-- 留白组件 -->
        <x-abnormal v-else :text="tips" class="tips" />
      </view>
</view>

        很简单的一个移动端页面中间嵌套了一个iframe页面

        监听加载

async getFormData() { 
    ....
    await this.$nextTick();
    this.$refs.iframe &&
    this.$refs.iframe.addEventListener('load', e => this.handleIframeLoad(e));
}

        发送讯息

        同时监听PC端发过来的讯息

// iframe加载完成
  handleIframeLoad(e) {
    // 先打开对PC讯息的监听器
    window.addEventListener('message', this.messageGateway);
    // 对PC建立握手
    this.handShake(5);
  }

        这里为什么要握手五次?其实这里可以填大一点。因为单方无法知道连接是否成功。 所以每500毫秒重新握手一次,直到收到回复。

        握手

handShake(t = 0) {
    if (this.connected || t < 1) {
      return;
    }
    // console.log('mobile: 开始建立握手');
    this.$refs.iframe.contentWindow.postMessage({ 
        type: 'ping', 
        data: {timeStamp:this.currentTime},
    }, '*');
    setTimeout(() => {
      this.handShake((t -= 1));
    }, 500);
  }

       收到回复后把this.connected改成true就好了

         

 Pc部分

        Iframe通讯

         PC上通过监听message来捕抓移动端发送过来的讯息

  created() {
    window.addEventListener('message', e => this.messageGateway(e));
  }

        这里可以过滤一下域名:

get allowOrigin() {
    return ['localhost:8080', 'm.xxx.com', 'mobile.xxx.com'];
}
  
messageGateway(e) {
    const findIndex = this.allowOrigin.findIndex(item =>
      e.origin.includes(item),
    );
    if (findIndex > -1) {
        ...
    }
  }

用户权限问题

        在移动端打开PC端的Iframe页面,需要传入token来验证登录状态和身份权限。

get iframeUrl() {
    return `${createModuleUrl('app')}/m-dashboard/${this.formId}?token=${
      this.token
    }`;
}

        iframe页面验证token后通过路由跳转到页面

const routes = [
    ...,
    {
        path: '/m-dashboard/:formId',
        component: () => import('@/views/dashboard/mobile')
    },
]

 

更多推荐

GRACE球谐数据滤波处理(利用matlab实现GRACE月水储量的二维傅里叶变化滤波)

GRACE的全球重力场产品以球谐系数(SHCs)的形式表现出明显的南北条带噪声问题,这种噪声被认为来源于它的极轨道、缺乏横向敏感性以及采样频率引起的混叠效应。空间滤波器的例子包括各向同性高斯滤波器(Wahretal.,1998)及其非各向同性变体(Hanetal.,2005;Zhangetal.,2009),维纳滤波器

Springboot 集成WebSocket作为客户端,含重连接功能,开箱即用

使用演示publicstaticvoidmain(String[]args)throwsException{//初始化socket客户端BaseWebSocketClientsocketClient=BaseWebSocketClient.init("传入链接");//发送消息socketClient.sendMess

电磁散射模拟的体积积分方程求解器:使用MATLAB中的ceviche_challenges模块进行光子器件逆向设计详解

第一部分:电磁散射模拟与体积积分方程求解器简介在现代光子学领域,电磁散射模拟是一个核心技术,它涉及到光子器件的设计、分析和优化。为了准确地模拟电磁波在复杂介质中的传播,研究者们开发了多种数值方法。其中,体积积分方程求解器是一个强大的工具,它可以为复杂的光子器件提供精确的模拟结果。MATLAB,作为一个广泛使用的数值计算

讯飞星火认知大模型Java后端接口

文章目录1.免费申请星火大模型套餐2.Java后端接口说明2.1项目地址2.2项目说明2.3项目结构2.4项目代码🍀maven依赖🍀application.yml配置文件🍀config包📌XfXhConfig🍀dto包📌MsgDTO📌RequestDTO📌ResponseDTO🍀listener包📌

详细介绍下路由器的LAN接口

路由器的LAN口(LocalAreaNetworkport)是指用于连接局域网(LAN)设备的接口。它提供了有线连接的接口,允许局域网内的设备通过以太网线连接到路由器,并与其他局域网设备进行通信。以下是对路由器的LAN口的详细介绍:功能:LAN口的主要功能是提供有线网络连接,用于连接局域网内的设备,如台式电脑、网络打印

探索状态驱动开发的奇妙世界——Cola-StateMachine的介绍与使用

文章目录1.前言2.Cola-StateMachine概述3.Cola-StateMachine相关API4.Cola-StateMachine实战5.其他1.前言前面接受了Spring实现的状态机SpringStateMachine,这个状态机的优点在于功能很完备,缺点也是功能十分完备。完备到什么程度了,提供了状态机

ICS TRIPLEX T8310 自动化控制模块

ICSTRIPLEXT8310是一种自动化控制模块,通常用于工业控制和自动化系统中,以实现对各种过程和设备的自动控制。以下是可能包括在ICSTRIPLEXT8310自动化控制模块中的一些常见产品功能:PLC(可编程逻辑控制器)功能:T8310模块通常具备PLC功能,可编程逻辑控制,以实现自动化控制逻辑和任务。多通道输入

C#webform Static DataTable 多人同时操作网页数据重复问题

在C#WebForms中,如果声明一个static变量,它将在整个应用程序域(ApplicationDomain)中保持持久化状态。每个用户的请求都在同一个应用程序域中处理,因此static变量在不同页面间保持相同的值。当一个用户发起请求时,Web服务器会创建一个新的线程来处理该请求,但它仍然在同一个应用程序域中运行。

C#通过重写Panel改变边框颜色与宽度的方法

在C#中,Panel控件是一个容器控件,用于在窗体或用户控件中创建一个可用于容纳其他控件的面板。Panel提供了一种将相关控件组合在一起并进行布局的方式。以下是Panel控件的详细使用方法:在窗体上放置Panel控件:在VisualStudio的窗体设计器中,从工具箱中拖动并放置一个Panel控件到你的窗体上。添加其他

【大数据】Doris 构建实时数仓落地方案详解(一):实时数据仓库概述

本系列包含:Doris构建实时数仓落地方案详解(一):实时数据仓库概述Doris构建实时数仓落地方案详解(二):Doris核心功能解读Doris构建实时数仓落地方案详解(三):Doris实时数仓设计Doris构建实时数仓落地方案详解(一):实时数据仓库概述1.数据仓库的发展历程2.数据仓库技术的发展3.数仓的相关技术栈

grafana结合Skywalking追踪Trace(一)

SW应用中对Trace的跟踪一直占有重要的地位,即可以用户指定的tag值,可以筛选出感兴趣的trace(跟踪链),用户可以通过跟踪链追踪各个Span的详细情况。但是在使用SWOAP原生页面中会存在两个问题:1)Trace数量太多了,需要反复搜索才能找到2)找到的Trace,往往代表一类业务,但原生的OAP无法提供Tra

热文推荐