vue菜單點擊下劃線跟隨動畫

需求

實現頂部菜單欄,切換時下劃線跟隨滑動

效果

思路

看效果,思路有2:

  1. 方案A:下劃線
    • 設置下劃線 border-bottom
    • 點擊標題後控制下劃線的展示隱藏
    • 注:下劃線長度及圓角無法設置
  2. 方案B:模擬下劃線
    • 新啓元素模,使用背景色擬下劃線效果
    • 點擊標題後,計算要滑動的距離
    • css3動畫移動到目標位置

以上方案對比,發現方案1缺點較大,例如無法控制下劃線長度,圓角,以及下劃線漸變色等。因此採用方案2處理。

實現步驟

本案例基於vue實現

1. 基礎佈局

<div id="app">
    <div class="nav">
        <!-- 標題列表 -->
        <div class="nav-list">
            <div v-for="(item, index) in navList" :key="item">
                {{ item }}
            </div>
        </div>
        <!-- 下劃線 -->
        <div class="nav-line">
            <div :style="{transform: 'translateX(' + translateX + 'px) translateX(-50%)',}"></div>
        </div>
    </div>
</div>
.nav {
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 999;
    background: #fff;
}

.nav .nav-list {
    margin: 0 auto;
    max-width: 600Px;
    display: flex;
    justify-content: space-around;
    align-items: center;
    height: 44px;
}

.nav .nav-list>div {
    font-size: 16px;
    font-family: PingFangSC-Regular, PingFang SC, sans-serif;
    font-weight: 400;
    color: #666;
    line-height: 16px;
    cursor: pointer;
    text-align: center;
}

.nav-line {
    margin: 0 auto;
}

.nav-line>div {
    width: 18px;
    height: 4px;
    border-radius: 2px;
    transition-duration: 0.3s;
    position: relative;
    top: -7px;
}
data: {
    navList: ['首頁', '推薦', '關注', '會員', '消息'],
    translateX: 0
},

運行如下:

2. 添加點擊切換事件及激活的菜單加粗

<!-- 標題列表 -->
<div class="nav-list">
    <div v-for="(item, index) in navList" :key="item" 
+       @click="changeTitle(index)"
+       :class="{ 'nav-list--active': index === active }"
    >
        {{ item }}
    </div>
</div>
/* 新增激活狀態樣式 */
.nav .nav-list .nav-list--active {
    font-family: PingFangSC-Semibold, PingFang SC, sans-serif;
    font-weight: bold;
    color: #333333;
    transition: all 0.3s;
}
data: {
    navList: ['首頁', '推薦', '關注', '會員', '消息'],
    active: 0,
    translateX: 0
},
methods: {
    /** 
    * 點擊切換標題
    * @param {number} index 菜單序列(點擊的第index個)
    */
    changeTitle(index) {
        this.active = index;
        this.setUnderLine();
    },
    /**
    * 設置下劃線
    */
    setUnderLine() {
        // 按照步驟2設置下劃線
    }
},

3. 設置下劃線

/**
* 設置下劃線
*/
setUnderLine() {
+   // 屏幕寬
+   let width = document.documentElement.clientWidth;
+   // 每個菜單所佔寬度 = 屏寬 / 菜單個數
+   let slidingWidth = (width / this.navList.length).toFixed(2);
+   // 半個菜單寬度 (爲了將下劃線與菜單對齊)
+   let halfSlidingWidth = (slidingWidth / 2).toFixed(2);
+   // 水平位移目的座標 = 半個菜單寬度 + (菜單寬 x 當前所在的index)
+   this.translateX = Number(halfSlidingWidth) + Number(slidingWidth * this.active);
}

實現如下效果:

4. bug處理

如上所示,點擊後的效果完成了,但是在初始化的時候,會發現依然有問題。解決方案是在頁面加載後先執行一次setUnderLine方法。

+   mounted() {
+       this.setUnderLine();
+   }

5. 優化

上述方案已基本滿足需求,現提出優化方案:將標題文字及下劃線採用漸變色處理

優化內容:

  1. 下劃線漸變色
  2. 標題文字漸變色
  3. 根據標題個數自適應【已完成】

由於我們在處理的平移距離的時候已經是根據標題個數長度去處理,因此優化3已完成。

5.1 下劃線漸變

由於下劃線是背景色填充的,因此可直接修改背景色爲漸變色:

.nav-line>div {
    width: 18px;
    height: 4px;
    background-color: #4158D0;
+   background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
    border-radius: 2px;
    transition-duration: 0.3s;
    position: relative;
    top: -7px;
}

5.2 文字顏色漸變

.nav .nav-list>div {
    font-size: 16px;
    font-family: PingFangSC-Regular, PingFang SC, sans-serif;
    font-weight: 400;
    color: #666;
    line-height: 16px;
    cursor: pointer;
    text-align: center;
+   background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
+   -webkit-background-clip: text;
+   -webkit-text-fill-color: transparent;
}

5.3 激活文字改顏色

.nav .nav-list .nav-list--active {
    font-family: PingFangSC-Semibold, PingFang SC, sans-serif;
    font-weight: bold;
    color: #333333;
    transition: all 0.3s;
+   background-color: #FFE53B;
+   background-image: linear-gradient(147deg, #FFE53B 0%, #FF2525 74%);
}

最終完成圖例效果

完整代碼關注W信G衆號【流眸】回覆【21601】獲取

小結

案例通過新增元素div來模擬下劃線,點擊時計算水平方向的目的座標,通過CSS動畫實現效果。實現方式難度適中,效果良好,並且可以在一定程度上進行優化擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章