html
<div class="message_type">
<div
class="option_per"
:class="{ option_active: index === messages.index }"
v-for="(item, index) of messages.options"
:key="index"
@click.stop="messages.index = index"
>
{{ item.text }}
</div>
</div>
Vue.js
data() {
return {
messages: {
options: [
{
text: "@我",
},
{
text: "全部",
},
],
index: 0,
},
};
computed: {
centerCssVariable() {
const { index } = this.messages;
const result = {
"--index": index,
};
return result;
},
},
CSS
.message_type {
display: flex;
align-items: center;
justify-content: space-between;
width: 194rpx;
height: 56rpx;
border: 2rpx solid #ffade1;
border-radius: 28rpx;
margin-bottom: 16rpx;
font-size: 22rpx;
box-sizing: border-box;
padding: 6rpx;
position: relative;
&::after {
content: "";
width: 88rpx;
height: 44rpx;
background-color: #ffade1;
border-radius: 22rpx;
box-sizing: border-box;
position: absolute;
top: 0;
bottom: 0;
left: calc(6rpx + (var(--index) * 97rpx));
margin: auto;
transition: left 0.45s;
}
.option_per {
width: 88rpx;
height: 44rpx;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
position: relative;
z-index: 2;
color: transparent;
background-image: linear-gradient(
to right,
#ffade1,
#ffade1 50%,
white 50%,
white 100%
);
-webkit-background-clip: text;
background-position-x: calc(
22rpx + var(--index) * 44rpx
);
transition: background-position 0.3s;
&:nth-child(1) {
background-image: linear-gradient(
to left,
#ffade1,
#ffade1 50%,
white 50%,
white 100%
);
}
}
}
- 上面贴了所有的实现代码,比较关键的代码也加上了注释,copy走可以看效果,感觉实现方式还不是最优解,粉色滑块的移动和文字的颜色渐变并不是同步的 同步的计算有难度就放弃了,如果有更好的实现方法希望可以在下方评论中留言指导