PC端的一些简单适配
不同比例的屏幕需要展示的内容一样
16:9
24:9
32:9
的屏幕比例需要显示同样的内容
主要是使用的是rem
布局, 这里通过调节不同分辨率的时候, 左边盒子和中间盒子的宽度比例关系保持不变
- 依赖模块
postcss-pxtorem
Github地址, 安装该模块时, 需要先安装postcss
模块,使用vue脚手架创建的项目中自带了postcss
模块,也可以不用额外安装
注意这里使用的不是最新的postcss-pxtorem
而是使用 5.1.1的版本
yarn add postcss postcss-pxtorem@5.1.1
在与src
同级的目录下添加postcss.config.js
文件
module.exports = {
plugins: {
autoprefixer: {},
// flexible配置
'postcss-pxtorem': {
rootValue: 100,
unitPrecision: 5,
propList: ['*'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
minPixelValue: 0,
exclude: /node_modules/i
}
}
}
rootValue: 100
主要是因为是为了适配PC
端的大小
- 还需要监听屏幕变化来动态赋值
html
的font-size
, 这里设置的默认宽度是1920
的屏幕分辨率, 默认的字体大小是100
, 而且只是简单计算了宽度的比例关系
export const flexView = () => {
const defalutWidth = 1920 // 默认宽度
const defalueScale = 1 // 默认比例关系
const html = document.querySelector('html')
let defalutFontSize = 100 // 默认字体大小
const resizeFunc = () => {
const getWidth = window.innerWidth // 获取屏幕的宽度
const currentScale = getWidth / defalutWidth // 计算当前的屏幕大小和默认宽度之间的比例
// 计算的宽度比例关系 再 * 默认的字体大小,获取计算的字体大小
const currentFontSize = (currentScale / defalueScale) * defalutFontSize
html.style.fontSize = currentFontSize + 'px'
}
resizeFunc()
window.addEventListener('resize', resizeFunc)
}
- 在
main.js
文件中导入
...
import { flexView } from '@/utils'
flexView()
...
固定比例的屏幕
比如已知的屏幕比例16:9
, 这个时候缩放屏幕, 保持整体内容的不变, 但是窗口两边会有白边
主要是使用了transfrom:scale()
的属性, 通过监听屏幕变化动态设置
这里为了方便, 直接在App.vue
中写的代码
html
部分, 需要有一个全局的盒子包裹内容
<template>
<div id="app">
<div id="big-screen">
<router-view />
</div>
</div>
</template>
这里使用1920*1080
的比例进行处理, 注意 css
的样式也需要保持一致
<script>
// * 设计稿尺寸(px)
const baseWidth = 1920
const baseHeight = 1080
// * 需保持的比例(默认1.77778)
const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
export default {
data() {
return {
// * 定时函数
drawTiming: null
}
},
mounted () {
this.calcRate()
window.addEventListener('resize', this.resize)
},
beforeDestroy () {
window.removeEventListener('resize', this.resize)
},
methods: {
calcRate () {
const appRef = document.querySelector('#big-screen')
if (!appRef) return
// 当前宽高比
const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
if (appRef) {
// 第一种方式
let scaleNum = 1
if (currentRate > baseProportion) {
// 表示分辨率变大,可能是高度变小
// scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
// scale.height = (window.innerHeight / baseHeight).toFixed(5)
scaleNum = (window.innerHeight / baseHeight).toFixed(5)
} else {
// 表示分辨率变小,可能是宽度变小
// scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
scaleNum = (window.innerWidth / baseWidth).toFixed(5)
}
/**
* 也可以直接使用 第二种方式
* const scaleWidth = window.innerWidth / baseWidth
const scaleHeight = window.innerHeight / baseHeight
let scaleNum = scaleWidth < scaleHeight ? scaleWidth : scaleHeight
*/
appRef.style.transform = `scale(${scaleNum}) translate(-50%, -50%)`
}
},
resize () {
clearTimeout(this.drawTiming)
this.drawTiming = setTimeout(() => {
this.calcRate()
}, 200)
}
}
}
</script>
这里的方式都是在屏幕分辨率变化的时候, 通过
transform
改变scale
的大小变化
要想保证内容都在页面之中, 需要使用定位
#app {
overflow: hidden;
position: relative;
width: 100vw;
height: 100vh;
background-color: #080f34;
#big-screen {
position: absolute;
left: 50%;
top: 50%;
transform-origin: left top;
width: 1920px;
height: 1080px;
background-color: pink;
}
}
使用vw/vh
进行适配
什么是视口?
在桌面端,视口指的是在桌面端,指的是浏览器的可视区域
视口单位中的“视口”,桌面端指的是浏览器的可视区域
根据CSS3
规范,视口单位主要包括以下4个:
1.vw:1vw等于视口宽度的1%。
2.vh:1vh等于视口高度的1%。
3.vmin:选取vw和vh中最小的那个。
4.vmax:选取vw和vh中最大的那个。
vh / vw
:相对于视口的高度和宽度,而不是父元素的(CSS百分比是相对于包含它的最近的父元素的高度和宽度)。1vh
等于1/100的视口高度,1vw
等于1/100的视口宽度。
比如:浏览器高度1080px
,宽度为1920px
, 1 vh = 1080px/100 = 10.8 px,1vw = 1920px/100 =19.2 px
。
vmax
相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax
。
vmin
相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin
。
进行适配
借助sass / sass-loader
进行处理(这里没有使用node-sass
主要是因为在开发过程中遇到了未知的bug)
提一嘴, sass/node-sass/dart-sass
都是用来处理sass/scss
编译为css
的工具 参考地址
区别在于
1. sass
是由 ts调用 dart-sass
实现的工具类,来编译 sass
(以前是由单纯的 ts实现的)
2. dart-sass
是由 dart
实现的,通过 dart vm
运行 dart
是编译 sass
(在 npm 可以看到该包已不被开放下载了)
3. node-sass
是由 node
调用 底层 c++ 实现的 libsass
来编译 sass
最大的区别在于深度选择器
sass/dart-sass
使用::v-deep 和 :deep()
进行处理
node-sass
使用/deep/
进行处理
回到正题, 安装依赖yarn add sass@1.53.0 sass-loader@8.0.2 -D
指定版本是因为高版本部分需要依赖node
的高版本
- 新建
utils.scss
文件,用来计算vh/vw
math.div是用来计算的
重要的一点是, 需要确定设计稿的宽高
@use "sass:math";
// 默认的宽度
$baseWidth: 1920px;
// 默认的高度
$baseHeight: 1080px;
@function vw($px) {
@return math.div($px, $baseWidth) * 100vw;
}
@function vh($px) {
@return math.div($px, $baseHeight) * 100vh;
}
- 在
vue.config.js
中配置全局导入scss
文件,这样就不用每次都手动导入官方地址
module.exports = {
css: {
loaderOptions: {
/**
* https://cli.vuejs.org/zh/guide/css.html#%E5%90%91%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8-loader-%E4%BC%A0%E9%80%92%E9%80%89%E9%A1%B9
* @/ 是 src/ 的别名
所以这里假设你有 `src/variables.sass` 这个文件
注意:在 sass-loader v8 中,这个选项名是 "prependData"
*
*/
scss: {
prependData: `@import "~@/style/utils.scss";`
}
}
}
}
- 使用
div {
font-size: vh(30px);
color: #fff;
height: vh(100px);
}
- 不管页面分辨率如何变化, 给定的
vw/vh
都是固定的, 但是元素还是会跟随变化