170 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Vue
		
	
	
<template>
 | 
						|
  <view>
 | 
						|
    <view :id="'tab-' + props.index" class="ui-tab-item" :class="[{ cur: cur }, tpl]">
 | 
						|
      <view class="ui-tab-icon" :class="props.data.icon" v-if="props.data.icon"></view>
 | 
						|
      <view
 | 
						|
        class="ui-tab-text"
 | 
						|
        :class="[cur ? 'curColor cur' : 'default-color']"
 | 
						|
        :style="[{ color: cur ? titleStyle.activeColor : titleStyle.color }]"
 | 
						|
      >
 | 
						|
        {{ props.data.title }}
 | 
						|
      </view>
 | 
						|
 | 
						|
      <view class="ui-tag badge ml-2" v-if="props.data.tag != null">{{ props.data.tag }}</view>
 | 
						|
    </view>
 | 
						|
    <view
 | 
						|
      v-if="tpl === 'subtitle'"
 | 
						|
      class="item-subtitle ss-flex ss-col-bottom ss-row-center"
 | 
						|
      :style="[{ color: cur ? subtitleStyle.activeColor : subtitleStyle.color }]"
 | 
						|
    >
 | 
						|
      {{ props.data.subtitle }}
 | 
						|
    </view>
 | 
						|
  </view>
 | 
						|
</template>
 | 
						|
 | 
						|
<script>
 | 
						|
  export default {
 | 
						|
    name: 'UiTabItem',
 | 
						|
  };
 | 
						|
</script>
 | 
						|
 | 
						|
<script setup>
 | 
						|
  /**
 | 
						|
   * 基础组件 - uiTabItem
 | 
						|
   */
 | 
						|
  import { computed, onMounted, getCurrentInstance, inject } from 'vue';
 | 
						|
  import sheep from '@/sheep';
 | 
						|
  const vm = getCurrentInstance();
 | 
						|
 | 
						|
  const props = defineProps({
 | 
						|
    data: {
 | 
						|
      type: [Object, String, Number],
 | 
						|
      default() {},
 | 
						|
    },
 | 
						|
    index: {
 | 
						|
      type: Number,
 | 
						|
      default: 0,
 | 
						|
    },
 | 
						|
  });
 | 
						|
 | 
						|
  const emits = defineEmits(['up']);
 | 
						|
 | 
						|
  onMounted(() => {
 | 
						|
    computedQuery();
 | 
						|
    uni.onWindowResize((res) => {
 | 
						|
      computedQuery();
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  function getParent(name) {
 | 
						|
    let parent = vm?.parent;
 | 
						|
    // 无父级返回null
 | 
						|
    if (parent) {
 | 
						|
      let parentName = parent?.type?.name;
 | 
						|
      // 父组件name 为真返回父级,为假循环
 | 
						|
      while (parentName !== name) {
 | 
						|
        parent = parent?.parent;
 | 
						|
        // 存在父级循环,不存在打断循环
 | 
						|
        if (parent) {
 | 
						|
          parentName = parent?.type?.name;
 | 
						|
        } else {
 | 
						|
          return null;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return parent;
 | 
						|
    }
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  const UiTab = getParent('SuTab');
 | 
						|
 | 
						|
  // 获取抛出的数据和方法
 | 
						|
  let uiTabProvide;
 | 
						|
  if (UiTab) {
 | 
						|
    uiTabProvide = inject('suTabProvide');
 | 
						|
  }
 | 
						|
  const cur = computed(() => uiTabProvide?.curValue.value === props.index);
 | 
						|
  const tpl = computed(() => uiTabProvide?.props?.tpl);
 | 
						|
  const subtitleStyle = computed(() => uiTabProvide?.props?.subtitleStyle);
 | 
						|
  const titleStyle = computed(() => uiTabProvide?.props?.titleStyle);
 | 
						|
 | 
						|
  const computedQuery = () => {
 | 
						|
    uni.createSelectorQuery()
 | 
						|
      .in(vm)
 | 
						|
      .select('#tab-' + props.index)
 | 
						|
      .boundingClientRect((data) => {
 | 
						|
        if (data != null) {
 | 
						|
          // 传递到父组件进行计算
 | 
						|
          emits('up', props.index, data);
 | 
						|
        } else {
 | 
						|
          console.log('tab-item data error');
 | 
						|
        }
 | 
						|
      })
 | 
						|
      .exec();
 | 
						|
  };
 | 
						|
</script>
 | 
						|
 | 
						|
<style lang="scss" scoped>
 | 
						|
  .default-color {
 | 
						|
    color: $black;
 | 
						|
  }
 | 
						|
  .ui-tab-item {
 | 
						|
    display: inline-flex;
 | 
						|
    align-items: center;
 | 
						|
    padding: 0 1em;
 | 
						|
    min-height: 1.5em;
 | 
						|
    line-height: 1.5em;
 | 
						|
    position: relative;
 | 
						|
    z-index: 1;
 | 
						|
    opacity: 0.6;
 | 
						|
    transition: opacity 0.3s;
 | 
						|
    min-width: 60px;
 | 
						|
 | 
						|
    .ui-tab-text {
 | 
						|
      width: 100%;
 | 
						|
      text-align: center;
 | 
						|
    }
 | 
						|
 | 
						|
    .ui-tab-icon {
 | 
						|
      margin: 0 0.25em;
 | 
						|
      font-size: 120%;
 | 
						|
    }
 | 
						|
 | 
						|
    &.cur {
 | 
						|
      opacity: 1;
 | 
						|
      font-weight: bold;
 | 
						|
    }
 | 
						|
 | 
						|
    &.btn {
 | 
						|
      .ui-tab-text {
 | 
						|
        transform: scale(0.9);
 | 
						|
        transition: color 0.3s;
 | 
						|
        font-weight: bold;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    &.subtitle {
 | 
						|
      .ui-tab-text {
 | 
						|
        transform: scale(0.9);
 | 
						|
        transition: color 0.3s;
 | 
						|
        font-weight: bold;
 | 
						|
        height: calc(100% - 2.6em);
 | 
						|
        line-height: calc(100% - 2.6em);
 | 
						|
        margin-top: 1.2em;
 | 
						|
        color: $white;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  .item-subtitle {
 | 
						|
    height: 2em;
 | 
						|
    font-size: 22rpx;
 | 
						|
    color: $dark-9;
 | 
						|
    margin-bottom: 0.6em;
 | 
						|
  }
 | 
						|
 | 
						|
  .cur-subtitle {
 | 
						|
    color: var(--ui-BG-Main);
 | 
						|
  }
 | 
						|
</style>
 |