在开发移动端的时候需要适配各种机型,有大的,有小的,我们需要一套代码,在不同的分辨率适应各种机型。
因此我们需要设置meta标签
<meta name="viewport" content="width=device-width, initial-scale=1.0">
圣杯布局
移动设备具有各种不同的屏幕尺寸和分辨率,例如智能手机和平板电脑。为了提供更好的用户体验,网页需要根据设备的屏幕宽度进行自适应布局。如果不设置width=device-width,移动设备会按照默认的视口宽度(通常是较宽的桌面屏幕)来渲染网页,导致网页内容在移动设备上显示不正常,可能出现内容被截断或需要水平滚动的情况
然后我们实现一个经典的圣杯布局
圣杯布局:在CSS中,圣杯布局是指两边盒子宽度固定,中间盒子自适应的三栏布局,其中,中间栏放到文档流前面,保证先行渲染
<template>
<div>
<header>
<div>左</div>
<div>中</div>
<div>右</div>
</header>
</div>
</template>
<script setup lang="ts"></script>
<style scoped lang="scss">
header {
display: flex;
justify-content: space-between;
div {
height: 50px;
color: white;
text-align: center;
line-height: 50px;
}
div:nth-child(1) {
width: 100px;
background: red;
}
div:nth-child(2) {
flex: 1;
background: green;
}
div:nth-child(3) {
width: 100px;
background: blue;
}
}
</style>
自适应
发现px是相对单位固定的,无法进行自适应,不会随着屏幕尺寸的改变而改变。
而rem 是根据html的font-size 进行缩放的,可以进行自适应,缺点就是需要计算每个屏幕大小所对应的font-size
vw vh是相对viewport 视口的单位,配合meta标签可以直接使用,无需计算
1vw=1/100视口宽度
1vh=1/100视口高度
当前屏幕视口是375像素,1vw就是3.75像素
vite 官方文档 共享选项post Css
*[注意]: vw和vh(viewport ) 与 百分比是不一样的
- 百分比是相对于父元素的
- viewport 是相对于视口
postCss 提供了 把Css 转换AST的能力,类似于Babel,为此我们可以编写一个插件用于将px转换为vw
postCss官网
postCss 提供了 把Css 转换AST的能力,类似于Babel,为此我们可以编写一个插件用于将px转换为vw
vue 项目 使用postCss
- 在项目根目录总新建一个plugins文件夹创建postcss-px-to-viewport.ts文件
// 编写 postcss 插件 vite内置了postCss 无需安装
import { Plugin } from 'postcss'
const Option = {
viewPortWidth: 375,// UI设计稿的宽度 给多少写多少 一般默认375
}
interface Options {
viewPortWidth?: number
}
export const PostCssPxToViewport = (options: Options = Option): Plugin => {
const opt = Object.assign({}, Option, options)
return {
postcssPlugin: 'postcss-px-to-viewport',
// 拿到所有css节点的钩子函数
Declaration(node) {
// px 转换成 vw
const value = node.value;
if (value.includes('px')) {
const num = parseFloat(value)// 考虑到有小数
node.value = `${((num / opt.viewPortWidth) * 100).toFixed(2)}vw` //转换之后的值
}
}
}
}
- 然后在tsconfig.node.json
includes 配置 “plugins/**/*”,
compilerOptions 配置 noImplicitAny:false
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"noImplicitAny":false
},
"include": ["vite.config.ts","plugins/**/*"]
}
- 配置 vite.config.ts文件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { PostCssPxToViewport } from './plugins/postcss-px-to-viewport'
export default defineConfig(({ command }) => {
return {
plugins: [vue()],
css: {
postcss: {
plugins: [PostCssPxToViewport()]
}
}
}
})
设置全局的字体大小或者全局背景颜色切换
第一种方法使用vueUse插件:
-
安装vueUse插件
npm i @vueuse/core -
定义Css变量
-
点击切换字体大小
<template>
<div>
<header>
<div>左</div>
<div>中</div>
<div>右</div>
</header>
<div>
<button @click="change(36)">大</button>
<button @click="change(24)">中</button>
<button @click="change(14)">小</button>
</div>
</div>
</template>
<script setup lang="ts">
import { useCssVar } from "@vueuse/core"
// 做全局的字体大小 添加这个变量就可以了
// var(--size) 任何页面都可以用 挂在到html
const change = (str: number) => {
const size = useCssVar("--size")
size.value = `${str}px`
}
</script>
<style scoped lang="scss">
:root {
--size: 14px;
}
header {
display: flex;
justify-content: space-between;
font-size: var(--size);
div {
height: 50px;
color: white;
text-align: center;
line-height: 50px;
}
div:nth-child(1) {
width: 100px;
background: red;
}
div:nth-child(2) {
flex: 1;
background: green;
}
div:nth-child(3) {
width: 100px;
background: blue;
}
}
</style>
第二种方法:不使用插件运用 useCassVar的底层原理
<template>
<div>
<header>
<div>左</div>
<div>中</div>
<div>右</div>
</header>
<div>
<button @click="change(36)">大</button>
<button @click="change(24)">中</button>
<button @click="change(14)">小</button>
</div>
</div>
</template>
<script setup lang="ts">
const change = (num: number) => {
document.documentElement.style.getPropertyPriority("--size")
document.documentElement.style.setProperty("--size", num + "px")
}
</script>
<style scoped lang="scss">
:root {
--size: 14px;
}
header {
display: flex;
justify-content: space-between;
font-size: var(--size);
div {
height: 50px;
color: white;
text-align: center;
line-height: 50px;
}
div:nth-child(1) {
width: 100px;
background: red;
}
div:nth-child(2) {
flex: 1;
background: green;
}
div:nth-child(3) {
width: 100px;
background: blue;
}
}
</style>