大屏适配方案自适应
方案(一)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 中引入
1 | 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具