前端大屏适配几种方案

1920*1080的设计稿。

方案一:vw(单位)

假设设计稿尺寸为 1920*1080(做之前一定问清楚 ui 设计稿的尺寸)

即: 网页宽度=1920px 网页高度=1080px

我们都知道 网页宽度=100vw 网页宽度=100vh 所以,在 1920px*1080px 的屏幕分辨率下 1920px = 100vw 1080px = 100vh

这样一来,以一个宽 300px 和 200px 的 div 来说,其所占的宽高,以 vw 和 vh 为单位,

计算方式如下: vwDiv = (300px / 1920px ) * 100vw vhDiv = (200px / 1080px ) * 100vh

所以,就在 1920*1080 的屏幕分辨率下,计算出了单个 div 的宽高 当屏幕放大或者缩小时,div 还是以 vw 和 vh 作为宽高的,就会自动适应不同分辨率的屏幕

使用scss

util.scss

// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div
@use "sass:math";// 默认设计稿的宽度
$designWidth: 1920;
// 默认设计稿的高度
$designHeight: 1080;// px 转为 vw 的函数
@function vw($px) {@return math.div($px, $designWidth) * 100vw;
}// px 转为 vh 的函数
@function vh($px) {@return math.div($px, $designHeight) * 100vh;
}

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

vue.config.js

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: {prependData: `@import "@/styles/utils.scss";`,},},},
};

如果是vite.config.ts得这样配置

  return {resolve: {// Vite路径别名配置alias: {"@": pathSrc,},},css: {// CSS 预处理器preprocessorOptions: {//define global scss variablescss: {javascriptEnabled: true,additionalData: `@use "@/styles/variables.scss" as *;// 必须这样配置才能生效!@use "@/styles/until.scss" as *;`,},},},};

  在.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;
}
</style>

定义 js 样式处理函数

// 定义设计稿的宽高
const designWidth = 1920;
const designHeight = 1080;// px转vw
export const px2vw = (_px) => {return (_px * 100.0) / designWidth + 'vw';
};export const px2vh = (_px) => {return (_px * 100.0) / designHeight + 'vh';
};export const px2font = (_px) => {return (_px * 100.0) / designWidth + 'vw';
};

屏幕变化后,图表自动调整

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

为了解决这个问题,你需要在各个图表中监听页面尺寸变化,重新调整图表,在 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

// 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.html 代码

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

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

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

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

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

  • 默认情况下,这里以你的设计稿是 1920*1080 为例,即网页宽度是 1920px (做之前一定问清楚 ui 设计稿的尺寸)

  • 把这个函数写在一个单独的工具文件dataUtil.js里面,在需要的时候调用

  • 其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值

  • 另外,其它 echarts 的配置项,比如间距、定位、边距也可以用该函数

1.编写 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.将函数挂载到原型上

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

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

<template><div class="chartsdom" ref="chart" v-chart-resize></div>
</template><script>
export default {name: "dashboardChart",data() {return {option: null,};},mounted() {this.getEchart();},methods: {getEchart() {let myChart = this.$echarts.init(this.$refs.chart);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,},calculable: true,series: [{color: ["#0db1cdcc"],name: "计划投入",type: "funnel",width: "45%",height: "70%",x: "5%",minSize: "10%",funnelAlign: "right",center: ["50%", "50%"], // for piedata: [{value: 30,name: "下单30%",},{value: 55,name: "咨询55%",},{value: 65,name: "点击65%",},{value: 60,name: "访问62%",},{value: 80,name: "展现80%",},].sort(function (a, b) {return a.value - b.value;}),roseType: true,label: {normal: {formatter: function () {},position: "inside",},},itemStyle: {normal: {borderWidth: 0,shadowBlur: this.fitChartSize(20),shadowOffsetX: 0,shadowOffsetY: this.fitChartSize(5),shadowColor: "rgba(0, 0, 0, 0.3)",},},},{color: ["#0C66FF"],name: "实际投入",type: "funnel",width: "45%",height: "70%",x: "50%",minSize: "10%",funnelAlign: "left",center: ["50%", "50%"], // for piedata: [{value: 35,name: "下单35%",},{value: 40,name: "咨询40%",},{value: 70,name: "访问70%",},{value: 90,name: "点击90%",},{value: 95,name: "展现95%",},].sort(function (a, b) {return a.value - b.value;}),roseType: true,label: {normal: {position: "inside",},},itemStyle: {normal: {borderWidth: 0,shadowBlur: this.fitChartSize(20),shadowOffsetX: 0,shadowOffsetY: this.fitChartSize(5),shadowColor: "rgba(0, 0, 0, 0.3)",},},},],};myChart.setOption(option, true);},},beforeDestroy() {},
};
</script><style lang="scss" scoped>
.chartsdom {width: 100%;height: 100%;
}
</style>

方案二:scale(缩放)强烈推荐

我们整个大屏的尺寸设置和设计图一样,只是通过css的scale放大缩小属性,来控制实际展示的大小。

通过监听浏览器窗口的大小,来改变scale的比例,从而实现数据大屏适配。(百度、网易等大数据适配的解决方案均是这个)

设计稿宽高比是 1920 * 1080

缺点:1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.当缩放比例过大时候,字体会有一点点模糊,就一点点 3.当缩放比例过大时候,事件热区会偏移。

空白的部分用背景图片填充就好了。

<template><div class="container"><!-- 数据大屏展示内容区域 --><div class="screen" ref="screen"><div class="top"><Top></Top></div><div class="bottom"><div class="left">左侧</div><div class="center">中间</div><div class="right">右侧</div></div></div></div>
</template><script setup lang="ts">
import Top from './components/top/index.vue'import { ref, onMounted } from 'vue'//获取数据大屏展示内容盒子的DOM元素
let screen = ref()
onMounted(() => {screen.value.style.transform = `scale(${getScale()}) translate(-50%,-50%)`// screen.value.style.transform = `translate(-50%,-50%) scale(${getScale().ww},${getScale().wh})`;})
//定义大屏缩放比例
function getScale(w = 1920, h = 1080) {const ww = window.innerWidth / wconst wh = window.innerHeight / hreturn ww < wh ? ww : wh;// return { ww, wh };
}
// 根据浏览器大小推断缩放比例
// 首先要确定设计稿尺寸,默认是 1920 x 1080
// 分别计算浏览器和设计图宽高比
// 如果浏览器的宽高比大于设计稿的宽高比,就取浏览器高度和设计稿高度之比
// 如果浏览器的宽高比小于设计稿的宽高比,就取浏览器宽度和设计稿宽度之比
//监听视口变化
window.onresize = () => {screen.value.style.transform = `scale(${getScale()}) translate(-50%,-50%)`
}
</script><style scoped lang="scss">
.container {width: 100vw;height: 100vh;background: url(./images/bg.png) no-repeat;background-size: cover;.screen {/* 注意:width,height 原稿多大就设多大 */width: 1920px;height: 1080px;position: fixed;left: 50%;top: 50%;// transform-origin: left top;transform: translate(-50%, -50%);.top {width: 100%;height: 40px;}.bottom {display: flex;.left {flex: 1;height: 1040px;display: flex;flex-direction: column;.tourist {flex: 1.2;}.sex {flex: 1;}.age {flex: 1;}}.center {flex: 2;}.right {flex: 1;}}}
}
</style>
  1. 获取数据大屏展示内容区域的 DOM 元素。
  2. style.transform:这是访问元素的 transform 样式属性。transform 是一个 CSS 属性,用于对元素进行变换,例如旋转、缩放、平移等。
  3. scale(${getScale()}):这部分代码中,getScale() 函数返回一个缩放比例,这个比例会应用在 scale() 函数中。这样,页面元素会按照指定的比例进行缩放。缩放比例是根据窗口大小和设计稿大小计算的,以确保内容适应不同的屏幕尺寸。
  4. translate(-50%, -50%):这部分代码中,translate() 函数用于对元素进行平移。在这里,它将元素的中心点平移到屏幕的中心。-50% 表示水平和垂直方向都要将元素平移到其自身宽度和高度的一半的位置,从而实现居中效果。
  5. transform-origin 是 CSS 属性,用于指定元素的变换(比如旋转、缩放、平移等)的原点位置,即元素围绕哪个点进行变换操作。在你提供的样式中,transform-origin 设置为 left top,这意味着元素的变换原点位于元素的左上角。

方案三:插件v-scale-screen

它其实也是通过 scale 进行等比例计算放大和缩小的,和方案二的原理是一样的,还可以通过api调整样式,源码地址和对应的API 

使用方法:
1.vue2请使用v-scale-screen@1.0.0版本,vue3请使用v-scale-screen@2.0.0版本

npm install v-scale-screen@1.0.0 -save
# or
yarn add v-scale-screen

2.使用-vue2中使用插件导入,vue3以组件导入

vue2
// main.js
import VScaleScreen from 'v-scale-screen'
Vue.use(VScaleScreen)
组件内使用
//html
<v-scale-screen width="1920" height="1080" :boxStyle="boxStyle"><div><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart></div>
</v-scale-screen>
//jsdata() {return {boxStyle: {backgroundColor: 'green'},}
vue3
<v-scale-screen width="1920" height="1080"><div><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart><v-chart>....</v-chart></div>
</v-scale-screen>
<script>
import VScaleScreen from 'v-scale-screen'
export default {components:{VScaleScreen}
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/537243.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云轻量应用服务器使用全攻略,都在这!

腾讯云轻量应用服务器怎么使用&#xff1f;轻量应用服务器使用包括快速创建轻量服务器、轻量服务器远程连接、使用轻量应用服务器搭建网站教程、轻量服务器开通端口教程等&#xff0c;腾讯云服务器网txyfwq.com整理了关于腾讯云轻量应用服务器的使用教程&#xff0c;目前轻量应…

第六篇【传奇开心果系列】Python的自动化办公库技术点案例示例:大学生数据全方位分析挖掘经典案例

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas库全方位分析挖掘大学生数据能力介绍二、大学生学生成绩数据分析数据挖掘示例代码三、大学生选课数据分析数据挖掘示例代码四、大学生活动参与数据分析数据挖掘示例代码五、大学…

React Hooks 那些事儿

翻了波之前写的文章还有笔记&#xff0c;发现关于前端的文章并不多&#xff08;好歹也划水做过点前端开发&#xff09;。巧了&#xff0c;最近没什么好话题可写&#xff0c;做下 React Hooks 学习笔记吧。 Effect Hook 不得不说 Hook 的出现降低了我们在 React 中处理副作用&…

VB+ACCESS学籍管理系统-264-(代码+说明)

转载地址: http://www.3q2008.com/soft/search.asp?keyword264 设计要求&#xff1a; 第一&#xff1a;一篇论文&#xff08;5000到10000字&#xff09;不包括图表和程序代码。A4纸20页之内。 论文结构如下&#xff1a; 设计题目&#xff1a;学籍管理系统 附&#xff1a;程…

LDK加密狗的多种功能特点

LDK加密狗是一种在软件保护领域广泛应用的硬件加密设备&#xff0c;它为软件提供了强有力的版权保护&#xff0c;确保软件开发商的权益得到充分保障。本文将从LDK加密狗的工作原理、功能特点、应用场景以及未来发展等方面进行详细阐述。 LDK加密狗的工作原理基于硬件加密技术。…

零知识玩转AVH(5)—— 怎么玩(4)

接前一篇文章&#xff1a;零知识玩转AVH&#xff08;4&#xff09;—— 怎么玩&#xff08;3&#xff09; 上一回经过了一个艰苦的探索过程&#xff0c;最终完成了“arm-avh-best-practice-project-product-subscription-guide-cn.pdf”即“Arm虚拟硬件实践专题一&#xff1a;产…

【绩效管理】某连锁购物中心绩效考核体系搭建咨询项目

随着企业规模的扩大&#xff0c;员工数量不断增加&#xff0c;与之相关的人事管理工作的复杂性也随之增大。但是由于行业的特点&#xff0c;该购物中心的人员整体素质偏低&#xff0c;且自成立以来&#xff0c;该中心重经营轻管理&#xff0c;其人力资源管理水平也有待提升。在…

第二证券|炒股最好用的6个指标?

炒股存在以下好用的6个目标&#xff1a; 1、kdj目标 当k线从下方往上穿过d线时&#xff0c;构成金叉&#xff0c;是一种买入信号&#xff0c;投资者能够考虑在此刻买入一些个股&#xff0c;其间kdj金叉方位越低&#xff0c;买入信号越强&#xff1b;当k线从上往下穿过d线时&a…

【Java并发知识总结 | 第四篇】Java线程池详讲

文章目录 4.Java线程池详讲4.1线程池介绍4.1.1什么是线程池4.1.2线程池的作用4.1.3没有线程池的线程执行任务模型 4.2JAVA线程池4.2.1Executor框架介绍4.2.2Executor框架的组成&#xff08;1&#xff09;任务&#xff08;Runnable/Callable&#xff09;&#xff08;2&#xff0…

视频格式怎么批量转换?5 个批量视频转换器分享

可以同时转换多个视频吗&#xff1f;您是否正在寻找一款有用的批量视频转换器&#xff1f;最好的批量视频转换器是什么&#xff1f; 使用批量视频转换器同时转换多个视频文件是一个好方法。这篇文章为您总结了 5 个最好的批量视频转换器。 5 个批量视频转换器分享 1、奇客视频…

不用ChatGPT会扣分!韩国大学大胆拥抱生成式AI

“请尝试使用人工智能(AI)进行创作”。 这是韩国成均馆大学影像系教授李慧旼(音)在上学期的课堂中给学生们留的作业。她希望学生们能利用生成型绘图AI软件Dall-E或Midjourney来创作作品。学生们利用AI创作的作品非常有趣&#xff0c;一名学生用文字描述了喜欢用的香水后&#x…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时&#xff0c;几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法&#xff1a; 2. 错误的导入路径解决方法&#xff1a; 3. 第三方库的使用错误解决方法&#xff1a; 4. 包未正…