You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

387 lines
8.1 KiB
Vue

2 years ago
<template>
<view @touchmove.stop.prevent="stop">
<view class="tui-bottom-navigation" :class="{ 'tui-navigation-fixed': isFixed, 'tui-remove-splitLine': unlined }">
<view
class="tui-navigation-item"
:class="{ 'tui-item-after_height': splitLineScale, 'tui-last-item': index == itemList.length - 1 }"
:style="{ backgroundColor: isDarkMode ? '#202020' : backgroundColor }"
v-for="(item, index) in itemList"
:key="index"
>
<view class="tui-item-inner" @tap="menuClick(index, item.parameter, item.type)">
<image
:src="getIcon(current,index, item)"
class="tui-navigation-img"
v-if="item.iconPath || (current == index && item.selectedIconPath && item.type == 1)"
></image>
<text
class="tui-navigation-text"
:style="{
color: isDarkMode ? '#fff' : current == index && item.type == 1 ? selectedColor : item.color || color,
fontWeight: current == index && bold && item.type == 1 ? 'bold' : 'normal',
fontSize: fontSize
}"
>
{{ item.text }}
</text>
</view>
<view
class="tui-navigation-popup"
:class="{ 'tui-navigation-popup_show': showMenuIndex == index }"
:style="{ backgroundColor: isDarkMode ? '#4c4c4c' : subMenuBgColor, left: item.popupLeft || '50%' }"
v-if="item.itemList"
>
<view
class="tui-popup-cell"
:class="{ 'tui-first-cell': subIndex === 0, 'tui-last-cell': subIndex === item.itemList.length - 1 }"
:hover-class="subMenuHover ? (isDarkMode ? 'tui-item-dark_hover' : 'tui-item-hover') : ''"
:hover-stay-time="150"
v-for="(subItem, subIndex) in item.itemList || []"
:key="subIndex"
@tap="subMenuClick(index, item.type, subIndex, subItem.parameter || '')"
>
<text class="tui-ellipsis" :style="{ color: isDarkMode ? '#fff' : subMenuColor, fontSize: subMenufontSize, lineHeight: subMenufontSize }">
{{ subItem.text }}
</text>
</view>
<view class="tui-popup-triangle" :style="{ borderTopColor: isDarkMode ? '#4c4c4c' : subMenuBgColor }"></view>
</view>
</view>
</view>
<view class="tui-navigation-mask" :class="{ 'tui-navigation-mask_show': showMenuIndex != -1 }" @tap="handleClose"></view>
</view>
</template>
<script>
export default {
name: 'tuiBottomNavigation',
emits: ['click'],
props: {
//当前索引
current: {
type: Number,
default: 0
},
/**
* {
text: 'ThorUI',
iconPath: '/static/images/common/icon_menu_gray.png',
selectedIconPath: '/static/images/common/icon_menu_gray.png',
color: '#666',
//1-选中切换2-跳转、请求、其他操作3-菜单
type: 3,
//自定义参数,类型自定义
parameter: null,
//子菜单left值,不传默认50%,当菜单贴近左右两边可用此参数调整
popupLeft: '',
itemList: [
{
//不建议超过6个字请自行控制
text: '自定义参',
//自定义参数,类型自定义
parameter: null
},
{
text: '自定义参数',
//自定义参数,类型自定义
parameter: null
}
]
}
*
* */
itemList: {
type: Array,
default: () => {
return [];
}
},
//颜色
color: {
type: String,
default: '#666'
},
//选中颜色
selectedColor: {
type: String,
default: '#5677fc'
},
fontSize: {
type: String,
default: '28rpx'
},
//选中后字体是否加粗
bold: {
type: Boolean,
default: true
},
//导航条背景颜色
backgroundColor: {
type: String,
default: '#F8F8F8'
},
//item分割线高度是否缩小
splitLineScale: {
type: Boolean,
default: true
},
//二级菜单字体颜色
subMenuColor: {
type: String,
default: '#333'
},
//二级菜单字体大小
subMenufontSize: {
type: String,
default: '28rpx'
},
//二级菜单背景色 深色:#4c4c4c
subMenuBgColor: {
type: String,
default: '#fff'
},
//二级菜单是否有点击效果
subMenuHover: {
type: Boolean,
default: true
},
//是否固定在底部
isFixed: {
type: Boolean,
default: true
},
//去除导航栏顶部的线条
unlined: {
type: Boolean,
default: false
},
//是否暗黑模式 (true所有设置颜色失效)
isDarkMode: {
type: Boolean,
default: false
}
},
data() {
return {
showMenuIndex: -1 //显示的菜单index
};
},
methods: {
getIcon: function(current, index, item) {
let url = item.iconPath;
if (item.type == 1) {
url = current == index ? item.selectedIconPath || item.iconPath : item.iconPath;
}
return url;
},
stop() {
return false;
},
handleClose() {
this.showMenuIndex = -1;
},
menuClick(index, parameter, type) {
//type1-选中切换2-跳转、请求、其他操作3-菜单
if (type == 3) {
this.showMenuIndex = this.showMenuIndex == index ? -1 : index;
} else {
this.showMenuIndex = -1;
this.$emit('click', {
menu: 'main', //main,sub 主菜单,子菜单
type: type,
index: index,
parameter: parameter || ''
});
}
},
subMenuClick(index, type, subIndex, parameter) {
this.showMenuIndex = -1;
this.$emit('click', {
menu: 'sub', //main,sub 主菜单,子菜单
type: type,
index: index,
subIndex: subIndex,
parameter: parameter || ''
});
}
}
};
</script>
<style scoped>
.tui-bottom-navigation {
width: 100%;
height: 100rpx;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
z-index: 999;
}
.tui-navigation-fixed {
position: fixed !important;
left: 0;
bottom: 0;
padding-bottom: env(safe-area-inset-bottom);
}
.tui-bottom-navigation::after {
content: '';
width: 100%;
border-top: 1px solid #bfbfbf;
position: absolute;
top: 0;
left: 0;
transform: scaleY(0.5) translateZ(0);
transform-origin: 0 0;
z-index: 1000;
}
.tui-remove-splitLine::before {
border-top: 0 !important;
}
.tui-navigation-item {
flex: 1;
height: 100rpx;
position: relative;
box-sizing: border-box;
}
.tui-item-inner {
width: 100%;
height: 100rpx;
display: flex;
text-align: center;
align-items: center;
justify-content: center;
}
.tui-navigation-item::after {
height: 100%;
content: '';
position: absolute;
border-right: 1px solid #bfbfbf;
transform: scaleX(0.5) translateZ(0);
right: 0;
top: 0;
}
.tui-item-after_height::after {
height: 40% !important;
top: 30% !important;
}
.tui-last-item::after {
border-right: 0 !important;
}
.tui-navigation-img {
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.tui-navigation-popup {
max-width: 160%;
width: auto;
position: absolute;
border-radius: 8rpx;
visibility: hidden;
opacity: 0;
transform: translate3d(-50%, 0, 0);
transform-origin: center;
transition: all 0.12s ease-in-out;
bottom: 0;
z-index: -1;
}
.tui-navigation-popup_show {
transform: translate3d(-50%, -124rpx, 0);
visibility: visible;
opacity: 1;
}
.tui-popup-triangle {
position: absolute;
width: 0;
height: 0;
border-left: 9rpx solid transparent;
border-right: 9rpx solid transparent;
border-top: 18rpx solid;
left: 50%;
bottom: -18rpx;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
z-index: 997;
}
.tui-popup-cell {
width: 100%;
padding: 32rpx 20rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
position: relative;
}
.tui-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tui-popup-cell::after {
content: '';
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
bottom: 0;
right: 24rpx;
left: 24rpx;
}
.tui-item-hover {
background-color: #f1f1f1;
}
.tui-item-dark_hover {
background-color: #555;
}
.tui-first-cell {
border-top-left-radius: 8rpx;
border-top-right-radius: 8rpx;
}
.tui-last-cell {
border-bottom-left-radius: 8rpx;
border-bottom-right-radius: 8rpx;
}
.tui-last-cell::after {
border-bottom: 0 !important;
}
.tui-navigation-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 995;
transition: all 0.3s ease-in-out;
opacity: 0;
visibility: hidden;
background-color: rgba(0, 0, 0, 0);
}
.tui-navigation-mask_show {
opacity: 1;
visibility: visible;
}
</style>