GoView潜伏的另一隐患: 外层容器transform之后, 不同分辨率下, 内部组件存在拉伸问题前言 由于需要兼
前言
由于需要兼容不同的屏幕分辨率, GoView在外层容器上设置了transform, 导致的后果是: 内部所有组件皆被拉伸, 这并不是用户希望看到的.
为了彻底解决该问题, 我决定删除该外层容器, 使用postcss-px-to-viewport
解决不同屏幕分辨率下, 组件的宽高、位置等样式问题.
正文
引入postcss-px-to-viewport
在项目根目录下, 新增postcss.config.js
文件, 其内容如下
module.exports = {
plugins: {
'postcss-px-to-viewport': {
unitToConvert: 'px', // 需要转换的单位
viewportWidth: 1920, // 设计稿的视口宽度
unitPrecision: 5, // 转换后保留的小数位数
propList: ['*'], // 需要进行转换的 CSS 属性,* 表示所有
viewportUnit: 'vw', // 指定转换后的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: ['.ignore'], // 指定不转换为视口单位的类
minPixelValue: 1, // 小于或等于 1px 不进行转换
mediaQuery: false, // 允许在媒体查询中转换 px
exclude: [/node_modules\/(?!naive)/] // 忽略某些文件夹或文件
}
}
}
此处将viewportWidth
设置为1920
, 这并非意味着仅仅只能匹配1920
宽度的分辨率, 相反postcss-px-to-viewport
以此为基准, 在不同分辨率下, 做vw
的自动转换.
举个简单的例子, 1920
时, 你看到的字体大小为28px
, 当为2880
时, 字体大小会自动调整为42px
这种自动转换的前提是, 字体大小单位必须为vw
.
修改vite.config.ts
在vite.config.ts
文件内, 增加如下配置
...
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd())
return {
css: {
...
postcss: './postcss.config.js'
},
}
})
将组件的left
、top
等px
转换为vw
或vh
我们只需处理预览页面下, 各个组件容器的位置、宽高.
let viewportWidth = window.innerWidth;
let viewportHeight = window.innerHeight;
let aspectRatio = viewportWidth / viewportHeight
// 设置位置
export const getComponentAttrStyle = (attr: AttrType, index: number) => {
let h = 100 - (attr.h * aspectRatio / 1920) * 100
h = h < 0 ? 0 : h
const minTop = Math.min(h, (attr.y / 1080) * 100)
const componentStyle = {
zIndex: index + 1,
left: pxToVw(attr.x),
top: minTop + 'vh'
}
return componentStyle
}
上面的minTop
是为了处理, 在3880*1080
分辨率时, 处于底部的部分组件会存在显示不全的问题.
(attr.h * aspectRatio / 1920) * 100
是为了处理长宽相同的组件, 位于页面底部时存在遮挡的问题. (attr.h / 1920) * 100
是将当前组件的高度像素转换为vw
, *aspectRatio
是将vw
转换为实际的vh
值.
Math.min(h, (attr.y / 1080) * 100)
从两者之间选取最小的top
值
我给红框组件单独设置了height: v-bind('pxToVw(h)');
, 其他组件的高度默认使用vh
. 因为若该组件的高度设置为vh
, 则宽高会存在不一致的情况, 即在3880 * 1080
的分辨率下时, 该组件会呈椭圆形, 为了保证组件宽高一致, 都需采用vw
单位.
将组件内联样式里的px
转换为vw
或vh
postcss-px-to-viewport
只能处理静态文件里的px
转换, 组件内联样式里的px
或变量px
需手动转换为vw
或vh
, 代码如下所示
export function pxToVw(px: number) {
return `${(px / 1920) * 100}vw`;
}
export function pxToVh(px: number) {
return `${(px / 1080) * 100}vh`;
}
<template>
<div class="tables-basic">
<n-data-table
size="small"
:style="`
width: ${pxToVw(w)};
height: ${pxToVh(h)};
font-size: ${pxToVw(option.style.fontSize)};
`"
</div>
</template>
<script setup lang="ts">
import { pxToVw, pxToVh } from '@/utils'
</script>
<style lang="scss" scoped>
@include deep() {
.n-base-selection-label {
height: v-bind('pxToVh(h)');
display: flex;
align-items: center;
}
.n-base-selection-tag-wrapper {
padding: v-bind('`${pxToVh(paddingY)} ${pxToVw(paddingX)}`');
}
}
</style>
尾声
经测试, 在不同的屏幕分辨率下, 各个组件皆能正常显示, 至此成功地解决了预览页面中组件的拉伸问题, 感兴趣的小伙伴们欢迎在下方留言、点赞或关注哦~
转载自:https://juejin.cn/post/7423582965215100963