案例:
结果:(超出预期了,不光做了一个定宽的,还附带了一个不定宽,给自己鼓掌~)
先分析下需求,在选项卡中,选中的选项顶部会带有一个线条,然后在鼠标hover时这个线条会滑动到相应的选项,这时如果选中了,线条会停留在选中的选项,如果没选中,那么它会滑回到之前的位置(也就是被选中的选项会一直有这个线条)
了解了需求之后,发现这个线条由于是需要滑动的(脱离元素自身),所以不能用元素的border属性或者伪类来实现。
那我第一个想到的就是写一个独立的元素,通过定位来实现。
选项卡一般都用ul来实现,这里也不例外,先写主体部分
<ul class="noqLengthUl">
<span class="navBg"></span>
<li v-for="(item, index) in noqtab" :key="item.id"
:class="{active: index == nowIndex}"
@click="changeTab($event, index)">
<a href="javascript:;">{{item.value}}</a>
</li>
</ul>
style部分就省略了,这个太简单。注意:li是定宽的!!!
看一下vue的data部分
nowIndex: 0,
noqtab: [
{
id: 'noqtab1',
value: '网站首页'
},
{
id: 'noqtab2',
value: '学习那事'
},
{
id: 'noqtab3',
value: '娱乐这事'
},
{
id: 'noqtab4',
value: '关于我们'
},
{
id: 'noqtab5',
value: '产品中心'
},
{
id: 'noqtab6',
value: '联系我们'
}
]
看下效果
此时这是一个最常见的选项卡,选中哪个,哪个就会有一个样式添加上,让它与其他选项不同。网站首页上面的线条就是咱们的主角,首先给他定位在 ul left:0的位置,因为是定宽所以宽度写好和li一致就行 ,下一步就是让它跟随鼠标hover来滑动。
既然是hover,那就是鼠标事件,因为在vue中没有hover事件,所以这里我用了@mouseenter 和 @mouseleave来实现。
因为选项卡是定宽的,所以在鼠标进入和离开时只需要改变它的left即可,具体方法如下:
changeBgPos(el, index){
this.$refs.noNavBg.style.left = `${(index)*90}px`;
},
backBgPos(el, index){
let bgLeft = document.querySelector(".noqLengthUl li.active").offsetLeft;
this.$refs.noNavBg.style.left = `${bgLeft}px`;
},
这里是通过 ref 配合 $refs 来实现的,在HTML中添加事件
<ul class="noqLengthUl">
<span class="navBg" ref="noNavBg"></span>
<li v-for="(item, index) in noqtab" :key="item.id" :class="{active: index == nowIndex}"
@click="changeTab($event, index)" @mouseenter="changeBgPos($event, index)" @mouseleave="backBgPos($event, index)">
<a href="javascript:;">{{item.value}}</a>
</li> :class="{active: index == nowIndex}"
</ul>
最终结果就是这啦!
那么,不定宽的选项卡要怎么做呢?这个问题就先留给大家自己思考趴 ~