自定义动态顶部导航栏--uniapp
自定义顶部导航栏--uniapp
·
1.设置页面原生导航栏是否显示
这是非常重要的,否者会出现两个导航栏的情况,一定要关闭原生导航栏
1)全局关闭
"window": {
// 全局导航栏设置,"default"默认显示 "custom"关闭状态
"navigationStyle": "default",//默认显示原生导航栏
},
2)单页关闭
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
// 单页导航栏设置,"default"默认显示 "custom"关闭状态
"navigationStyle": "custom",//设置不显示原生导航栏
}
}
}
2.将想要导航栏封装成组件,这里命名为topNav.vue
1)这是我配置的文件目录,如果需要可以放到公用components下
2)topNav.vue 这里内容有点多,大家自行斟酌增删改
<template>
<view class="topNav" :style="{'background-color': nav.bg}" >
<view class="bigBox">
<view class="header"
:style="{'height':titleBarHeight,'padding-top':statusBarHeight,'background-color': nav.bg}">
<!-- 正常显示 第一种顶部展示-->
<view class="top-boxA" v-if="!indexScrollTopFlag">
<view class="top-title">
<!-- 返回按钮 -->
<uni-icons v-if="backFlag" class="back-home" @click="topBack()" type="back" size="24"
color="#fff"></uni-icons>
<view v-if="backFlag" class="title">页头标题</view>
</view>
</view>
<!-- 上滑一定距离显示 第二种顶部展示-->
<view class="top-boxB" v-else>
<!-- 标题 -->
<view class="top-title">
<!-- 返回按钮 -->
<uni-icons v-if="backFlag" class="back-home" @click="topBack()" type="back" size="24"
color="#fff"></uni-icons>
<!-- 搜索框 -->
<input class="input" type="text" placeholder="请输入商品名称、关键词" disabled @click="search"
placeholder-class="grey" />
<!-- 小按钮 -->
<view class="icons">
<view class="">
<image v-if="getUserShopId&&getUserShopId!=shopDetail.id" @click="checkoutShop"
style="width: 52rpx;height: 52rpx;"
src="home2.png" mode="widthFix">
</image>
</view>
<view class="">
<image style="width: 52rpx;height: 52rpx;" @click="showKefu = true"
src="phone2.png" mode="widthFix">
</image>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- bigBox设置position: fixed; 后续内容会被bigBox覆盖,这里使用和bigBox相同的设置占位 -->
<view class="div" :style="{'height':titleBarHeight,'padding-top':statusBarHeight,'background-color': nav.bg}">
</view>
<!-- 搜索框 -->
<view class="inputCon" v-if="!indexScrollTopFlag">
<text class="inputConText iconfont icon-sousuo"></text>
<input class="input" type="text" placeholder="请输入商品名称、关键词" disabled @click="search"
placeholder-class="grey" />
</view>
<!-- 信息 -->
<view class="shop-Box" :style="{'height': !indexScrollTopFlag ? '':'0rpx'}">
<view class="shop-Box-info" v-if="!indexScrollTopFlag">
<view class="shop-logo">
<image :src="shopDetail.logo?shopDetail.logo:'../../../static/logo.png'" mode=""></image>
</view>
<view class="shop-right">
<view class="shop-right-top">
<!-- 名称 -->
<view class="shop-name line" @click="showListFlag = true">{{shopDetail.name}}</view>
<!-- 小图标 -->
<view class="shop-icon">
<image v-if="getUserShopId&&getUserShopId!=shopDetail.id" @click="checkoutShop"
src="home1.png" mode="widthFix">
</image>
<image style="width: 52rpx;height: 52rpx;" @click="showKefu = true"
src="phone1.png" mode="widthFix">
</image>
</view>
</view>
<!-- 地址 -->
<view class="shop-address">
<view class="shop-address-name">地址:</view>
<view class="shop-address-details line" @click="mapFun">
{{shopDetail.districtName}} {{shopDetail.address}}
</view>
</view>
</view>
</view>
<!-- 公告 -->
<view class="" v-if="!indexScrollTopFlag">
<slot name="news"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
props: ['shopDetail', "nav", 'shopId', 'distance', 'focusShopF', 'indexScrollTopFlag'],
components: {
callTel
},
data() {
return {
userId: null,
statusBarHeight: 0,
titleBarHeight: 0,
showKefu: false,
addrModel: false,
showListFlag: undefined,
startX: 0,
startY: 0,
backFlag: false
}
},
watch: {},
computed: {},
created() {
var that = this;
// 根据设备给予顶部不同高度
uni.getSystemInfo({
success: function(res) {
if (res.model.indexOf('iPhone') !== -1) {
that.titleBarHeight = 12 + 'vh';
} else {
that.titleBarHeight = 11 + 'vh';
}
that.statusBarHeight = res.statusBarHeight + 10 + 'px'
}
})
},
onShow() {},
methods: {
topBack() {
this.$emit("topBack") //index页面返回函数
},
}
}
</script>
<style lang="scss" scoped>
// 顶部
.bigBox {
position: fixed;
width: 100%;
z-index: 3;
.top-boxA {
width: 100%;
text-align: center;
font-weight: bold;
height: 60rpx;
line-height: 60rpx;
color: #fff;
font-size: 32rpx;
.top-title {
position: relative;
.back-home {
position: absolute;
top: 0rpx;
left: 16rpx;
}
}
}
.top-boxB {
width: 100%;
text-align: center;
height: 60rpx;
line-height: 60rpx;
color: #fff;
font-size: 32rpx;
margin-top: -16rpx;
.top-title {
display: flex;
position: relative;
.back-home {
position: absolute;
top: 6rpx;
left: 16rpx;
}
.input {
margin-left: 80rpx;
text-align: left;
border: none;
outline: none;
font-size: 26upx;
padding-left: 10rpx;
color: #999999;
width: 324rpx;
height: 72rpx;
line-height: 72upx;
background: #FFFFFF;
border-radius: 88rpx;
}
.icons {
margin-top: 10rpx;
width: 100rpx;
display: flex;
view {
width: 64rpx;
margin-left: 10rpx;
}
image {
width: 64rpx;
}
}
}
}
}
// 输入框
.inputCon {
width: 702upx;
margin: 0 auto;
padding: 0 20upx;
box-sizing: border-box;
border: 2upx solid #DDDDDD;
border-radius: 35upx;
display: flex;
align-items: center;
background-color: #fff;
position: relative;
.inputConText {
font-size: 32upx;
flex-shrink: 0;
color: #999999;
}
.input {
width: 686rpx;
height: 70rpx;
text-align: left;
border: none;
outline: none;
font-size: 26upx;
padding-left: 6%;
color: #999999;
height: 70upx;
line-height: 70upx;
}
.grey {
color: #999999;
font-size: 26upx;
}
.inputErweima {
width: 50rpx;
height: 50rpx;
display: block;
position: absolute;
top: 8rpx;
right: 16rpx;
background-image: url(../../../static/erweima.png);
background-size: 50rpx 50rpx;
background-repeat: no-repeat;
z-index: 20;
}
}
// 信息
.shop-Box {
width: 100%;
height: 286rpx;
padding: 32rpx 16rpx;
margin-top: 38rpx;
background: #FFFFFF;
border-radius: 28rpx 28rpx 0rpx 0rpx;
.shop-Box-info {
display: flex;
.shop-logo {
image {
width: 136rpx;
height: 136rpx;
border-radius: 50rpx;
}
}
.shop-right {
width: 566rpx;
padding-left: 16rpx;
.shop-right-top {
font-size: 32rpx;
font-weight: bold;
color: #000000;
display: flex;
justify-content: space-between;
align-items: center;
.shop-icon {
display: flex;
image {
width: 52rpx;
height: 52rpx;
margin-right: 8rpx;
margin-left: 8rpx;
}
}
}
.shop-address {
width: 100%;
height: 40rpx;
margin-top: 24rpx;
font-size: 28rpx;
color: #333333;
display: flex;
.shop-address-name {
display: inline-block;
width: 146rpx;
height: 100%;
}
.shop-address-details {
width: 424rpx;
height: 100%;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
</style>
3)index.vue
<template>
<view class="index">
<!-- 使用组件 规范写法: top-nav -->
<!--注: 顶部导航组件一定要写在顶部 -->
<shop-mod :nav="setNav" :shopDetail='shopDetail' :shopId='shopId' :distance='distance' @child-event='loadShop' @topBack="topBack" :focusShopF='focusShopF' :indexScrollTopFlag='indexScrollTopFlag'>
<!-- 公告内容 -->
<template #news>
<view class="news" @click="toShowNews">
<view class="newsImg">
<text class="iconfont icon-gonggao"></text>
</view>
<view class="newsInfo" :class="newsHideFlag?'hide':'show'">
{{shopDetail.notice?shopDetail.notice:'暂无公告'}}
</view>
</view>
</template>
</shop-mod>
<!-- 下面就可以编写其他内容了 -->
<view class="content"></view>
</view>
</template>
<script>
import topNav from './componets/topNav.vue' //引入组件
export default {
data() {
return {
//用来判断是否采用第二种顶部样式 false不采用 true采用
indexScrollTopFlag:false,
};
},
components: { //挂载组件
topNav
},
onPageScroll(e) {//监听页面滚动距离
// console.log(e)
if (e.scrollTop >= 4) {
//这里大家可以根据需求自行更改
//滚动距离超过4将indexScrollTopFlag改为false
this.indexScrollTopFlag = true
} else {
this.indexScrollTopFlag = false
}
},
methods: {
topBack() { // 返回函数,内容大家自行修改编写
// 返回顶部
uni.pageScrollTo({
scrollTop: 0,
duration: 300
});
}
}
}
</script>
<style></style>
3.效果图
样式1: 样式2:
你可能需要:(自己写的,放心食用)
更多推荐
已为社区贡献1条内容
所有评论(0)