123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- <template>
- <view
- class="tn-custom-nav-bar-class tn-custom-nav-bar"
- :style="[navBarStyle]"
- >
- <view
- class="tn-custom-nav-bar__bar"
- :class="[barClass]"
- :style="[barStyle]"
- >
- <view v-if="isBack">
- <view v-if="customBack">
- <view
- :style="{
- width: customBackStyleInfo.width + 'px',
- height: customBackStyleInfo.height + 'px',
- marginLeft: customBackStyleInfo.left + 'px'
- }"
- >
- <slot name="back"></slot>
- </view>
- </view>
- <view v-else class="tn-custom-nav-bar__bar__action" @tap="handlerBack">
- <text class="tn-custom-nav-bar__bar__action--nav-back" :class="[`tn-icon-${backIcon}`]"></text>
- <text class="tn-custom-nav-bar__bar__action--nav-back-text" v-if="backTitle">{{ backTitle }}</text>
- </view>
- </view>
- <view class="tn-custom-nav-bar__bar__content" :style="[contentStyle]">
- <slot></slot>
- </view>
- <view>
- <slot name="right"></slot>
- </view>
- </view>
- </view>
- </template>
- <script>
- import componentsColorMixin from '../../libs/mixin/components_color.js'
- export default {
- name: 'tn-nav-bar',
- mixins: [componentsColorMixin],
- props: {
- // 层级
- zIndex: {
- type: Number,
- default: 0
- },
- // 导航栏的高度
- height: {
- type: Number,
- default: 0
- },
- // 高度单位
- unit: {
- type: String,
- default: 'px'
- },
- // 是否显示返回按钮
- isBack: {
- type: Boolean,
- default: true
- },
- // 返回按钮的图标
- backIcon: {
- type: String,
- default: 'left'
- },
- // 返回按钮旁显示的文字
- backTitle: {
- type: String,
- default: '返回'
- },
- // 透明状态栏
- alpha: {
- type: Boolean,
- default: false
- },
- // 是否固定在顶部
- fixed: {
- type: Boolean,
- default: true
- },
- // 是否显示底部阴影
- bottomShadow: {
- type: Boolean,
- default: true
- },
- // 是否自定义返回按钮
- customBack: {
- type: Boolean,
- default: false
- },
- // 返回前回调
- beforeBack: {
- type: Function,
- default: null
- }
- },
- computed: {
- navBarStyle() {
- let style = {}
- style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit
- if (this.fixed) {
- style.position = 'fixed'
- }
- style.zIndex = this.elZIndex
-
- return style
- },
- barClass() {
- let clazz = ''
- if (this.backgroundColorClass) {
- clazz += ` ${this.backgroundColorClass}`
- }
- if (this.fontColorClass) {
- clazz += `${this.fontColorClass}`
- }
- if (this.fixed) {
- clazz += ' tn-custom-nav-bar__bar--fixed'
- }
- if (this.alpha) {
- clazz += ' tn-custom-nav-bar__bar--alpha'
- }
- if (this.bottomShadow) {
- clazz += ' tn-custom-nav-bar__bar--bottom-shadow'
- }
-
- return clazz
- },
- barStyle() {
- let style = {}
- style.height = this.height === 0 ? this.customBarHeight + this.unit : this.height + this.unit
-
- if (this.fixed) {
- style.paddingTop = this.statusBarHeight + 'px'
- }
-
- if(!this.backgroundColorClass) {
- style.backgroundColor = this.backgroundColor !== '' ? this.backgroundColor : '#FFFFFF'
- }
- if (!this.fontColorClass && this.fontColor) {
- style.color= this.fontColor
- }
-
- style.zIndex = this.elZIndex
-
- return style
- },
- contentStyle() {
- let style = {}
- style.top = this.fixed ? this.statusBarHeight + 'px' : '0px'
- style.height = this.height === 0 ? (this.customBarHeight - this.statusBarHeight) + this.unit : this.height + this.unit
- style.lineHeight = style.height
-
- if (this.isBack) {
- if (this.customBack) {
- const width = (this.customBackStyleInfo.width + this.customBackStyleInfo.left) * 2
- style.width = `calc(100% - ${width}px)`
- } else {
- style.width = 'calc(100% - 340rpx)'
- }
- } else {
- style.width = '100%'
- }
-
- return style
- },
- elZIndex() {
- return this.zIndex ? this.zIndex : this.$t.zIndex.navbar
- }
- },
- data() {
- return {
- // 状态栏的高度
- statusBarHeight: 0,
- // 自定义导航栏的高度
- customBarHeight: 0,
- // 自定义返回按钮时,返回容器的宽高边距信息
- customBackStyleInfo: {
- width: 86,
- height: 32,
- left: 15
- }
- }
- },
- mounted() {
- // 获取vuex中的自定义顶栏的高度
- this.updateNavBarInfo()
- },
- created() {
- // 获取胶囊信息
- // #ifdef MP-WEIXIN
- let custom = wx.getMenuButtonBoundingClientRect()
- this.customBackStyleInfo.width = custom.width
- this.customBackStyleInfo.height = custom.height
- this.customBackStyleInfo.left = uni.upx2px(750) - custom.right
- // #endif
- },
- methods: {
- // 更新导航栏的高度
- async updateNavBarInfo() {
- // 获取vuex中的自定义顶栏的高度
- let customBarHeight = this.vuex_custom_bar_height
- let statusBarHeight = this.vuex_status_bar_height
- // 如果获取失败则重新获取
- if (!customBarHeight) {
- try {
- const navBarInfo = await this.$t.updateCustomBar()
- customBarHeight = navBarInfo.customBarHeight
- statusBarHeight = navBarInfo.statusBarHeight
- } catch(e) {
- setTimeout(() => {
- this.updateNavBarInfo()
- }, 10)
- return
- }
- }
-
- // 更新vuex中的导航栏信息
- this && this.$t.vuex('vuex_status_bar_height', statusBarHeight)
- this && this.$t.vuex('vuex_custom_bar_height', customBarHeight)
-
- this.customBarHeight = customBarHeight
- this.statusBarHeight = statusBarHeight
- },
- // 处理返回事件
- async handlerBack() {
- if (this.beforeBack && typeof(this.beforeBack) === 'function') {
- // 执行回调,同时传入索引当作参数
- // 在微信,支付宝等环境(H5正常),会导致父组件定义的函数体中的this变成子组件的this
- // 通过bind()方法,绑定父组件的this,让this的this为父组件的上下文
- let beforeBack = this.beforeBack.bind(this.$t.$parent.call(this))()
- // 判断是否返回了Promise
- if (!!beforeBack && typeof beforeBack.then === 'function') {
- await beforeBack.then(res => {
- // Promise返回成功
- this.navBack()
- }).catch(err => {})
- } else if (beforeBack === true) {
- this.navBack()
- }
- } else {
- this.navBack()
- }
- },
- // 返回上一页
- navBack() {
-
- // 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页
- const pages = getCurrentPages()
- if (pages && pages.length > 0) {
- const firstPage = pages[0]
- if (pages.length == 1 && (!firstPage.route || firstPage.route != 'pages/index/index')) {
- uni.reLaunch({
- url: '/pages/index/index'
- })
- } else {
- uni.navigateBack({
- delta: 1
- })
- }
- } else {
- uni.reLaunch({
- url: '/pages/index/index'
- })
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
-
- .tn-custom-nav-bar {
- display: block;
- position: relative;
-
- &__bar {
- display: flex;
- position: relative;
- align-items: center;
- min-height: 100rpx;
- justify-content: space-between;
- min-height: 0px;
- /* #ifdef MP-WEIXIN */
- padding-right: 220rpx;
- /* #endif */
- /* #ifdef MP-ALIPAY */
- padding-right: 150rpx;
- /* #endif */
- box-shadow: 0rpx 0rpx 0rpx;
- z-index: 9999;
-
- &--fixed {
- position: fixed;
- width: 100%;
- top: 0;
- }
-
- &--alpha {
- background: transparent !important;
- box-shadow: none !important;
- }
-
- &--bottom-shadow {
- box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.05);
- }
-
- &__action {
- display: flex;
- align-items: center;
- height: 100%;
- justify-content: center;
- max-width: 100%;
-
- &--nav-back {
- /* position: absolute; */
- /* top: 50%; */
- /* left: 20rpx; */
- /* margin-top: -15rpx; */
- // width: 25rpx;
- // height: 25rpx;
- margin-left: 20rpx;
- font-size: 38rpx;
- line-height: 100%;
- // border-width: 0 0 4rpx 4rpx;
- // border-color: #000000;
- // border-style: solid;
- // transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
- }
-
- &--nav-back-text {
- margin-left: 10rpx;
- }
- }
-
- &__content {
- position: absolute;
- text-align: center;
- left: 0;
- right: 0;
- bottom: 0;
- margin: auto;
- font-size: 32rpx;
- cursor: none;
- // pointer-events: none;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- }
- }
- }
-
- </style>
|