移动项目 一般是陪的是手机和平板,有可能也会需要适配电脑客户端,介绍下我的思路
1. 基于postcss 去做vw 的适配,这里需要做文件的拆分,要不然无法区分viewportwidth
- 对于同一个页面进行UI拆分,js 逻辑共用原则, 然后 postcss 通过文件名来设置不同的viewportwidth(index.vue index-pad.vue index.js 公共逻辑存放)
- 上面的做法不利于组建的拆分,一旦拆分组件多了就会很复杂
2. JS 和 scss 结合判断
- 首先我们写一个 scss 转换的函数 来转换 手机和平板的尺寸
$phoneViewport: 375;
$padViewport: 800;
@function phone($px) {
@return calc(#{$px * 100vmin} / #{$phoneViewport});
}
@function pad($px) {
@return calc(#{$px * 100vmin} / #{$padViewport});
}
- 然后写一个JS 实现同样的功能 获取设备类型,转换尺寸
import { useWindowSize } from '@vant/use' //vant获取屏幕尺寸,可自行替换
import { ref, watch } from 'vue'
// phone 手机 pad 平板 设备类型
export type ScreenTypeReutrn = 'phone' | 'pad'
// 此尺寸对应 pxToVw.scss 里面的尺寸,需要保持一致
const viewport: Record<ScreenTypeReutrn, number> = {
phone: 375,
pad: 800,
}
//如果方法不准确可以自己调整,如果原生webview可以提供js变量来区分,就是用 js 来判断
export const screenType = (): ScreenTypeReutrn => {
const big = window.matchMedia('(min-width: 550px) and (min-height: 550px)').matches
if (!big) {
return 'phone'
} else {
return 'pad'
}
}
export const ScreenTypeHook = () => {
const type = ref<ScreenTypeReutrn>(screenType())
const { width, height } = useWindowSize()
watch([width, height], () => {
type.value = screenType()
})
return {
type,
}
}
// 可以根据屏幕类型传入不同的值 pxToVw(screenType() === ' phone' ? 10 : 15)
export const pxToVw = (num: number): string => {
const type = screenType()
const tmp = num / viewport[type]
return `${(tmp * 100).toFixed(6)}vmin`
}
export const phone = (num: number): string => {
const tmp = num / viewport['phone']
return `${(tmp * 100).toFixed(6)}vmin`
}
export const pad = (num: number): string => {
const tmp = num / viewport['pad']
return `${(tmp * 100).toFixed(6)}vmin`
}
export const calcSize = (phone: number, pad: number) => {
const type = screenType()
return type === 'phone' ? phone : pad
}
<template>
<div :device-type="deviceType" class="page">
<van-nav-bar title="屏幕适配" fixed />
<div class="test">测试字体</div>
<div class="test2"></div>
</div>
</template>
<script setup lang="ts">
import { ScreenTypeHook } from '@/fitScreen'
const deviceType = ScreenTypeHook().type
</script>
<style scoped lang="scss">
.page[device-type='phone'] {
font-size: phone(16);
.test {
color: red;
}
.test2 {
margin-top: phone(8);
background-color: red;
width: 80vw;
height: 20vh;
}
}
.page[device-type='pad'] {
font-size: pad(20);
.test {
color: purple;
}
.test2 {
margin-top: pad(8);
background-color: purple;
width: 40vw;
height: 40vh;
}
}
</style>
- 第三方的css 修改 可以直接在app.vue 中全局使用 scss函数一定要在 #{} 里面使用,否则方法无效
<div class="vantfit" :deviceType v-show="showPage">
.vantfit[deviceType='phone'] {
--van-cell-font-size: #{phone(15)};
--van-cell-line-height: #{phone(24)};
--van-cell-vertical-padding: #{phone(10)};
--van-cell-icon-size: #{phone(15)};
--van-nav-bar-icon-color: '#ffffff';
--van-nav-bar-height: #{phone(46)};
--van-line-height-lg: #{phone(46)};
--van-nav-bar-arrow-size: #{phone(16)};
--van-nav-bar-title-font-size: #{phone(18)};
--van-nav-bar-title-text-color: '#222222';
--van-font-size-md: #{phone(16)};
}
.vantfit[deviceType='pad'] {
--van-cell-font-size: #{pad(15)};
--van-cell-line-height: #{pad(24)};
--van-cell-vertical-padding: #{pad(10)};
--van-cell-icon-size: #{pad(15)};
--van-nav-bar-icon-color: '#ffffff';
--van-nav-bar-height: #{pad(60)};
--van-line-height-lg: #{pad(60)};
--van-nav-bar-arrow-size: #{pad(16)};
--van-nav-bar-title-font-size: #{pad(30)};
--van-nav-bar-title-text-color: '#222222';
--van-font-size-md: #{pad(16)};
}
如果要要适配pc 可以自己在加一个屏幕尺寸判断或者
网友评论