| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- <template>
- <div :class="{'box_tab':props.tabType == 'box','line_tab':props.tabType == 'line'}">
- <span
- v-for="item in props.tabList"
- :key="item.key"
- :class="{
- 'selected': activedId == item.key,
- 'un_selected': activedId !== item.key,
- 'prefix':item.prefix,
- 'disabled':disabled
- }"
- @click="disabled ? '' : HandleTabChange(item.key)"
- >
- <img v-if="item.prefix" :src="activedId==item.key ? item.prefixLight : item.prefix" alt="" class="prefix" />
- {{ item.label }}
- <span v-if="item.suffix || item.suffix === 0" class="suffix">{{item.suffix}}</span>
- </span>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, watch} from 'vue';
- interface TabItem {
- label:String,
- key:String,
- prefix?:String,
- prefixLight?:String,
- suffix?:String,
- }
- type TabType = 'box'|'line'
- const props = defineProps({
- tabList:{
- required:true,
- type:Array<TabItem>
- },
- tabType:{
- required:true,
- type:String
- },
- defaultTabKey:{
- required:true,
- type:String
- },
- disabled:{
- type:Boolean,
- default:false
- }
- })
- const emit = defineEmits(['tabChange'])
- const activedId = ref(props.defaultTabKey)
- watch([()=>props.defaultTabKey,()=>props.tabList],([newVal,newValList])=>{
- activedId.value = newVal
- },{immediate:true,deep:true})
- const HandleTabChange = async (params) =>{
- activedId.value = params
- emit('tabChange',activedId.value)
- }
- </script>
- <style lang="scss" scoped>
-
- .box_tab {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- font-size: 14px;
- > span{
- height: 36px;
- display: flex;
- gap:4px;
- justify-content: center;
- align-items: center;
- line-height: 1.5 !important;
- padding:7px 12px;
- cursor: pointer;
- .prefix{
- width: 16px;
- height: 16px;
- }
- }
- .un_selected{
- border: 1px solid #dcdfe6;
- color: #666;
- }
-
- .selected{
- background: #2E64FA;
- color: #fff;
- + span{
- border-left: transparent;
- }
- &.prefix{
- background-color: rgba(46, 100, 250,0.1);
- color:rgba(46, 100, 250);
- border:solid #2E64FA 1px;
- }
- }
- > span:nth-child(1){
- border-radius: 4px 0 0 4px;
- }
- > span:last-child{
- border-radius:0 4px 4px 0;
- }
- >span:nth-child(n):not(:last-child):not(.selected){
- border-right: transparent;
- }
- }
- .line_tab{
- display: flex;
- gap:24px;
- padding-bottom: 10px;
- color:#666666;
- font-size:14px;
- >span{
- cursor: pointer;
- }
- .selected{
- position: relative;
- color: #2E64FA;
- font-weight: bold;
- &::after{
- position: absolute;
- left: 0;
- bottom: -10px;
- content:'';
- width: 100%;
- height: 2px;
- background-color: #2E64FA;
- }
- }
- }
- .box_tab,
- .line_tab{
- .disabled{
- cursor: not-allowed;
- }
- }
- </style>
|