赞
踩
在tab上定位一个slider,每次点击的时候获取当前active的tab-item序号,从而获取到其相对于父元素的水平距离,然后把这个距离更新到slider的left属性上。
代码存档↓
- <template>
- <!-- tab组件封装 -->
- <div class="tab" style="margin-top: 10px;" >
- <div
- class="tab-item" v-for="(item, index) in props.tabData" :key="index"
- @click="handleTabChange(index)"
- :ref="el => {if(el)tabs[index] = el}"
- >
- {{ item.label }}
- </div>
- <div class="slider" :style="`left: ${data.sliderPositionX}px`">{{ data.activeLabel }}</div>
- </div>
- </template>
-
- <script setup>
- import {onMounted, reactive, ref} from 'vue'
- //父组件传递来的tab信息
- const props = defineProps({
- tabData:{
- type:Object,
- validator: (value) => {
- return value.hasOwnProperty('label') && value.label !== ''
- }
-
- }
- })
- const emit = defineEmits(['returnCurrentIndex'])
- const data = reactive({
- current: 1, //当前被选中的tab-item序号
- sliderPositionX: 0, //slider X轴方向位置
- windowWidth: window.innerWidth,
- activeLabel:''
- })
- const tabs = ref([])
-
- //更改slider的位置
- function updateSliderPosition(){
- let activeTab = tabs.value[data.current - 1]
- data.sliderPositionX = activeTab.offsetLeft
- data.activeLabel = props.tabData[data.current - 1].label
- console.log('tab', data.sliderPositionX)
- }
-
- function handleTabChange(index){
- data.current = index + 1
- //向父组件返回当前active tab的序号 方便对页面更新
- emit('returnCurrentIndex', data.current)
- updateSliderPosition()
- }
-
- onMounted(() => {
- updateSliderPosition()
- window.addEventListener('resize', () => updateSliderPosition());
- })
-
- </script>
-
- <style scoped lang="scss">
- .tab{
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- margin-bottom: 10px;
- position: relative;
- .tab-item{
- background-color: #353945;
- border: 1px solid #B1B5C3;
- color: #B1B5C3;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- font-size: 14px;
- padding: 8px 16px;
- box-sizing: border-box;
- width: 95px;
- height: 40px;
- margin: 0;
- }
- .tab-item:first-child{
- border-radius: 2px 0 0 2px;
- }
- .tab-item:last-child{
- border-radius: 0 2px 2px 0;
- }
- .slider{
- position: absolute;
- top: 0;
- width: 95px;
- height: 40px;
- transition: left 0.5s;
- box-sizing: border-box;
- background: linear-gradient(to right, #F4A58A, #ED6B4E);
- color:#000;
- border: 1px solid transparent;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
- </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。