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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>