前端自适应方案

前端自适应方案

  • 基于rem的适配方案

    • rem: 指相对于根元素的字体大小的单位,在日常开发过程中我们通常把根元素(html/body)的字体设置为10px,方便于我们计算(此时子元素的1rem就相当于10px)

    • 适用场景不固定宽高比的Web应用,适用于绝大部分业务场景

    • 使用方式

      • 安装依赖
      npm i postcss-pxtorem autoprefixer amfe-flexible --save-dev
      

      注:postcss-pxtorem 是PostCSS的插件,用于将像素单元生成rem单位 autoprefixer 浏览器前缀处理插件 amfe-flexible 可伸缩布局方案 替代了原先的lib-flexible 选用了当前众多浏览器兼容的viewport

      • 项目根目录创建 postcss.config.js 文件
      module.exports = {
       plugins: {
        autoprefixer: {
         overrideBrowserslist: [
          "Android 4.1",
          "iOS 7.1",
          "Chrome > 31",
          "ff > 31",
          "ie >= 8",
          "last 10 versions", // 所有主流浏览器最近10版本用
         ],
         grid: true,
        },
        "postcss-pxtorem": {
         rootValue: 192, // 设计稿宽度的1/ 10 例如设计稿按照 1920设计 此处就为192
         propList: ["*", "!border"], // 除 border 外所有px 转 rem
         selectorBlackList: [".el-"], // 过滤掉.el-开头的class,不进行rem转换
        },
       },
      };
      
      • main.ts/js 文件中导入依赖
      import "amfe-flexible/index.js";
      
      • 项目重启即可
      • **建议:**vscode安装 px to rem & rpx & vw (cssrem)插件,同时在vscode左上角的文件 – 首选项 – 设置(左下角管理 – 设置) – 输入框输入“root”,找到 "基准font-size "更改为192,然后在就能够根据视觉稿中的像素值进行自动转化rem值。
  • 基于scale的适配方案

    • 在CSS3中,我们可以使用transform属性的scale()方法来实现元素的缩放效果。缩放,指的是“缩小”和“放大”的意思。

    • transform: scaleX(x); / 沿x轴方向缩放/

    • transform: scaleY(y); / 沿y轴方向缩放/

    • transform: scale(); / 同时沿x轴和y轴缩放/

    • 适用场景固定宽高比的Web应用,如大屏或者固定窗口业务应用

    • 使用方式(Vue2)

      • 新建resize.ts/js文件
      // * 设计稿尺寸(px)
      const baseWidth = 1920;
      const baseHeight = 1080;
      const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5));
      
      
      export default {
        data() {
          return {
            screenRef: '', // * 指向最外层容器
            timer: 0, // 定时函数
            scale: {
              width: "1",
              height: "1",
            }, // 默认缩放值
            baseProportion,
          }
        },
        methods: {
          // * 需保持的比例(默认1.77778)
          calcRate() {
            // 当前宽高比
            const currentRate = parseFloat(
              (window.innerWidth / window.innerHeight).toFixed(5)
            );
            if (this.screenRef) {
              if (currentRate > this.baseProportion) {
                // 表示更宽
                this.scale.width = (
                (window.innerHeight * this.baseProportion) /
                  baseWidth
                ).toFixed(5);
                this.scale.height = (window.innerHeight / baseHeight).toFixed(5);
                this.screenRef.style.transform = `this.(${scale.width}, ${this.scale.height})`;
              } else {
                // 表示更高
                this.scale.height = (
                window.innerWidth /
                this.baseProportion /
                baseHeight
                ).toFixed(5);
                this.scale.width = (window.innerWidth / baseWidth).toFixed(5);
                this.screenRef.style.transform = `scale(${this.scale.width}, ${this.scale.height})`;
              }
            }
          },
      
          resize() {
            clearTimeout(this.timer);
            this.timer = window.setTimeout(() => {
              this.calcRate();
            }, 200);
          },
      
          // 改变窗口大小重新绘制
          windowDraw() {
            window.addEventListener("resize", this.resize);
          },
      
          // 改变窗口大小重新绘制
          unWindowDraw() {
            window.removeEventListener("resize", this.resize);
          },
        },
      }
      
      • 相关界面引入resize.ts/js
      <script>
      import windowResize from './minxins/resize';
      
      export default {
        name: 'App',
        components: {},
        mixins: [windowResize],
        data() {
          return {}
        },
        mounted() {
          // 监听浏览器窗口尺寸变化
          this.windowDraw()
          this.calcRate()
        },
        destroyed() {
          this.unWindowDraw();
        },
      }
      </script>
      
      • 注意:如果是通过mixins的方法引入,需要在main.js文件加入下面代码:

        import minxins from './minxins/resize';
        
        Vue.use(minxins);
        
    • 使用方式(Vue3)

      • 新建resize.ts/js文件
      import { ref } from "vue";
      
      export default function windowResize() {
       // * 指向最外层容器
       const screenRef = ref();
       // * 定时函数
       const timer = ref(0);
       // * 默认缩放值
       const scale = {
        width: "1",
        height: "1",
       };
          
       // * 设计稿尺寸(px)
       const baseWidth = 1920;
       const baseHeight = 1080;
      
       // * 需保持的比例(默认1.77778)
       const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5));
       const calcRate = () => {
        // 当前宽高比
        const currentRate = parseFloat(
         (window.innerWidth / window.innerHeight).toFixed(5)
        );
        if (screenRef.value) {
         if (currentRate > baseProportion) {
          // 表示更宽
          scale.width = (
           (window.innerHeight * baseProportion) /
           baseWidth
          ).toFixed(5);
          scale.height = (window.innerHeight / baseHeight).toFixed(5);
          screenRef.value.style.transform = `scale(${scale.width}, ${scale.height})`;
         } else {
          // 表示更高
          scale.height = (
           window.innerWidth /
           baseProportion /
           baseHeight
          ).toFixed(5);
          scale.width = (window.innerWidth / baseWidth).toFixed(5);
          screenRef.value.style.transform = `scale(${scale.width}, ${scale.height})`;
         }
        }
       };
      
       const resize = () => {
        clearTimeout(timer.value);
        timer.value = window.setTimeout(() => {
         calcRate();
        }, 200);
       };
      
       // 改变窗口大小重新绘制
       const windowDraw = () => {
        window.addEventListener("resize", resize);
       };
      
       // 改变窗口大小重新绘制
       const unWindowDraw = () => {
        window.removeEventListener("resize", resize);
       };
      
       return {
        screenRef,
        calcRate,
        windowDraw,
        unWindowDraw,
       };
      }
      
      • 相关界面引入resize.ts/js
      <template>
          <div class="screen-container">
              <div class="screen-content" ref="screenRef">
                  <span class="screen-title">基于scale的适配方案</span>
                  <img class="screen-img" src="https://img2.baidu.com/it/u=1297807229,3828610143&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281" alt="">
              </div>
          </div>
      </template>
      
      <script setup lang="ts">
      import windowResize from '../../utils/resize';
      import {onMounted, onUnmounted} from 'vue';
      
      const { screenRef, calcRate, windowDraw, unWindowDraw } = windowResize()
      
      onMounted(() => {
          // 监听浏览器窗口尺寸变化
          windowDraw()
          calcRate()
      })
      
      onUnmounted(() => {
          unWindowDraw();
      })
      
      </script>
      
      <style lang="scss" scoped>
      .screen-container {
          height: 100%;
          background-color: lightcyan;
          display: flex;
          justify-content: center;
          align-items: center;
          .screen-content {
              width: 1920px;
              height: 1080px;
              background-color: #fff;
              display: flex;
              justify-content: center;
              align-items: center;
              flex-direction: column;
              .screen-title {
                  font-size: 32px;
              }
              .screen-img {
                  margin-top: 20px;
              }
          }
      }
      </style>
      
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值