Live2d Test Env

【论术】项目复盘总结-响应式界面

工作的意义和动力本质上是终身学习者在自由市场中的创造性表达 —— 佚名

项目需求:首页需要在用户屏幕下实现自适应并尽量维持UI稿中的样式,而用户的分辨率不能保持在1920*1080,缩放比率通常在150%,且界面图片要确保其不失真。

此需求下,媒体查询无法实现特定高度不失效,使用js动态设置容器宽高又无法在短时间内全部完成间距尺寸的修改
因而采用了一种特殊的实现方式。

一 定义基准

  1. 基准宽:1920(ui稿)
  2. 基准高:1080(ui稿) 注意:项目实际使用中要减去ui稿顶部的navBar高度(如果有)
  3. 固定区间:在某个高度范围内不进行任何适配,基于ui稿1:1还原

二 封装适配逻辑

计算当前屏幕的宽高,从再与基准宽高相除得到宽高比

vue2

// ./AutoFitMixin.js
export default {
  data() {
    return {
      fitStyle: {
        '--hScale': 1, // 高度缩放比例
        '--wScale': 1, // 宽度缩放比例
      }
    };
  },
  //挂载所在的节点下的所有正常子孙组件都可以接收到fitStyle这个变量,但是类似于Echart这类组件可能要监听这个变量从而重新绘制图表,因而使用依赖注入的方式将此值传递出去,图表组件可以监听`globalScale.--hScale`以触发重新绘制
  provide() {
    return {
      globalScale: this.fitStyle 
    };
  },
  methods: {
    _calcScale() {
      const currentW = window.innerWidth;
      const currentH = window.innerHeight;
      const baseW = 1920;
      const baseH = 890;  // 1080 - navHeight
      const lockRange = [890, 950];

      const wScale = currentW / baseW;
      let hScale = 1;
      if (currentH < lockRange[0] || currentH > lockRange[1]) {
        hScale = currentH / baseH;
      }
      this.fitStyle['--hScale'] = hScale;
      this.fitStyle['--wScale'] = wScale;
    }
  },
  mounted() {
    this._calcScale();
    window.addEventListener('resize', this._calcScale);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this._calcScale);
  }
};

三 模板注入

根节点动态添加style以配置mixin的宽高比(利用CSS作用域向下传递的特性,此dom下所有子孙节点都继承了fitStyle的值)

<template>
  <div class="home-container" :style="fitStyle">
  </div>
</template>

<script>
import AutoFitMixin from './AutoFitMixin';

export default {
  mixins: [AutoFitMixin], 
}
</script>

四 CSS解析映射

这一步最复杂,最繁琐也最重要

//lang=less
// 定义缩放变量别名
@s: var(--hScale); 

// 定义缩放函数
.fit(@prop, @val) {
  @{prop}: calc(@val * @s);
}

// 如果是复合属性
padding: calc(16px * @s);

// 如果是单一属性
.fit(margin-top, 24px); // 设置上间距
.fit(border-radius, 8px); // 设置圆角
// 字体适配
font-size: calc(34px * @s);
//动态设置图片宽高比  start
aspect-ratio: 16 / 9;  // 假设图片宽高比是16比9
width: 40%; // 注意aspect-ratio的正确应用的前提是要有宽度
//动态设置图片宽高比  end

总结

js里获取并导出了当前宽高比fitStyle;
template使用动态style在根目录声明了fitStyle,因而其所有子孙节点都继承了这个属性;
css中定义的@s本质上就是当前高,界面中所有的尺寸都基于此值使用calc进行动态计算, .fit是less赋予的函数能力
在每次resize时都会实时更新fitStyle,随后此流程再次运转,界面再次响应式展示

以上。

posted @ 2025-12-08 19:38  致爱丽丝  阅读(27)  评论(0)    收藏  举报