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

相关文章
|
3月前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
680 139
|
3月前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
338 1
|
4月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
524 11
|
3月前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
394 0
|
5月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
576 1
|
4月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
411 2
|
3月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
371 137
|
7月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
901 0
|
7月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
8月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1120 78

热门文章

最新文章