Browse Source

refactor(页面布局): 统一调整多个页面的布局结构和样式

重构多个页面的布局结构,统一使用navv组件和topTitle组件,优化内容区域高度计算方式
调整样式细节包括边距、对齐方式和滚动行为,提升整体一致性和用户体验
master
wei 2 days ago
parent
commit
32078140a1
  1. 2
      .hbuilderx/launch.json
  2. 16
      components/custom-tab-bar/my-tab-bar.vue
  3. 33
      components/nav/nav.vue
  4. 4
      components/topTitle/topTitle.vue
  5. 9
      libs/utils/index.js
  6. 7
      pages/allDish/allDish.scss
  7. 27
      pages/allDish/allDish.vue
  8. 11
      pages/allDish/dishDetail.vue
  9. 2
      pages/deliveryAddress/deliveryAddress.scss
  10. 14
      pages/deliveryAddress/deliveryAddress.vue
  11. 7
      pages/home/announcement.vue
  12. 6
      pages/home/enterKing/enterKing.vue
  13. 9
      pages/home/enterKing/enterKingInfo.vue
  14. 24
      pages/home/home.vue
  15. 27
      pages/home/honest.vue
  16. 14
      pages/joinEnterprise/joinEnterprise.vue
  17. 16
      pages/recipeOrder/recipeOrder.scss
  18. 12
      pages/recipeOrder/recipeOrder.vue
  19. 10
      pages/shoppingCart/shoppingCart.scss
  20. 23
      pages/shoppingCart/shoppingCart.vue

2
.hbuilderx/launch.json

@ -8,7 +8,7 @@
"type" : "uni-app:app-android"
},
{
"playground" : "standard",
"playground" : "custom",
"type" : "uni-app:app-ios"
}
]

16
components/custom-tab-bar/my-tab-bar.vue

@ -1,6 +1,6 @@
<script setup>
import { onReady } from "@dcloudio/uni-app";
import { computed, getCurrentInstance, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { computed, getCurrentInstance, nextTick, ref } from "vue";
import { useRect } from "@/libs/utils";
import useStore from "@/store";
@ -85,12 +85,12 @@ function onChangeTab(index) {
});
}
onReady(() => {
useRect(".tab-bar", instance.proxy).then((rect) => {
store.tabbarBottomHeight = rect?.height || 0;
});
useRect(".tab-bar-item", instance.proxy).then((rect) => {
store.tabbarItemWidth = rect?.width || 0;
onLoad(() => {
nextTick(async () => {
const tabBarRect = await useRect("#tab-bar", instance.proxy);
store.tabbarBottomHeight = tabBarRect?.height || 0;
const tabBarItemRect = await useRect("#tab-bar-item", instance.proxy);
store.tabbarItemWidth = tabBarItemRect?.width || 0;
});
});
</script>

33
components/nav/nav.vue

@ -7,11 +7,11 @@ import useStore from "@/store";
const store = useStore();
const safeHeight = ref({
status: 0,
menu: 0,
screen: 0,
content: 0,
bottom: 0,
status: 0, //
menu: 0, // titlte
screen: 0, //
content: 0, //
bottom: 0, //
});
onLoad(() => {
@ -23,14 +23,15 @@ onLoad(() => {
safeHeight.value.screen = height.screen;
safeHeight.value.content = height.content;
safeHeight.value.bottom = height.bottom;
safeHeight.value.tabbar = height.tabbar;
// #ifdef H5
nextTick(async () => {
const rect = await useRect(".h5Title");
if (rect) {
safeHeight.value.menu = rect.height;
}
});
// #ifdef H5|APP-PLUS
// nextTick(async () => {
// const rect = await useRect(".h5Title");
// if (rect) {
// safeHeight.value.menu = rect.height;
// }
// });
// #endif
});
@ -50,7 +51,7 @@ onLoad(() => {
:tabbar="safeHeight.tabbar"
:content="safeHeight.content"
:style="{
height: safeHeight.menu ? `${safeHeight.menu}px` : '45px',
height: safeHeight.menu ? `${safeHeight.menu}px` : '40px',
paddingTop: `${safeHeight.status}px`,
backgroundColor: '#f8f8f8',
width: '100%',
@ -58,7 +59,7 @@ onLoad(() => {
alignItems: 'center',
}"
:fix-style=" {
height: safeHeight.menu ? `${safeHeight.menu}px` : '45px',
height: safeHeight.menu ? `${safeHeight.menu}px` : '40px',
paddingTop: `${safeHeight.status}px`,
backgroundColor: '#f8f8f8',
width: '100%',
@ -70,8 +71,8 @@ onLoad(() => {
alignItems: 'center',
} "
:pad-style="{
paddingTop: `${safeHeight.status + (safeHeight.menu || 45) + 5}px`,
height: `${safeHeight.menu || 45}px`,
paddingTop: `${safeHeight.status + (safeHeight.menu || 40) + 5}px`,
height: `${safeHeight.menu || 40}px`,
}"
/>
</view>

4
components/topTitle/topTitle.vue

@ -33,11 +33,11 @@ const props = defineProps(
<style lang="scss" scoped>
.left {
display: flex;
align-items: center;
align-items: baseline;
padding-left: 29rpx;
.icon-back {
font-size: $text-8xl;
font-size: $text-4xl;
font-weight: bold;
color: black;
}

9
libs/utils/index.js

@ -44,6 +44,7 @@ export function sleep(timeout = 3000) {
* @property {number} content - 内容高度(屏幕高度 - 安全区域底部高度)
* @property {number} bottom - 安全区域底部高度
* @property {number} statusMenu - 状态栏高度 + 小程序胶囊高度
* @property {number} tabbar - tabbar高度
*/
/**
@ -75,11 +76,13 @@ export function useHeight() {
safeHeight.menu = safeHeight.menu || 0; // 小程序胶囊高度
safeHeight.bottom = info.safeAreaInsets.bottom || 0; // 手机屏幕底部安全高度
safeHeight.statusMenu = safeHeight.status + safeHeight.menu; // 手机状态栏+小程序胶囊的高度
safeHeight.tabbar = store.tabbarBottomHeight || 0; // tabbar高度
safeHeight.content = info.screenHeight
// - info.safeAreaInsets.bottom
- store.tabbarBottomHeight
- safeHeight.statusMenu; // 减去手机状态栏 + 小程序胶囊 + tabbar + 底部安全高度
// - store.tabbarBottomHeight
- safeHeight.bottom
- safeHeight.status - (safeHeight.menu || 40); // 减去手机状态栏 + 小程序胶囊 + tabbar + 底部安全高度
return safeHeight;
}
@ -197,5 +200,5 @@ export function increaseFontScale(incScale = 0.1) {
const store = useStore();
store.fontScale += incScale;
uni.setStorageSync("fontScale", store.fontScale);
validates(() => true && `${store.fontScale} 倍数`);
// validates(() => true && `${store.fontScale} 倍数`);
}

7
pages/allDish/allDish.scss

@ -1,5 +1,9 @@
.header-box {
width: 100%;
position: relative;
box-sizing: border-box;
background-color: #fff;
z-index: 99999999;
.box {
margin-left: 14rpx;
margin-right: 14rpx;
@ -746,7 +750,6 @@ page {
padding-top: 12rpx;
position: relative;
z-index: 9;
background-color: #fff;
border-bottom: 1px solid #CCCCCC;
.left {
@ -843,7 +846,7 @@ page {
.first-big-type {
position: fixed;
z-index: 999999;
z-index: 999999999;
background-color: #fff;
width: 100%;
padding: 30rpx 30rpx 20rpx 30rpx;

27
pages/allDish/allDish.vue

@ -1,5 +1,5 @@
<script setup>
import { onHide, onLoad, onShow } from "@dcloudio/uni-app";
import { onHide, onShow } from "@dcloudio/uni-app";
import { nextTick, ref } from "vue";
import customTabBar from "@/components/custom-tab-bar/my-tab-bar.vue";
// import navigation from "@/components/navigation/navigation.vue";
@ -42,12 +42,12 @@ const keyword = ref("");
/**
* 各种距离
*/
const safeHeight = ref({
screen: 0,
status: 0,
menu: 0,
content: 0,
});
// const safeHeight = ref({
// screen: 0,
// status: 0,
// menu: 0,
// content: 0,
// });
/**
* 当前标签
*/
@ -790,13 +790,11 @@ onShow(() => {
onOpenRecord();
store.showVoice = false;
}
});
onShow(() => {
nextTick(async () => {
const boxHeight = (await useRect(".first-box"))?.height || 0;
const { content } = useHeight();
pageContainerHeight.value = content - boxHeight - 5;
const { content, tabbar } = useHeight();
pageContainerHeight.value = content - boxHeight - tabbar;
});
});
@ -1123,11 +1121,12 @@ onHide(() => {
<view v-show="isShowAll" class="first-type-mask" @tap="onShowAllTypes" />
<!-- 展开全部分类 -->
<view>
<view
class="first-big-type"
:style="{
top: isShowAll
? `${safeHeight.status + (safeHeight.menu || 45) + 5}px`
? `${status + (menu || 45) + 5}px`
: '-1600rpx',
}"
>
@ -1164,6 +1163,7 @@ onHide(() => {
<text class="iconfont icon-up1" />
</view>
</view>
</view>
<!-- 输入购买数量弹框 -->
<!-- <modal
@ -1202,8 +1202,9 @@ onHide(() => {
</template>
<style lang="scss" scoped>
@import './allDish.scss';
.moneySymbol {
font-size: $text-xs;
}
@import './allDish.scss';
</style>

11
pages/allDish/dishDetail.vue

@ -5,9 +5,14 @@ import topTitle from "@/components/topTitle/topTitle.vue";
<template>
<navv>
<template #default="{ fixStyle, padStyle }">
<topTitle title="菜品详情" :style="fixStyle" />
<view :style="padStyle">
<template #default="{ style, content }">
<topTitle title="菜品详情" :style="style" />
<view
:style="{
height: `${content}px`,
overflowY: 'auto',
}"
>
<view
v-for="(item, index) in 1000" :key="index"
>

2
pages/deliveryAddress/deliveryAddress.scss

@ -1,6 +1,6 @@
/* pages/selectAddress/selectAddress.wxss */
.content {
margin: 21rpx 14rpx 0 14rpx;
padding: 21rpx 14rpx 0 14rpx;
// padding-bottom: 200rpx;
}
.padding {

14
pages/deliveryAddress/deliveryAddress.vue

@ -2,7 +2,7 @@
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue";
import navv from "@/components/nav/nav.vue";
import TopTitle from "@/components/topTitle/topTitle.vue";
import topTitle from "@/components/topTitle/topTitle.vue";
import {
editDefaultAddressApi,
getMyAreaApi,
@ -142,9 +142,15 @@ onLoad(() => {
<template>
<navv>
<template #default="{ content, style }">
<TopTitle title="选择地址" :style="{ style }" />
<view class="content" :style="{ 'height': `${content}px`, 'overflow-y': 'auto' }">
<template #default="{ style, content }">
<topTitle title="选择地址" :style="style" />
<view
class="content"
:style="{
height: `${content}px`,
overflowY: 'auto',
}"
>
<block
v-for="(item, idx) in selectData"
:key="idx"

7
pages/home/announcement.vue

@ -22,15 +22,16 @@ onLoad(() => {
<template>
<navv>
<template #default="{ screen, status, menu }">
<topTitle title="通知公告" />
<template #default="{ content, style }">
<topTitle title="通知公告" :style="style" />
<view
:style="{
borderTop: 'solid 1px #F0f0f0',
width: '100%',
height: `${screen - status - (menu || 0)}px`,
height: `${content}px`,
overflowY: 'auto',
overflowX: 'hidden',
}"
>
<view v-for="(item, index) in notices" :key="index" class="notice">

6
pages/home/enterKing/enterKing.vue

@ -68,14 +68,14 @@ onLoad(() => {
<template>
<navv>
<template #default="{ content, screen, status, menu }">
<topTitle title="走进菜大王" />
<template #default="{ style, content }">
<topTitle title="走进菜大王" :style="style" />
<scroll-view
:scroll-y="true"
:style="{
width: '100%',
height: `${screen - status - (menu || 0)}px`,
height: `${content}px`,
overflowY: 'auto',
}"
@scrolltolower="loadList"

9
pages/home/enterKing/enterKingInfo.vue

@ -47,12 +47,12 @@ function preview(index) {
<template>
<navv>
<template #default="{ screen, status, menu }">
<topTitle title="菜大王" />
<template #default="{ style, content }">
<topTitle title="菜大王" :style="style" />
<view
:style="{
height: `${screen - status - (menu || 0)}px`,
height: `${content}px`,
overflowY: 'auto',
}"
>
@ -112,4 +112,7 @@ function preview(index) {
<style scoped lang="scss">
@import "./enterKingInfo.scss";
.container {
display: flex;
}
</style>

24
pages/home/home.vue

@ -565,21 +565,6 @@ onLoad(() => {
getBanner(); //
getProductCategory(); //
getNoticesApiList(); //
// statusBarHeight.value = uni.getWindowInfo().statusBarHeight;
// nextTick(() => {
// #ifdef MP-WEIXIN
// width,height,top,right,left,bottom
// const menuButton = uni.getMenuButtonBoundingClientRect();
// statusBarHeight.value = menuButton.top;
// locationBarHeight.value = menuButton.height;
// = +
// navHeight.value = locationBarHeight.value + statusBarHeight.value;
// #endif
// });
});
onShow(async () => {
@ -591,12 +576,11 @@ onShow(async () => {
<template>
<navv>
<template #default="{ status: statusBarHeight, menu: locationBarHeight }">
<template #default="{ status, menu }">
<view
class="main"
:style="{
'paddingBottom': statusBarHeight ? `${statusBarHeight + 45}px` : '89px',
'--font-scale': store.fontScale,
paddingBottom: status ? `${status + 45}px` : '89px',
}"
>
<view
@ -612,7 +596,7 @@ onShow(async () => {
<view
class="location-share"
:style="{
paddingTop: `${statusBarHeight}px`,
paddingTop: `${status}px`,
}"
>
<!-- #ifdef APP-PLUS|H5 -->
@ -620,7 +604,7 @@ onShow(async () => {
<!-- #endif -->
<view
class="location-box"
:style="{ height: locationBarHeight ? `${locationBarHeight}px` : 'auto' }"
:style="{ height: menu ? `${menu}px` : 'auto' }"
>
<!-- left -->
<view class="left" @tap="onGotoSelectAddress">

27
pages/home/honest.vue

@ -2,7 +2,9 @@
import { onReady, onShow } from "@dcloudio/uni-app";
import moment from "moment";
import { nextTick, ref } from "vue";
import navigation from "@/components/navigation/navigation.vue";
import navv from "@/components/nav/nav.vue";
import topTitle from "@/components/topTitle/topTitle.vue";
// import navigation from "@/components/navigation/navigation.vue";
import { addHonestApi, getHonestApi, getUserInfoApi, sealImgApi } from "@/libs/api";
/**
* 甲方
@ -217,9 +219,19 @@ onShow(async () => {
</script>
<template>
<navigation title="廉洁协议" />
<view id="main" style="padding: 28rpx; border-top:solid 1px #f0f0f0;font-size: 30rpx;">
<!-- <navigation title="廉洁协议" /> -->
<navv>
<template #default="{ style, content }">
<topTitle title="廉洁协议" :style="style" />
<view
id="main" :style="{
height: `${content}px`,
overflowY: 'auto',
padding: '28rpx',
borderTop: 'solid 1px #f0f0f0',
fontSize: '30rpx',
}"
>
<view>
<view class="companyName">
<text style="width:90rpx;font-size:30rpx;">
@ -390,8 +402,10 @@ onShow(async () => {
</button>
</view>
</template>
</navv>
</template>
<style lang="css" scoped>
<style lang="scss" scoped>
.autograph {
display: flex;
justify-content: flex-start;
@ -418,4 +432,7 @@ onShow(async () => {
color: #333333;
border-bottom: solid 1px #d9d9d9;
}
uni-page {
height: 100%;
}
</style>

14
pages/joinEnterprise/joinEnterprise.vue

@ -2,7 +2,7 @@
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue";
import navv from "@/components/nav/nav.vue";
import TopTitle from "@/components/topTitle/topTitle.vue";
import topTitle from "@/components/topTitle/topTitle.vue";
import { getJoinEnterpriseApi } from "@/libs/api";
/**
@ -44,9 +44,15 @@ async function addEnterprise() {
<template>
<navv>
<template #default="{ fixStyle, padStyle }">
<TopTitle title="加入企业" :style="fixStyle" />
<view v-if="!showTil" class="content" :style="padStyle">
<template #default="{ style, content }">
<topTitle title="加入企业" :style="style" />
<view
v-if="!showTil" class="content" :style="{
height: `${content}px`,
overflowY: 'auto',
}"
>
<view class="tips">
创建企业您将成为企业的管理者加入企业您将成为企业的子账号若有同事已经创建过企业请加入企业
</view>

16
pages/recipeOrder/recipeOrder.scss

@ -2,7 +2,7 @@
width: 100%;
display: flex;
align-items: center;
font-size: $text-4xl;
font-size: $text-3xl;
.icon-search1 {
font-size: $text-8xl;
@ -525,7 +525,7 @@
font-weight: 400;
font-size: 26rpx;
color: #333333;
padding: 0 30rpx;
padding: 0 20rpx;
box-sizing: border-box;
transition: .3s all;
}
@ -536,11 +536,13 @@
}
.page-container {
padding-top: 35rpx;
// padding-top: 35rpx;
display: flex;
box-sizing: border-box;
}
.page-container .left {
width: 150rpx;
height: 100%;
@ -549,7 +551,8 @@
font-size: 26rpx;
color: #333333;
background: #F8FAF7;
padding-top: 14rpx;
padding-top: 35rpx;
// padding-top: 14rpx;
}
.page-container .left .text {
@ -577,9 +580,10 @@
}
.page-container .right {
padding-top: 35rpx;
flex: 1;
margin-left: 14rpx;
margin-right: 26rpx;
padding-left: 14rpx;
padding-right: 14rpx;
}
.page-container .right .right-list {

12
pages/recipeOrder/recipeOrder.vue

@ -383,13 +383,15 @@ onLoad(() => {
});
onShow(() => {
initCartInfo();
nextTick(async () => {
const boxHeight = (await useRect(".second-list"))?.height || 0;
const { content } = useHeight();
await sleep(500);
const boxHeight = (await useRect(".second"))?.height || 0;
pageContainerHeight.value = content - boxHeight - 80;
const { content, tabbar } = useHeight();
pageContainerHeight.value = content - boxHeight - tabbar;
});
initCartInfo();
},
);
</script>
@ -422,7 +424,7 @@ onShow(() => {
<view
class="page-container"
:style="{ height: `${pageContainerHeight}px` }"
:style="{ height: `calc(${pageContainerHeight}px - 35rpx)` }"
>
<view class="left">
<view

10
pages/shoppingCart/shoppingCart.scss

@ -1,5 +1,11 @@
.header-box {
padding-left: 33rpx;
font-size: $text-3xl;
display: flex;
align-items: center;
}
.address {
padding: 17rpx 0 33rpx 0;
padding: 17rpx 0 0rpx 0;
margin: 0 29rpx 0 33rpx;
background: #FFFFFF;
display: flex;
@ -222,7 +228,7 @@
background: #fff;
z-index: 999;
/* padding-bottom: 20rpx; */
padding: 0 14rpx 20rpx;
padding: 0 14rpx 10rpx;
box-sizing: border-box;
.under-box-left {
display: flex;

23
pages/shoppingCart/shoppingCart.vue

@ -3,7 +3,7 @@ import { onLoad, onShow } from "@dcloudio/uni-app";
import { ref } from "vue";
import customTabBar from "@/components/custom-tab-bar/my-tab-bar.vue";
import navv from "@/components/nav/nav.vue";
import topTitle from "@/components/topTitle/topTitle.vue";
// import topTitle from "@/components/topTitle/topTitle.vue";
import {
addCartApi,
deleteFromCartApi,
@ -625,15 +625,21 @@ onLoad(() => {
<template>
<navv>
<template #default="{ content, fixStyle }">
<template #default="{ menu, status, content, tabbar }">
<!-- 购物车标题 -->
<topTitle
title="购物车"
:style="{ ...fixStyle, backgroundColor: '#fff', position: 'static' }"
/>
<view
class="header-box"
:style="{
paddingTop: `${status}px`,
height: `${menu || 45}px`,
}"
>
<!-- <text class="iconfont icon-search1" /> -->
<text>购物车</text>
</view>
<!-- 收获地址 -->
<view class="address">
<view id="address" class="address">
<view class="left" @tap="onGoSelectAddress">
<text class="iconfont icon-positioning" />
<text class="name">
@ -650,7 +656,7 @@ onLoad(() => {
<view
v-if="cartLists.length > 0"
class="third"
:style="{ 'height': `${content - store.tabbarBottomHeight}px`, 'overflow-y': 'auto' }"
:style="{ 'height': `calc(${content}px - 14vh)`, 'overflow-y': 'auto' }"
>
<!-- 购物车列表 -->
<view class="top-box" :style="{ paddingBottom: `${store.tabbarBottomHeight}px` }">
@ -731,6 +737,7 @@ onLoad(() => {
<!-- 底部统计栏 -->
<view
id="under-box"
class="under-box" :style="{
bottom: `${store.tabbarBottomHeight}px`,
}"

Loading…
Cancel
Save