VUE3大屏自适应布局

1. 视口单位布局 (Viewport Units)

使用 vwvh 单位来实现响应式布局:

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>

注意事项

  1. 避免副作用 :确保 utils.scss 中不包含实际 CSS 输出,只包含变量、混合宏和函数
  2. 性能影响:虽然轻微,但每个样式文件都会额外编译注入的内容
  3. 命名冲突:全局注入可能导致命名冲突,需注意命名规范

函数工作原理

  1. 设计基准:以 1920×1080 分辨率作为设计基准
  2. 单位转换
    • vw($px):将像素值转换为相对于视口宽度的百分比
    • vh($px):将像素值转换为相对于视口高度的百分比
  3. 计算方式
    • 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);
}

注意事项

  1. 极端比例屏幕(如超宽屏)可能需要额外媒体查询调整
  2. 字体大小使用视口单位可能导致可读性问题,需要谨慎使用
  3. 最小字体大小可能需要设置限制,防止在小屏幕上过小

这种方法是实现大屏自适应布局的高效方式,特别适合数据可视化类的大屏项目。

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. 媒体查询

有码友可以补充一下嘛?

相关推荐
只会写Bug1 小时前
后台管理项目中关于新增、编辑弹框使用的另一种展示形式
前端·vue.js
M ? A2 小时前
Vue v-bind 转 React:VuReact 怎么处理?
前端·javascript·vue.js·经验分享·react.js·面试·vureact
军军君012 小时前
数字孪生监控大屏实战模板:政务服务大数据
前端·javascript·vue.js·typescript·前端框架·echarts·less
忆往wu前2 小时前
前端请求三部曲:Ajax / Fetch / Axios 演进与 Vue 工程化封装
前端·vue.js
.Cnn3 小时前
Ajax与Vue 生命周期核心笔记
前端·javascript·vue.js·笔记·ajax
吴声子夜歌4 小时前
Vue3——渲染函数
前端·vue.js·vue·es6
Ruihong4 小时前
你的 Vue KeepAlive 组件,VuReact 会编译成什么样的 React 代码?
vue.js·react.js·面试
Ruihong4 小时前
你的 Vue slot 插槽,VuReact 会编译成什么样的 React 代码?
vue.js·react.js·面试
一 乐4 小时前
房产租赁管理|基于springboot + vue房产租赁管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·房产租赁管理系统
2501_913680004 小时前
Vue3项目快速接入AI助手的终极方案 - 让你的应用智能升级
前端·vue.js·人工智能·ai·vue·开源软件