大屏适配方案自适应

方案(一)vw+vh方案:

1.安装sass和sass loader

node 16+安装版本如下,node16以下百度查找对饮的版本

npm i sass@1.58.2  sass-loader@10.2.0 -D

要想使用math.div函数,sass的版本必须在1.33.0及以上。

scss 数学操作符(operators)包括加(+)减(-)乘(*)除(math.div()),和取整(%)。在使用前要先导入math的包.

@debug math.div(1, 2); // 0.5
@debug math.div(100px, 5px); // 20
@debug math.div(100px, 5); // 20px
@debug math.div(100px, 5s); // 20px/s

是的你没看错,math.div()就是 “除号”

2.新建utils.css文件

路径:src=>styles=>util.scss

// 使用 scss 的 math 函数
@use "sass:math";
// 默认设计稿的宽度
$designWidth: 1920;
// 默认设计稿的高度
$designHeight: 1080;
//最小字体 
$minFontSize: 12;

// px 转为 vw 的函数
@function vw($px) {
  @return math.div($px, $designWidth) * 100vw;
}

// px 转为 vh 的函数
@function vh($px) {
  @return math.div($px, $designHeight) * 100vh;
}
//字体px 转vw 的函数 
@function font($px){
  @return math.div($px, $designWidth) * 100vw; 
}

 

 

3.路径配置 只需在vue.config.js里配置一下utils.scss的路径,就可以全局使用了

const path = require("path");

function resolve(dir) {
  return path.join(__dirname, dir);
}

module.exports = {
  publicPath: "",
  configureWebpack: {
    name: "app name",
    resolve: {
      alias: {
        "@": resolve("src"),
      },
    },
  },
  css: {
    // 全局配置 utils.scs,详细配置参考 vue-cli 官网
    loaderOptions: {
      sass: {
         // sass-loader v10+,这个选项名是 "additionalData"
        //sass-loader v8-,这个选项名是 "data"
        //sass-loader v8 中,这个选项名是 "prependData"
        prependData: `@import "@/styles/utils.scss";`,
      },
    },
  },
};

4.在 .vue 中使用

<template>
    <div class="box">            
    </div>
</template>

<script>
export default{
    name: "Box",
}
</script>

<style lang="scss" scoped="scoped">
/* 
 直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh 单位         
 */
.box{
    width: vw(300);
    height: vh(100);
    font-size: vh(16);
    background-color: black;
    margin-left: vw(10);
    margin-top: vh(10);
    border: vh(2) solid red;
  font-size: font(30) }
</style>

5动态DOM元素适配(如业务用不到可忽略)

有的时候可能不仅在.vue文件中使用,比如在js中动态创建的DOM元素 它可能是直接渲染到html里面的

let oDiv = document.createElement('div')
document.body.appendChild(oDiv)

这种使用方式有个弊端,就是屏幕尺寸发生变化后,需要手动刷新一下才能完成自适应调整

为了解决这个问题,你需要在各个图表中监听页面尺寸变化,重新调整图表,在 vue 项目中,也可以借助element-resize-detector,最好封装个 resize 的指令,在各图表中就只要使用该指令就可以了。

1.安装 element-resize-detector

npm install element-resize-detector --save

2.引入工具包在组件中使用或者在单独的 js 中使用(如果封装自定义指令 ,这一步无需引入)

import resizeDetector from 'element-resize-detector'

3.封装 directive,路径:src=>directive=>directive.js

// directive.js
import * as ECharts from "echarts";
import elementResizeDetectorMaker from "element-resize-detector";
import Vue from "vue";
const HANDLER = "_vue_resize_handler";
function bind(el, binding) {
  el[HANDLER] = binding.value
    ? binding.value
    : () => {
        let chart = ECharts.getInstanceByDom(el);
        if (!chart) {
          return;
        }
        chart.resize();
      };
  // 监听绑定的div大小变化,更新 echarts 大小
  elementResizeDetectorMaker().listenTo(el, el[HANDLER]);
}
function unbind(el) {
  // window.removeEventListener("resize", el[HANDLER]);
  elementResizeDetectorMaker().removeListener(el, el[HANDLER]);
  delete el[HANDLER];
}
// 自定义指令:v-chart-resize 示例:v-chart-resize="fn"
Vue.directive("chart-resize", { bind, unbind });

4.main.js 中引入

import '@/directive/directive';

5.在.vue中使用

<template>
  <div class="linechart">
    <div ref="chart" v-chart-resize class="chart"></div>
  </div>
</template>

踩坑记录:

这里要注意的是,图表中如果需要 tab 切换动态更新图表数据,在更新数据时一定不要用 echarts 的 dispose 方法先将图表移除,再重新绘制,因为 resize 指令中挂载到的图表实例还是旧的,就监听不到新的 chart 元素的 resize 了,更新数据只需要用 chart 的 setOption 方法重新设置配置项即可。

 

6.图表字体、间距、位移等尺寸自适应

echarts 的字体大小只支持具体数值(像素),不能用百分比或者 vw 等尺寸,一般字体不会去做自适应,当宽高比跟 ui 稿比例出入太大时,会出现文字跟图表重叠的情况

这里我们就需要封装一个工具函数,来处理图表中文字自适应了:

(1)默认情况下,这里以设计稿是 1920*1080 为例,即网页宽度是 1920px

(2)把这个函数写在一个单独的工具文件dataUtil.js里面,在需要的时候调用 其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值 另外,其它 echarts 的配置项,比如间距、定位、边距也可以用该函数 编写 dataUtil.js 工具函数 

// Echarts图表字体、间距自适应
export const fitChartSize = (size,defalteWidth = 1920) => {
  let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
  if (!clientWidth) return size;
  let scale = (cientWidth / defalteWidth); //比例
return Number((size*scale).toFixed(3));
}

(3)将函数挂载到原型上

import {fitChartSize} from '@src/utils/dataUtil.js'
Vue.prototype.fitChartFont = fitChartSize;

(4)这样就可以在.vue文件中直接使用this.fitChartSize()调用

比如:

const option = {
        backgroundColor: "transparent",
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>{b} : {c}%",
        },
        grid: {
          left: this.fitChartSize(10),
          right: this.fitChartSize(20),
          top: this.fitChartSize(20),
          bottom: this.fitChartSize(10),
          containLabel: true,
        },
  ……其他配置项 }

 

 

方案(二)

datav:http://datav.jiaminghi.com/

v-scale-screen:https://github.com/Alfred-Skyblue/v-scale-screen

 

 

 

 

posted @ 2023-02-17 17:29  赵辉Coder  阅读(550)  评论(0编辑  收藏  举报