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

本文介绍了如何在Vite和Vue3项目中集成并使用PostCSS的px-to-viewport插件,实现响应式设计,将px单位转换为vw,以适应不同屏幕尺寸。作者通过逐步示例展示了从创建项目、布局调整到编写并配置插件的整个过程。
摘要由CSDN通过智能技术生成

🌟前言

        目前前端实现移动端适配方案千千万,眼花缭乱各有有缺,但目前来说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插件的功能。后续还可以继续改进。

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue.js是一种流行的JavaScript框架,用于构建现代Web应用程序,如移动应用程序和单页应用程序。使用Vue.js开发移动应用程序时,经常需要使用各种UI组件。其中,el-table是一个常用的表格组件,可以方便地展示数据。 移动端的el-table组件需要考虑到手机屏幕的大小和触摸操作的交互设计。因此,我们需要手写实现一套适用于移动端的el-table组件。 首先,我们需要设计一个表格结构,包括表头、表体和表尾。在移动端,由于屏幕较小,通常需要使用滚动条来滚动表体。因此,我们需要给表格设置固定高度,并设置overflow: auto属性。 其次,我们需要实现表格的数据绑定和分页功能。通常情况下,移动端的数据量较小,因此我们可以一次性将所有数据加载到前端进行分页展示。我们可以使用分页器组件来实现分页,并通过计算分页数据来动态更新表格数据。 最后,我们需要考虑到表格的交互设计。在移动端,我们通常使用左右滑动来进行某些操作。例如,我们可以使用左滑删除删除某一行数据,右滑编辑某一行数据。此外,我们还可以添加筛选功能和搜索功能,方便用户快速查找需要的数据。 总之,Vue.js手写实现移动端el-table组件需要考虑到表格结构、数据绑定、分页功能和交互设计等方面。通过仔细设计和实现,我们可以创建出易用性、高效性和美观性的el-table组件,满足用户需要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琢鸣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值