150 lines
2.8 KiB
Vue
150 lines
2.8 KiB
Vue
<template>
|
|
<!-- 自定义顶部返回栏 -->
|
|
<view class="custom-back-header" :style="headerStyle">
|
|
<!-- 返回按钮 -->
|
|
<view class="back-btn" @click="handleBack">
|
|
<slot name="icon">
|
|
<!-- 默认返回图标 -->
|
|
<view class="icon">←</view>
|
|
</slot>
|
|
<text v-if="showText" class="text">{{ backText }}</text>
|
|
</view>
|
|
|
|
<!-- 标题插槽 -->
|
|
<view class="title">
|
|
<slot>{{ title }}</slot>
|
|
</view>
|
|
|
|
<!-- 右侧插槽 -->
|
|
<view class="right-slot">
|
|
<slot name="right"></slot>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
// 标题文字
|
|
title: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 是否显示返回文字
|
|
showText: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
// 返回按钮文字
|
|
backText: {
|
|
type: String,
|
|
default: '返回'
|
|
},
|
|
// 背景颜色
|
|
bgColor: {
|
|
type: String,
|
|
default: '#ffffff'
|
|
},
|
|
// 文字颜色
|
|
color: {
|
|
type: String,
|
|
default: '#333333'
|
|
},
|
|
// 是否沉浸式(占位)
|
|
immersive: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
// 指定返回目标路径
|
|
targetPath: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
computed: {
|
|
headerStyle() {
|
|
return {
|
|
backgroundColor: this.bgColor,
|
|
color: this.color,
|
|
paddingTop: this.immersive ? 'var(--status-bar-height)' : '0'
|
|
};
|
|
}
|
|
},
|
|
methods: {
|
|
handleBack() {
|
|
if (this.$listeners.back) {
|
|
// 如果有自定义back事件则触发
|
|
this.$emit('back');
|
|
return;
|
|
}
|
|
|
|
const pages = getCurrentPages();
|
|
|
|
// 指定目标页面返回
|
|
if (this.targetPath) {
|
|
const target = pages.find(page =>
|
|
page.route === this.targetPath.replace(/^\//, '')
|
|
);
|
|
|
|
if (target) {
|
|
const delta = pages.length - pages.indexOf(target) - 1;
|
|
uni.navigateBack({ delta });
|
|
} else {
|
|
uni.redirectTo({ url: this.targetPath });
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 默认返回逻辑
|
|
if (pages.length >= 2) {
|
|
uni.navigateBack();
|
|
} else {
|
|
uni.switchTab({ url: '/pages/index/index' });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.custom-back-header {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 44px;
|
|
padding: 0 15px;
|
|
position: relative;
|
|
z-index: 999;
|
|
}
|
|
|
|
.back-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 5px 10px 5px 0;
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.icon {
|
|
font-size: 20px;
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.text {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.title {
|
|
flex: 1;
|
|
text-align: center;
|
|
font-size: 17px;
|
|
font-weight: bold;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.right-slot {
|
|
min-width: 60px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
</style> |