基于postCSS手写postcss-px-to-vewiport插件实现移动端适配

🌟前言

        目前前端实现移动端适配方案千千万,眼花缭乱各有有缺,但目前来说postcss-px-to-vewiport是一种非常合适的实现方案,postcss-px-to-vewiport是一个基于postCss开发的插件,其原理就是将项目中的px单位转换为vw(视口宽度)。对postCss不了解的朋友可以看看我的上篇文章postCss基本介绍。

🌟实现

        本篇文章是使用vite + vue3 基于postCss来实现postcss-px-to-vewiport插件。

1.创建项目

使用vite创建

npm init vite@latest

使用vue脚手架创建

vue create projectname

选自己喜欢的方式创建就OK

2.简单布局

在公司项目开发中,UI会出设计图,会有一个设计稿的宽度,然后我们根据这个宽度去适配,假设我们现在设计稿的宽度是1280,那么我们写出下面的简单布局:

App.vue文件:

<template>
  <div class="page">
    <div class="left"></div>
    <div class="right">
      测试自适应
    </div>
  </div>
</template>

<style scoped>
.page{
  width: 1276px;
  height: 748px;
  display: flex;
  border: 2px red solid;

  .left{
    width: 600px;
    height: 300px;
    background-color: cadetblue;
  }
  .right{
    width: 300px;
    height: 300px;
    margin-left: 200px;
    background-color: #425e5e;
    font-size: 20px;;
  }
}
</style>

 可以看到,当页面宽度是1280时,我们上面写的代码是没有问题的,那这时候我们修改页面大小效果如下:

明显不是我们想要的效果,那么开搞。 

3.编写插件

vite中是自带postCss的,我们不需要额外安装,在vite.config.ts文件中如下:

export default defineConfig({
  plugins: [vue()],
  server: {
    host: '0.0.0.0', //默认情况是不能用ip访问
    port: 3000
  },
  css: {
    postcss: {
      plugins: []
    }
  }
})

plugins数组中就是填写需要使用的插件。下面我们编辑pxtoVewiport方法:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import {Plugin} from 'postcss'

const pxtoVewiport = (): Plugin => {
  return {
    postcssPlugin:'pxtoVewiport',
    Declaration(node){
      const value = node.value
      console.log('样式值:',value)
    }
  }
}
export default defineConfig({
  plugins: [vue()],
  server: {
    host: '0.0.0.0', //默认情况是不能用ip访问
    port: 3000
  },
  css: {
    postcss: {
      plugins: [pxtoVewiport()]
    }
  }
})

此时可以看到打印的信息:

 

也就是说我们已经拿到项目中的所有样式值,那么接下来我们就是要把所有px单位改成vw。

这里我原本自己写正则实现后,发现还会有margin: 20px 60px;这样的情况,裂开,正则太烧脑,使用程序员必备技能,CV大法,看看postcss-px-to-vewiport源码是怎么实现的,然后就拿到了这个正则:

'"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)'

ok,能用就行,那接下来就是替换过程:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import {Plugin} from 'postcss'

const getUnitRegexp = (unit: string) => {
  return new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + unit, 'g');
}

const pxtoVewiport = (): Plugin => {
  return {
    postcssPlugin:'pxtoVewiport',
    Declaration(node){
      const value = node.value
      if (value.includes('px')) {
        const pxRegexp = getUnitRegexp('px')
        node.value = node.value.replace(pxRegexp, (match) => {
          return match.replace(/(\d*\.?\d+)/g, (m) => {
            return (parseFloat(m) / 1280 * 100).toFixed(3) + 'vw'
          })
        })
        let reg = new RegExp(/px/,'ig') //在这儿把px删掉
        node.value = node.value.replace(reg,'')
      }
    }
  }
}

export default defineConfig({
  plugins: [vue()],
  server: {
    host: '0.0.0.0', //默认情况是不能用ip访问
    port: 3000
  },
  css: {
    postcss: {
      plugins: [pxtoVewiport()]
    }
  }
})

 跑起项目:

 

 这时候单位都转换成了vw,在各种大小的屏幕都是我们想看到的效果了。

继续看代码

这里的1280就是我们开发中的设计稿宽度,3是保留的位数。那么继续优化一下,将设计稿宽带和保留位数改为可传参数:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import {Plugin} from 'postcss'

const getUnitRegexp = (unit: string) => {
  return new RegExp('"[^"]+"|\'[^\']+\'|url\\([^\\)]+\\)|(\\d*\\.?\\d+)' + unit, 'g');
}
const pxtoVewiport = (viewportSize = 375,Places = 2): Plugin => {
  return {
    postcssPlugin:'pxtoVewiport',
    Declaration(node){
      const value = node.value
      if (value.includes('px')) {
        const pxRegexp = getUnitRegexp('px')
        node.value = node.value.replace(pxRegexp, (match) => {
          return match.replace(/(\d*\.?\d+)/g, (m) => {
            return (parseFloat(m) / viewportSize * 100).toFixed(Places) + 'vw'
          })
        })
        let reg = new RegExp(/px/,'ig') //在这儿把px删掉
        node.value = node.value.replace(reg,'')
      }
    }
  }
}
export default defineConfig({
  plugins: [vue()],
  server: {
    host: '0.0.0.0', //默认情况是不能用ip访问
    port: 3000
  },
  css: {
    postcss: {
      plugins: [pxtoVewiport(1280,3)]
    }
  }
})

 到里就完成了一个移动端适配的小插件。

🌟总结

基于postCss还可以做很多事情,postCss就是css界的babel,我们这里也是基本实现了postcss-px-to-vewiport插件的功能。后续还可以继续改进。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML5+JavaScript实现语音合成(文字转语音)

HTML5JavaScript实现语音合成&#xff08;文字转语音&#xff09; 本文介绍用HTML5和JavaScript实现语音合成朗读&#xff08;文字转语音&#xff09;。 Web Speech API 有两个部分&#xff1a;SpeechSynthesis 语音合成&#xff08;文本到语音 TTS&#xff09;和 SpeechReco…

汽车研发项目进度管理的挑战与优化策略

随着汽车行业的快速发展和市场竞争的加剧&#xff0c;新车型研发项目的进度管理成为车企赢得市场的关键。然而&#xff0c;由于汽车研发项目通常具有投资大、周期长、技术难度高、参与方众多等特点&#xff0c;项目进度管理面临着诸多挑战。为了提升车型研发效率、缩短研发周期…

SQL的基础语句

1、select语句 select colums from table_name 2、条件语句 #查询出查询出用户id为1和3的用户记录 IN 操作符允许我们在 WHERE 子句中规定多个值。 select * from student where id in (1,3) #查询出所有姓王的同学 模糊查询 like 通配符(% 任意多个字符 _单个字符) #下例…

使用Docker搭建本地Nexus私有仓库

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 你需要Nexus Java应用编译构建的一种主流方式就是通过Maven, Maven可以很方便的管理Java应用的…

病理验证mIF和TMA路线(自学)

目录 技术 使用配对病理切片 mIF验证 单基因使用TMA验证 技术 多重荧光免疫组化技术 (Multiplex immunohistochemical&#xff0c;mIHC) 也称作酪氨酸信号放大 (Tyramide dignal amplification&#xff0c;TSA) 技术&#xff0c;是一类利用辣根过氧化酶 (Horseradish Pero…

【数据结构(邓俊辉)学习笔记】向量01——接口与实现

文章目录 0.意图1、概述2 从数组到向量3 向量ADT接口4 Vector 模板类5 构造与析构5.1默认构造方法5.2基于复制的构造方法5.3 析构方法 0.意图 一方面是将工作学习中零星的知识点串起来&#xff0c;另一方面向量是其他数据类型的基础&#xff0c;比如栈队列等&#xff0c;所以基…

算法练习|Leetcode49字母异位词分词 ,Leetcode128最长连续序列,Leetcode3无重复字符的最长子串,sql总结

目录 一、Leetcode49字母异位词分词题目描述解题思路方法:哈希总结 二、Leetcode128最长连续序列题目描述解题思路方法:总结 三、Leetcode3无重复字符的最长子串题目描述解题思路方法:双指针法总结sql总结 一、Leetcode49字母异位词分词 题目描述 给你一个字符串数组&#xf…

linux下 Mysql8.0 离线安装

环境&#xff1a;centos7.9 MysqlL8.0.36安装包 链接&#xff1a;https://pan.baidu.com/s/1bKwHr05z8Ye82dT9tntdUA 提取码&#xff1a;3a5z 参考Centos安装MYSQL8(离线可用) 文章目录 1、解压安装2、配置启动2.1 修改配置文件2.2 mysql 启动 3、mysql 测试 1、解压安装 #…

kettle数据迁移从oracle到mysql

kettle数据迁移从oracle到mysql 下载方式1&#xff1a;方式2&#xff1a;方式3&#xff1a;下载后解压就行 二、启动三、连接数据库1.前期2.oracle数据库3.mysql数据库 四、迁移一、配置表输入参数1.在【转换】里面&#xff0c;选择【核心对象】&#xff0c;选中将【表输入】拖…

springboot 批量下载文件, zip压缩下载

一、使用hutool 工具类 效果&#xff1a;下载速度可以 1、依赖&#xff1a;hutool <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version> </dependency>2、调用方式 im…

Rust 使用结构体组织相关联的数据

目录 结构体的定义和实例化 使用字段初始化简写语法使用结构体更新语法从其他实例创建实例使用没有命名字段的元组结构体来创建不同的类型没有任何字段的类单元结构体结构体示例程序 通过派生 trait 增加实用功能方法语法 定义方法带有更多参数的方法关联函数多个 impl 块本文有…

向量的点积和叉积的几何意义

1. 点积 点积(dot product)&#xff0c;又称标量积&#xff08;scalar product&#xff09;。结果等于。 可用于 判断的是否垂直求投影长度求向量是抑制作用还是促进作用 2. 叉积 叉积(cross product)&#xff0c;又称为向量积(vector product)。模长等于&#xff0c;方向…

简单学量化——pandas的应用26——sort_values函数5

简单学量化——pandas的应用26——sort_values函数5 sort_values是pandas中的排序函数&#xff0c;语法如下&#xff1a; DataFrame.sort_values(by,axis0,ascendingTrue,inplaceFalse,kindquicksort,na_positionlast, ignore_indexFalse,keyNone) 前面我们学习了by、axis、a…

嵌入式linux中uboot的启动过程分析

之前对这个uboot的源码了解有些许遗忘。最近做AVB校验,需要uboot到kernel的这个过程。这里再复习一下。 与大多数BootLoader一样,uboot的启动过程分为BL1和BL2两个阶段。 BL1阶段通常是开发板的配置等设备初始化代码,需要依赖依赖于SoC体系结构,通常用汇编语言来实现; …

Java | Leetcode Java题解之第43题字符串相乘

题目&#xff1a; 题解&#xff1a; class Solution {public String multiply(String num1, String num2) {if (num1.equals("0") || num2.equals("0")) {return "0";}int m num1.length(), n num2.length();int[] ansArr new int[m n];for…

转行做银行测试,需要了解哪些?

在这个内卷严重的时代&#xff0c;银行的业务不断增加&#xff0c;随着软件信息化的要求越来越高&#xff0c;银行对软件测试人员也提出了非常高的要求。 银行的软件测试是针对银行的软件系统&#xff08;如柜面系统、信贷系统&#xff09;和银行专用设备&#xff08;如ATM机、…

新手学习C++常去的网站!

1、cppreference cppreference 是一个免费学习 C 的网站&#xff0c;你也可以把它看成是一个 C 学习手册&#xff0c;内容相当丰富&#xff0c;涵盖几乎所有 C 的知识点&#xff0c;除此以外&#xff0c;它内容更新很快&#xff0c;紧随 C 标准&#xff0c;目前已经到 C23 的内…

【系统架构师】-案例考点(三)

1、信息系统架构ISA设计 四种架构模型&#xff1a; 1&#xff09;单机应用 2&#xff09;客户机/服务器模式&#xff1a;两层、三层C/S、B/S模型、MVC模式等 3&#xff09;面向服务架构SOA 4&#xff09;企业数据交换总线&#xff1a;不同企业应用之间通过信息交换的公共频…

Java入门四步走

1. 简单的入门语法&#xff1a; 1.1 数据类型&#xff1a; 基本数据类型&#xff1a; 整数类型 —— byte、short、int、long, 浮点类型 —— float、double 字符类型 —— char 布尔类型 —— boolean 引用数据类型&#xff1a; 接口&#xff08;interface&#xff09;、数…

解决在linux中执行tailscale up却不弹出验证网址【Tailscale】【Linux】

文章目录 问题解决提醒 问题 最近有远程办公需求&#xff0c;需要连接内网服务器&#xff0c;又不太想用todesk&#xff0c;于是找到一个安全免费可用的Tailscale Best VPN Service for Secure Networks&#xff0c;在windows中顺利注册账号后&#xff0c;登陆了我的windows …