|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <!-- 切换的tabBar -->
- <template>
- <view class="tab-bar" @touchmove.stop.prevent="()=>{}">
- <scroll-view id="nav-bar" class="noScorll bar-view" scroll-x :scroll-left="data.scrollLeft">
- <view v-for="(item,index) in tabs" :key="item.id" :class="{active:index === curIndex}" class="bar-item"
- :style="{width: `${data.itemWidth}px`}" @click="changeTab(index)">
- {{item.name}}
- </view>
- </scroll-view>
- </view>
- </template>
-
- <script setup lang="ts">
- import { ref, watch, reactive, PropType } from 'vue'
-
- const emit = defineEmits(['update:curIndex', 'index'])
- const props = defineProps({
- //当前选中的下标
- curIndex: {
- type: Number,
- default: 0
- },
- //标签选项数组
- tabs: {
- type: Array as PropType<{ id : number; name : string }[]>,
- default: () => []
- }
- })
-
- const data = reactive({
- scrollLeft: 0, //顶部选项卡左滑距离
- windowWidth: uni.getSystemInfoSync().windowWidth, //屏幕宽度
- itemWidth: uni.upx2px(150), //每个标签的宽度 默认150rpx
- })
-
- /* 查看父组件传过来的值是否变化,从而修改值 */
- const curIndex = ref(props.curIndex)
- watch(() => props.curIndex, (val) => {
- curIndex.value = val
- });
-
- /*监听标签数组变化,来计算每个标签占的宽度*/
- watch(() => props.tabs, (newVal) => {
- if (newVal && newVal.length < 5) {
- data.itemWidth = data.windowWidth / newVal.length
- }
- }, { immediate: true });
-
-
- /* 改变tab refresh:点击同个tab是否刷新*/
- const changeTab = (index, refresh ?: boolean) => {
- if (refresh) {
- console.log("index111", index)
- uni.$emit("refreshOrder");
- return;
- }
- if (props.curIndex != index) {
- emit('update:curIndex', index)
- console.log("index222", index)
- emit('index', index)
- }
- }
-
- defineExpose({
- changeTab
- })
- </script>
-
- <style lang="scss">
- .tab-bar {
- width: 100%;
- background-color: white;
- padding-bottom: 8rpx;
- box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(223, 223, 223, 0.8);
-
- .bar-view {
- width: 100%;
- text-align: center;
- background-color: white;
- white-space: nowrap;
- position: sticky;
- top: 0;
-
- .bar-item {
- flex: 1; //平均分配
- font-size: 28rpx;
- line-height: 80rpx;
- position: relative;
- display: inline-block;
- min-width: 150rpx;
-
- &:after {
- position: absolute;
- content: '';
- width: 0;
- height: 0;
- border-bottom: 6rpx solid #00B38B;
- left: 50%;
- bottom: 18rpx;
- z-index: -99;
- height: 16rpx;
- background: #00b38b;
- opacity: 0.3;
- transform: translateX(-50%);
- transition: .3s;
- }
- }
-
- .active {
- font-weight: bold;
- font-size: 30rpx;
-
- &:after {
- width: 70%;
- border-radius: 6rpx;
- }
-
- &:first-child {
- &:after {
- width: 50%;
- }
- }
-
- &:last-child {
- &:after {
- width: 95%;
- }
- }
- }
- }
- }
- </style>
|