大屏可视化方案
方案 1 scale
1.优点:无需考虑 rem 单位,无需考虑定位,一次适配,无需单独处理图标
2.缺点:两边留白,比例过大时热区偏移,字体模糊.
具体实现
根据屏幕的变化适配的比例
<template>
<div class="screen-wrapper">
<div class="screen" id="screen">
<div class="box">123</div>
</div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
const initData = () => {
const designDraftWidth = 1920; //设计稿的宽度
const designDraftHeight = 1080; //设计稿的高度
//根据屏幕的变化适配的比例
const scale =
document.documentElement.clientWidth /
document.documentElement.clientHeight <
designDraftWidth / designDraftHeight
? document.documentElement.clientWidth / designDraftWidth
: document.documentElement.clientHeight / designDraftHeight;
//缩放比例
document.querySelector(
"#screen"
).style.transform = `scale(${scale}) translate(-50%)`;
};
onMounted(() => {
// 初始化时禁止滚动
document.documentElement.style.overflow = "hidden";
initData();
window.onresize = () => initData();
});
</script>
<style scoped lang="less">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
}
.screen-wrapper {
height: 100%;
width: 100%;
.screen {
display: inline-block;
width: 1920px; //设计稿的宽度
height: 1080px; //设计稿的高度
transform-origin: 0 0;
position: absolute;
left: 50%;
.box {
width: 100%;
height: 100px;
background-color: skyblue;
}
}
}
</style>
方案 2 vw vh
1.优点:动态处理图标宽高、字体,屏幕两边不留白,比例正常,
2.缺点:每个图标需要做单独处理,费事麻烦
具体实现
1.使用 PostCSS 插件 postcss-px-to-viewport
npm install postcss-px-to-viewport --save-dev
2.vue.config.js
module.exports = defineConfig({
transpileDependencies: true,
css: {
loaderOptions: {
postcss: {
postcssOptions: {
plugins: [
require("postcss-px-to-viewport")({
unitToConvert: "px", // 要转换的单位
viewportWidth: 1920, // 设计稿宽度
viewportHeight: 1080, // 设计稿高度
unitPrecision: 5, // 转换后保留的小数位数
viewportUnit: "vw", // 转换成的单位
fontViewportUnit: "vw", // 字体转换成的单位
selectorBlackList: [], // 不转换的选择器(如 .ignore-*)
minPixelValue: 1, // 最小转换值(1px 以下不转换)
mediaQuery: false, // 是否转换媒体查询里的 px
}),
],
},
},
},
},
});
3.直接写 px,自动转 vw
<style lang="less" scoped>
.box {
width: 300px; /* 自动转成 vw */
height: 100px; /* 自动转成 vh */
font-size: 16px; /* 自动转成 vw */
margin-left: 300px; /* 自动转成 vw */
margin-top: 100px; /* 自动转成 vh */
}
</style>
图表自适应方案
- 安装 element-resize-detector
npm install element-resize-detector --save
- 引入工具包在组件中使用或者在单独的 js 中使用
import resizeDetector from 'element-resize-detector'
- 封装 directive
js 体验AI代码助手 代码解读复制代码// 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 });
- main.js 中引入
import '@/directive/directive';
- html 代码
<template>
<div class="linechart">
<div ref="chart" v-chart-resize class="chart"></div>
</div>
</template>
特殊尺寸处理工具
有些特殊情况,echarts只支持具体的px,导致文字过大过小或者重叠,就需要手动适配
- 编写 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 = (clientWidth / defalteWidth);
return Number((size*scale).toFixed(3));
}
2.图表使用
grid: {
left: this.fitChartSize(10),
right: this.fitChartSize(20),
top: this.fitChartSize(20),
bottom: this.fitChartSize(10),
},
方案3 第三方库v-scale-screen
vue2请使用v-scale-screen@1.0.0版本,vue3请使用v-scale-screen@2.0.0版本