uniapp 兼容ipad 自定义顶部与 tabber
pages.json
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "custom",//不显示title
"rpxCalcMaxDeviceWidth": 2000//
},
在路由页面中 app 端要使用
onLoad(){
uni.hideTabBar()
},
App.vue
onLaunch: function () {
uni.hideTabBar()
},
body.vue
<template>
<view class="custombody">
<view class="top-title" v-if="showTitle">
<!-- 如果页面栈没有上一 则显示 点击回到首页 -->
<view class="iconfont iconjifen" v-if="showhomebtn && homebtn" @tap="goHome" style="color:cadetblue">首页</view>
<view class="iconfont iconarrow-lift" @tap="goBack" v-else-if="isBack">返回</view>
<view class="ctitle">{{ title }}</view>
</view>
<scroll-view class="body" scroll-y show-scrollbar>
<slot></slot>
</scroll-view>
<view class="tabbar" v-if="tabber">
<view class="tabbar-item" v-for="(item, index) in list" :key="index" @tap="switchTab(item.pagePath)">
<image :src="getImage(index, item)" mode="aspectFill" class="tab-image"></image>
<view class="tab-title oneline" :class="curindex === index ? 'check' : ''">{{ item.text }}</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '标题'
},
//是否显示返回键
isBack: {
type: Boolean,
default: true
},
//是否显示栏目名
showTitle: {
type: Boolean,
default: true
},
tabber: {
type: Boolean,
default: false
},
homebtn: {
type: Boolean,
default: true
}
},
data() {
return {
showhomebtn: false,
curindex: -1,
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/images/tabBar/index.png",
"selectedIconPath": "static/images/tabBar/index_selected.png"
},
{
"pagePath": "pages/menu/menu",
"text": "点餐",
"iconPath": "static/images/tabBar/drink.png",
"selectedIconPath": "static/images/tabBar/drink_selected.png"
},
{
"pagePath": "pages/take-foods/take-foods",
"text": "取餐",
"iconPath": "static/images/tabBar/take.png",
"selectedIconPath": "static/images/tabBar/take_selected.png"
},
{
"pagePath": "pages/mine/mine",
"text": "我的",
"iconPath": "static/images/tabBar/mine.png",
"selectedIconPath": "static/images/tabBar/mine_selected.png"
}
]
}
},
mounted() {
this.hasBeforePage()
let pages = getCurrentPages() // 获取栈实例
let currentRoute = pages[pages.length - 1].route;
this.curindex = this.list.findIndex(item => item.pagePath === currentRoute)
console.log('mounted' + currentRoute);
},
activated() {
let pages = getCurrentPages() // 获取栈实例
let currentRoute = pages[pages.length - 1].route;
console.log('显示' + currentRoute);
this.hasBeforePage()
},
methods: {
hasBeforePage() {
let pages = getCurrentPages();//当前页
if (pages.length === 1) {
this.showhomebtn = true
} else {
this.showhomebtn = false
}
},
goHome() {
uni.switchTab({
url: '/pages/index/index'
});
},
getImage(index = -1, item = {}) {
if (index === this.curindex) {
return require('@/' + item.selectedIconPath)
} else {
return require('@/' + item.iconPath)
}
},
goBack() {
// uni.navigateBack()
const pages = getCurrentPages();
if (pages.length === 2) {
uni.navigateBack({
delta: 1
});
} else if (pages.length === 1) {
uni.switchTab({
url: '/pages/index/index',
})
} else {
uni.navigateBack({
delta: 1
});
}
},
switchTab(path) {
uni.switchTab({
url: '/' + path
});
}
}
}
</script>
<style lang="scss" scoped>
.custombody {
min-height: 100vh;
height: 100%;
display: flex;
flex-direction: column;
.top-title {
font-size: 24rpx;
height: 70rpx;
display: flex;
justify-content: center;
bottom: 90vh;
align-items: center;
background: #fff;
border-bottom: 1rpx solid #efefef;
box-shadow: 0px 2rpx 15rpx 0px #efefef;
}
.ctitle {
max-width: 70%;
text-overflow: ellipsis;
overflow: hidden;
font-size: 30rpx;
white-space: nowrap;
}
.iconfont {
position: absolute;
left: 10rpx;
font-size: 16rpx;
}
.body {
flex: 1;
height: 0;
// overflow: auto;
}
}
.oneline {
text-overflow: ellipsis;
overflow: hidden;
font-size: 30rpx;
white-space: nowrap;
width: 100%;
}
.tabbar {
display: flex;
align-items: center;
box-shadow: 0px 4rpx 15rpx 0px #999;
background: #f7f7f7;
.tabbar-item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 10rpx 6rpx;
box-sizing: border-box;
.tab-image {
width: 40rpx;
height: 40rpx;
}
.tab-title {
margin-top: 10rpx;
font-size: 24rpx;
max-width: 140rpx;
text-align: center;
}
}
}
.check {
color: #adb838;
}
</style>
main.js
import gBody from '@/components/body.vue'
Vue.component('gBody',gBody)
Vue.config.productionTip = false
<gBody :showTitle="false" :tabber="true" :homebtn="false">
...
</gBody>