最近做的一个官网项目,pc端要求适配平板和手机端,项目使用vue+vite搭建。想到一个插件,postcss,本文主要使用这个插件结合一些其他方案(媒体查询)来达到项目需求。
简单说一下postcss这个插件:它可以自动将px转化成rem, 也就意味着我们可以不再使用之前自己写的转化了,在css中直接写px就可以了。
还使用到了一个插件:amfe-flexible 是阿里移动前端团队开发的一个库,用于动态设置元素的font-size值。 使用amfe-flexible后,就不需要自己编写媒体查询来改变font-size了,amfe-flexible会自动根据设备的屏幕宽度来调整font-size
使用方法:
1.首先安装插件
js
npm install amfe-flexible --save
npm install postcss-pxtorem --save
- 新建rem.js文件,
js
// rem 函数
function setRem() {
const defalutWidth = 1920 // 默认宽度
const defalueScale = 1 // 默认比例关系
let defalutFontSize = 192 // 默认字体大小
const getWidth = window.innerWidth // 获取屏幕的宽度
let currentScale = getWidth / defalutWidth // 计算当前的屏幕大小和默认宽度之间的比例
// 防止缩放太小
if (currentScale < 0.85 && getWidth > 1024) {
currentScale = 0.855
}
// 当前为平板时
if (getWidth <= 1024) {
defalutFontSize = defalutFontSize * 2
}
// 计算的宽度比例关系 再 * 默认的字体大小,获取计算的字体大小
const currentFontSize = (currentScale / defalueScale) * defalutFontSize
document.documentElement.style.fontSize = currentFontSize + 'px'
}
// 调用方法
setRem()
// 监听窗口在变化时重新设置跟文件大小
window.onresize = function () {
setRem()
}
3.再main.js中引入。
js
import 'amfe-flexible'
import '@/utils/rem.js'
4.然后再到vite.conig.js中去配置postCssPxToRem。
js
import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
// 引入postCssPxToRem
import postCssPxToRem from 'postcss-pxtorem'
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
const { VITE_APP_ENV } = env
return {
plugins:[
vue()
],
css: {
postcss: {
plugins: [
postCssPxToRem({
// 自适应,px>rem转换
rootValue: 192, //pc端建议:192,移动端建议:75;设计稿宽度的1 / 10
propList: ['*', '!border'], // 除 border 外所有px 转 rem // 需要转换的属性,这里选择全部都进行转换
selectorBlackList: ['.norem'],
// 过滤掉norem-开头的class,不进行rem转换,这个内容可以不写
unitPrecision: 5, // 转换后的精度,即小数点位数
replace: true, // 是否直接更换属性值而不添加备份属性
mediaQuery: false, // 是否在媒体查询中也转换px为rem
minPixelValue: 0,// 设置要转换的最小像素值
})
]
}
}
}
});
以上基本就配置完了。开发时正常写px就行了。会自动转换的。但是这个肯定有局限性,部分模块的样式还是得用到element-ui中栅格布局。
为了解决部分需求,比如pc导航栏和移动端导航栏不一样。或者部分样式需要改变。还是得写两个导航栏,根据屏幕大小来判断使用那个。 样式的话就使用媒体查询来进行样式设置。
监听屏幕宽度设置导航栏:封装组件navbar
js
<div class="navbar-container">
<div class="big-navbar" v-if="!isMobile"></div>
<div class="small-navbar" v-else></div>
</div>
<script setup>
const isMobile = ref(window.innerWidth < 768);
const updateWindowSize = () => {
isMobile.value = window.innerWidth < 768;
};
// 使用watch来监听窗口大小变化(也可以使用其他方式)
watch(() => window.innerWidth,(newVal, oldVal) => {
updateWindowSize();
},
{ immediate: false }
);
onMounted(() => {
window.addEventListener("resize", updateWindowSize);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", updateWindowSize);
});
</script>
<style lang="scss" scoped>
// 也可以使用媒体查询来设置一些样式
@media (max-width: 768px) {
.navbar {
background: rgb(255, 255, 255);
}
}
</style>
以上是一个简单的导航栏组件案例
页面效果如果想要自定义调整的话也是使用媒体查询来进行调整,但是注意一点,在vite.conig.js配置的postcss中必须将mediaQuery设置为false才起作用,否则媒体查询是不生效的
放一段简单的媒体查询css
css
/* 针对平板设备的样式 */
@media screen and (max-width: 1024px) {
.container{
background:red;
}
}
/* 当屏幕宽度小于600px时 移动端 */
@media screen and (max-width: 600px) {
.container{
background:yellow;
}
}
尺寸大小可以根据需求进行自定义设置