手拉手带你用 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 的应用做介绍,并带大家一起封装一个移动端常用的列表组件,支持接口配置化以及进入详情返回列表时记录位置等常用功能,敬请大家期待!

目录
打赏
0
0
0
0
2
分享
相关文章
斩获开发者口碑!SnowAdmin:基于 Vue3 的高颜值后台管理系统,3 步极速上手!
SnowAdmin 是一款基于 Vue3/TypeScript/Arco Design 的开源后台管理框架,以“清新优雅、开箱即用”为核心设计理念。提供角色权限精细化管理、多主题与暗黑模式切换、动态路由与页面缓存等功能,支持代码规范自动化校验及丰富组件库。通过模块化设计与前沿技术栈(Vite5/Pinia),显著提升开发效率,适合团队协作与长期维护。项目地址:[GitHub](https://github.com/WANG-Fan0912/SnowAdmin)。
390 5
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。
175 17
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
186 6
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
437 0
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
163 0
|
3月前
|
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
355 4
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
230 77
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
142 17
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等