Vue3 (develop h5 adaptation)

When developing the mobile terminal, it needs to adapt to various models, some large and some small. We need a set of codes to adapt to various models at different resolutions.

So we need to set the meta tag

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

Mobile devices come in a variety of different screen sizes and resolutions, such as smartphones and tablets. In order to provide a better user experience, web pages need to be adaptively laid out according to the screen width of the device. If it is not set width=device-width, the mobile device will render the webpage according to the default viewport width (usually a wider desktop screen), which will cause the webpage content to be displayed abnormally on the mobile device, and the content may be truncated or require horizontal scrolling

Then we implement a classic圣杯布局

Holy Grail Layout : In CSS, Holy Grail Layout refers to a three-column layout in which the width of the boxes on both sides is fixed and the middle box is self-adaptive. Among them, the middle column is placed in front of the document flow to ensure that it is rendered first;

holy grail layout

<template>
  <div>
    <header>
      <div>left</div>
      <div>center</div>
      <div>right</div>
    </header>
  </div>
</template>
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;
  }
}

Looks fine on a normal phone

image.png

But if it is a small mobile phone, there will be problems and it will be very crowded.

image.png

adaptive

It is found that px is fixed relative to the unit, cannot be adaptive, and will not change as the screen size changes.

Instead, remit is scaled according to the font-size of html, which can be adaptive. The disadvantage is that the font-size corresponding to each screen size needs to be calculated

vw vhIt is a unit relative to the viewport, and can be used directly with the meta tag without calculation

1vw=1/100 viewport width

1vh=1/100 viewport height

The current screen viewport is 375 pixels, 1vw is 3.75 pixels

Now I know what unit to use, but it is very troublesome for us to convert vw according to px, can it be converted automatically? ? ?

postCss

https://cn.vitejs.dev/config/shared-options.html#css-postcss

Found that vite has built-inpostCss

https://www.postcss.com.cn/

postCss provides the ability to convert Css to AST, similar to Babelthis, we can write a plug-in to convert px to vw

npm init vue

Build a vue project

Create a plugins folder in the root directory and create two new files pxto-viewport.ts type.ts

Then configure in the includes of tsconfig.node.json"plugins/**/*",

compilerOptions placement noImplicitAny:false

image.png

pxto-viewport.js

import type {
    
     Options } from './type'
import type {
    
     Plugin } from 'postcss'
const defaultOptions = {
    
    
    viewPortWidth: 375,
    mediaQuery: false,
    unitToConvert:'px'
}
export const pxToViewport = (options: Options = defaultOptions): Plugin => {
    
    
    const opt = Object.assign({
    
    }, defaultOptions, options)
    return {
    
    
        postcssPlugin: 'postcss-px-to-viewport',
        //css节点都会经过这个钩子
        Declaration(node) {
    
    
            const value = node.value
            //匹配到px 转换成vw
            if (value.includes(opt.unitToConvert)) {
    
    
                const num = parseFloat(value)
                const transformValue = (num / opt.viewPortWidth) * 100
                node.value = `${
      
      transformValue.toFixed(2)}vw` //转换之后的值
            }    
        },
    }
}

type.ts

export interface Options {
    
    
    viewPortWidth?: number;
    mediaQuery?: boolean;
    unitToConvert?: string;
}

vite.config.ts imports our written plugins

  css:{
    
    
     postcss:{
    
    
         plugins:[
            pxToViewport()
         ]
     },
  },

image.png

In this case, all kinds of screens are almost the same.

extra little knowledge

For example, what should I do if I want to add a font size that can be set globally or a global background color switch?

  1. Install vueUse
npm i  @vueuse/core
  1. Define CSS variables
:root {
    
    
  --size: 14px;
}
div {
    
    
    height: 50px;
    color: white;
    text-align: center;
    line-height: 50px;
    font-size: var(--size);
}
  1. toggle font size
  <div>
      <button @click="change(36)"></button>
      <button @click="change(24)"></button>
      <button @click="change(14)"></button>
    </div>
import {
    
     useCssVar } from '@vueuse/core'
const change = (str: number) => {
    
    
  const color = useCssVar('--size')
  color.value = `${
      
      str}px`
}

The underlying principle of useCssVar is

document.documentElement.style.getPropertyValue('--size')
Read is get, setting is set, just use this css variable for the page you want to switch, and use it if you want to store it persistentlylocalstorage

image.png

image.png

Guess you like

Origin blog.csdn.net/qq1195566313/article/details/132526254