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

具体问题场景

        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端上的。为了避免各种坑爹问题,我在项目中还是选择了多端为一端的开发方案。具体项目下解决Echarts多端同步开发和维护的问题_第1张图片

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

图表部分

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


        <...>
          
        
 

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


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

通讯部分  

        代码分为两部分

 移动端部分

        主体

  
      ....
      
      
        
        
        
      

        很简单的一个移动端页面中间嵌套了一个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')
    },
]

 

你可能感兴趣的:(三叠云项目,前端,echarts,javascript)