手拉手带你用 Vue3 + VantUI 写一个移动端脚手架 系列二 (页面布局与兼容)

简介: 用 Vue3 + VantUI 写一个移动端脚手架

261890fed8013949a9dbc23f1b41188.png

项目地址(持续迭代中):github.com/jyliyue/vit…

系列文章:

前言

上一篇已经就项目结构和常用插件的配置给大家做了简单的介绍,本篇主要会从移动端页面布局常见兼容问题展开做讲解,废话不多,马上开始!

页面容器组件

思路

移动端页面一般采用最外层容器固定宽高,内部使用 弹性布局flex 处理,移动端的样式布局建议大家能使用 flex 弹性就使用 flex ,尽量少使用 calc(XX) 计算属性,一方面使用 calc 会有一定的 性能损耗,另一方面看过很多案例使用 calc 通常是配合 100vh 计算页面某一区域的高度,这两者加起来很多时候就会让页面在不同的屏幕下表现不一致,所以为了降低日后的维护负担,还是尽量强迫自己学着用 flex 花式解决布局问题 ^_^

为了保持所有页面布局的一致性,也为了日后维护时能统一处理一些兼容性问题,该项目统一封装 组件作为页面容器

关于 100 vh 与 html, body { height: 100% }

首先,这两种方法大家应该都很熟悉,都可以让我们获取一个全屏元素,大家在写代码时也时不时会用到,但是在一些场景下却会产生一些不可预料的问题,所以在选择方案上很重要,这是移动端布局的基础,打好地基很重要,这里我们先看下淘宝的做法

01a487f8c12c57a619efdee60407163.png

这里大家应该就有疑问了,为什么不使用 100vh 而是使用 html, body { height: 100% }

  • 首先我们来了解下 100vh
    1vh单位代表了屏幕可视区域的1% ,vh 获取的是视窗高度,100vh 在开发中浏览器预览时页面占据整个可视区域没有任何问题
    但是,核心问题是移动浏览器(Chrome和Safari)有一个 “ 特性 ” ,地址栏有时可见,有时隐藏,改变了视口的可见大小。这些浏览器没有将100vh的高度调整为视口高度变化时屏幕的可见部分,而是将100vh设置为隐藏地址栏的浏览器高度。结果是,当地址栏可见时,屏幕的底部部分将被切断,从而破坏了100vh的初衷

61ab407d5e13754fe54471e4ae86987.png

  • html, body { height: 100% }
    首先 html 设置 height: 100% 表示可视区域窗口的大小,而 html 的高度会随着窗口可用区的高度增大而增大,减小而减小,这样我们就不用怕地址栏影响可视区域了
    然后需要注意用 body 继承下 html 的高度属性就可以生效了,一般项目中这样配置就可以
html,
body,
#app {
    width: 100%;
    height: 100%;
}
复制代码

页面组件结构设计

274fa556c5b36e7bd49d072ebcd913e.png

组件实现

<template>
    <div class="app-page">
        <div class="app-main">
            <slot></slot>
        </div>
    </div>
</template>
<style lang="scss" scoped>
.app-page {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    .app-main {
        flex: 1;
        overflow: auto;
    }
}
</style>
复制代码

标题栏实现

标题栏我们希望它能根据我们路由里定义的标题动态显示页面标题,其次支持可以动态的控制标题栏的显示与隐藏,毕竟有的时我们的页面是不需要显示标题栏的,因为我们项目使用的是 ui 框架是 vant-ui,这里就直接拿 进行改造

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
defineProps({
    navBar: {
        type: Boolean,
        default: true
    },
    leftArrow: {
        type: Boolean,
        default: true
    },
    onClickLeft: {
        type: Function,
        default: () => history.back()
    }
})
const route = useRoute()
</script>
<template>
    <div class="app-page">
        <van-nav-bar
            v-if="navBar"
            :title="route.meta.title"
            :left-arrow="leftArrow"
            @click-left="onClickLeft"
        />
        <div class="app-main">
            <slot></slot>
        </div>
    </div>
</template>
复制代码

这样就完工了,后续所有的页面都用 组件作为根组件包裹,来保障所有页面结构统一,后续有兼容调整的话,也只要在组件中处理就好了

页面应用

<template>
    <app-page>
        <div> ... 开始开发 ... </div>
    </app-page>
</template>
复制代码

移动端兼容

ios 网页消除阻尼回弹效果

通过固定应用内容区域,消除最外层的拖拽界面抖动,让我们整个应用的功能都在 #app 这个固定宽高的盒子内完成,然后关键点是让 #app 容器隐藏溢出元素 overflow: hidden

html,
body,
#app {
    width: 100%;
    height: 100%;
    // 解决 ios 界面回弹
    overflow: hidden;
}
复制代码

ios 底部安全区域样式处理

使用 ios 提供的 safe-area-inset-topsafe-area-inset-bottom 做上下安全区域的兼容处理

#app {
    // 顶部安全区
    padding-top: constant(safe-area-inset-top);
    padding-top: env(safe-area-inset-top);
    // 底部安全区
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
}
复制代码

需要注意H5网页 meta 要设置 viewport-fit=cover 的时候才会生效

移动端 click 延时问题

移动端之所以会有点击 300ms 的延时,原因是移动端屏幕双击会缩放,需要一个判定时间,所以解决这个问题简单粗暴点只要禁用掉屏幕的缩放功能就好了

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover">
复制代码

此外,也可以借助 fastclick 插件解决300ms延迟

ios 时间格式的坑

这个算是顺便给大家提个醒,在做移动端项目时不要使用 new Date().getTime() 去处理 2022-10-14 之类格式的时间为时间戳,特别是用到 datePicker 之类的组件时要格外注意,例如

new Date("2022-01-17 10:00").getTime() // NaN
复制代码

这样你在 ios 下会获得一个 NaN 的异常返回,原因是 ios 下对数字中间的横杆 - 转化会有问题,需要转化为斜杆处理 /

const timestamp = (new Date('2021-07-28 18:00'.replace(/-/g, '/'))).getTime()
复制代码

目前本项目对移动端的兼容处理还比较简单,主要是针对 ios 端一些常见问题的处理,后续想到什么会不断完善补充,仓库也会定期更新,大家多多关注

项目地址(持续迭代中):github.com/jyliyue/vit…

好了,本篇对移动端项目的页面容器介绍和一些常见兼容问题的科普告一段落,下篇开始会对该项目的状态缓存管理体系 pinia 和 vue3 中 keep-alive 的应用做介绍,并带大家一起封装一个移动端常用的列表组件,支持接口配置化以及进入详情返回列表时记录位置等常用功能,敬请大家期待!

相关文章
|
6天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
19 7
|
7天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
25 3
|
6天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
24 1
|
6天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
25 1
|
9天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
10天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
3天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
3天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex
|
10天前
|
缓存 JavaScript 搜索推荐
Vue SSR(服务端渲染)预渲染的工作原理
【10月更文挑战第23天】Vue SSR 预渲染通过一系列复杂的步骤和机制,实现了在服务器端生成静态 HTML 页面的目标。它为提升 Vue 应用的性能、SEO 效果以及用户体验提供了有力的支持。随着技术的不断发展,Vue SSR 预渲染技术也将不断完善和创新,以适应不断变化的互联网环境和用户需求。
29 9
|
9天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。