1. 视口单位布局 (Viewport Units)
使用 vw
和 vh
单位来实现响应式布局:
scss
.full-screen {
width: vw(1920);
height: vh(1080);
padding: vh(5) vw(5) vh(5) vw(5);
}
.header-title {
font-size: vw(40);
line-height: vh(80);
}
这里的 vw()
和 vh()
函数是自定义的 SCSS 函数,用于将设计稿尺寸(1920×1080)转换为视口单位。
SCSS函数:
scss
@use "sass:math";
$designWidth: 1920;
$designHeight: 1080;
@function vw($px){
@return math.div($px, $designWidth) * 100vw;
}
@function vh($px){
@return math.div($px, $designHeight) * 100vh;
}
需要在 vite.config.js
中配置,非常重要,它实现了 SCSS 预处理器的全局变量和函数注入功能:
javascript
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/styles/utils.scss";'
},
},
}
作用解释
1. 全局 SCSS 变量和函数注入
这段配置会在编译每个 SCSS 文件时,自动在文件开头插入 @import "@/styles/utils.scss";
。这意味着:
- 无需在每个 Vue 组件的
<style>
标签中手动导入utils.scss
- 所有 SCSS 变量、混合宏(mixin)和函数都可以在所有组件中直接使用
2. 实际效果
由于这个配置,可以在任何组件的样式中直接使用 vw()
和 vh()
函数:
vue
<template>
<div class="container">...</div>
</template>
<style scoped lang="scss">
.container {
width: vw(300); // 直接使用,无需导入
height: vh(200); // 直接使用,无需导入
padding: vh(10) vw(20);
}
</style>
注意事项
- 避免副作用 :确保
utils.scss
中不包含实际 CSS 输出,只包含变量、混合宏和函数 - 性能影响:虽然轻微,但每个样式文件都会额外编译注入的内容
- 命名冲突:全局注入可能导致命名冲突,需注意命名规范
函数工作原理
- 设计基准:以 1920×1080 分辨率作为设计基准
- 单位转换 :
vw($px)
:将像素值转换为相对于视口宽度的百分比vh($px)
:将像素值转换为相对于视口高度的百分比
- 计算方式 :
math.div($px, $designWidth) * 100vw
:计算元素宽度占设计稿宽度的比例,然后转换为视口宽度单位math.div($px, $designHeight) * 100vh
:计算元素高度占设计稿高度的比例,然后转换为视口高度单位
使用示例
scss
.header {
width: vw(1900); // 转换为约 98.96vw (1900/1920*100)
height: vh(100); // 转换为约 9.26vh (100/1080*100)
font-size: vh(40); // 转换为约 3.7vh
}
.content-box {
margin: vh(5) 0;
padding: vh(5) vw(5) vh(10) vw(5);
}
注意事项
- 极端比例屏幕(如超宽屏)可能需要额外媒体查询调整
- 字体大小使用视口单位可能导致可读性问题,需要谨慎使用
- 最小字体大小可能需要设置限制,防止在小屏幕上过小
这种方法是实现大屏自适应布局的高效方式,特别适合数据可视化类的大屏项目。
2. Flex 弹性布局
整体布局使用 Flexbox 实现:
html
<div class="full-screen">
<div class="header">...</div>
<div class="center">...</div>
<div class="footer">...</div>
</div>
scss
.full-screen {
display: flex;
flex-direction: column;
}
.center {
display: flex;
// flex-direction: column;
}
3. 图表自适应
ECharts 图表通过监听窗口 resize 事件实现自适应:
javascript
window.addEventListener('resize', () => {
myChart.resize();
});
4. 全屏切换功能
使用 screenfull 库实现全屏切换:
javascript
let fullScreen = () => {
if (screenfull.isEnabled) {
screenfull.toggle();
}
};
5. 缩放控制
通过监听滚轮事件实现页面缩放:
javascript
window.addEventListener('wheel', function(event) {
if (event.ctrlKey || event.metaKey) {
if (event.deltaY > 0) {
document.body.style.zoom = (parseFloat(getComputedStyle(document.body).zoom) || 1) * 1.1;
}
if (event.deltaY < 0) {
document.body.style.zoom = (parseFloat(getComputedStyle(document.body).zoom) || 1) / 1.1;
}
}
});
6. 栅格系统
使用 Element Plus 的栅格系统进行列布局:
html
<el-row class="header" :gutter="20">
<el-col :span="7" class="header-time">...</el-col>
<el-col :span="10" class="header-title">...</el-col>
<el-col :span="6">...</el-col>
</el-row>
7. 媒体查询
有码友可以补充一下嘛?