vue+elementui的導航滑塊組件


工作需要做一個帶滑塊效果的導航欄,初步想法是用element的導航組件去做,后面摸坑結合各位大佬的博客初步實現效果,話不多說,直接上代碼,記錄一下爬坑之旅

  1 <template>
  2   <div class="y-nav">
  3     <el-row class="nav">
  4       <el-menu
  5         :default-active="$route.path"
  6         class="el-menu-demo"
  7         mode="horizontal"
  8         @select="handleSelect"
  9         text-color="#fff"
 10       >
 11         <el-menu-item index="/index">
 12           <router-link
 13             to="/"
 14             @mouseover.native="itransition($event )"
 15             @mouseout.native="outtransition($event)"
 16           >首頁</router-link>
 17         </el-menu-item>
 18         <el-menu-item index="/leaderboard/leaderlist">
 19           <router-link
 20             :to="{name:'leaderboard'}"
 21             @mouseover.native="itransition($event )"
 22             @mouseout.native="outtransition($event)"
 23           >排行榜</router-link>
 24         </el-menu-item>
 25         <el-menu-item index="/library">
 26           <router-link
 27             :to="{name:'library'}"
 28             @mouseover.native="itransition($event )"
 29             @mouseout.native="outtransition($event)"
 30           >書庫</router-link>
 31         </el-menu-item>
 32         <el-menu-item index="/recharge">
 33           <router-link
 34             to="/recharge"
 35             @mouseover.native="itransition($event )"
 36             @mouseout.native="outtransition($event)"
 37           >充值</router-link>
 38         </el-menu-item>
 39         <el-menu-item index="/vip">
 40           <router-link
 41             :to="{name:'vip'}"
 42             @mouseover.native="itransition($event )"
 43             @mouseout.native="outtransition($event)"
 44           >VIP專區</router-link>
 45         </el-menu-item>
 46         <el-menu-item index="/institution">
 47           <router-link
 48             to="/institution"
 49             @mouseover.native="itransition($event )"
 50             @mouseout.native="outtransition($event)"
 51           >院校</router-link>
 52         </el-menu-item>
 53         <el-menu-item index="/community">
 54           <router-link
 55             to="/community"
 56             @mouseover.native="itransition($event )"
 57             @mouseout.native="outtransition($event)"
 58           >社區</router-link>
 59         </el-menu-item>
 60         <el-menu-item index="/author">
 61           <router-link
 62             to="/author"
 63             @mouseover.native="itransition($event )"
 64             @mouseout.native="outtransition($event)"
 65           >作者福利</router-link>
 66         </el-menu-item>
 67 
 68         <div class="moveblock" ref="moveblock"></div>
 69       </el-menu>
 70     </el-row>
 71   </div>
 72 </template>
 73 <script>
 74 export default {
 75   data() {
 76     return {};
 77   },
 78   // created() {
 79   //   console.log(document.querySelector(".el-menu>.is-active").offsetLeft);
 80   // },
 81   mounted() {
 82     //獲取menu寬度
 83     let menuwidth = document.querySelector(".el-menu-item.is-active>a")
 84       .offsetWidth;
 85     //獲取li
 86     let liwidth = document.querySelectorAll(".el-menu li");
 87     //背景
 88     let moveblock = document.querySelector(".moveblock");
 89     //設置背景的寬度
 90     // moveblock.style.width = liwidth[0].offsetWidth + "px";
 91     let selfLeft = document.querySelector(".el-menu .is-active").offsetLeft;
 92 
 93     moveblock.style.width = menuwidth + "px";
 94 
 95     let winwidth = document.body.clientWidth;
 96     // console.log("base:" + selfLeft);
 97     moveblock.style.left = selfLeft + 35 + "px";
 98   },
 99   methods: {
100     handleSelect(key, keyPath) {
101       console.log(key, keyPath);
102     },
103     itransition($event) {
104       //為懸浮元素添加hover
105       // $event.currentTarget.className = "router-link-active hover";
106       //獲取元素的left值
107       let left = $event.currentTarget.getBoundingClientRect().left;
108       //獲取移動元素
109       let moveblock = document.querySelector(".moveblock");
110       //獲取可視區域的寬度
111       let winwidth = document.body.clientWidth;
112       if (winwidth > 1200) {
113         moveblock.style.left = left - (winwidth - 1200) / 2 + "px";
114       } else {
115         moveblock.style.left = left + "px";
116       }
117     },
118     outtransition($event) {
119       // $event.currentTarget.className = "router-link-active";
120       //獲取移動元素
121       let moveblock = document.querySelector(".moveblock");
122       //獲取is-active的offsetLeft
123       let selfLeft = document.querySelector(".el-menu .is-active").offsetLeft;
124       // let selfLeft = this.$refs.moveblock.offsetLeft;
125       moveblock.style.left = selfLeft + 35 + "px";
126     }
127   }
128 };
129 </script>
130 <style lang="sass">
131     @import "@/assets/css/public/header/nav.scss";
132 </style>
一、element組件的is-active
:default-active="$route.path"
導航的is-active,當時糾結了好久,百度了好久看到這個辦法,還是不行,后來才注意到要結合
<el-menu-item index="/index">
獲取當前的路由路徑和index中的數據進行對比,添加is-active
 
二、關於刷新后的元素offsetleft問題
   最初的想法是
let selfLeft = document.querySelectorAll(".el-menu .is-active").offsetLeft;
 刷新后發現selfLeft的值為undefined,懷疑是mounted中無法獲取刷新后元素的dom,先后試驗了$nextTick 和setTimeout均無法解決問題,后將整體代碼放到created()中仍未解決問題,
   在created()中直接打印document.querySelectorAll(".el-menu .is-active").offsetLeft;也是現實undefined,document.querySelectorAll(".el-menu .is-active")為一個數組結構,果斷換用
let selfLeft = document.querySelector(".el-menu .is-active").offsetLeft;
 出現數據,至此組件效果基本實現,代碼結構稍顯混亂,感覺有很大的優化空間,望各位大佬提出建議~
 
剛測試的時候發現bug,在子路由下無法匹配is-active,現進行更改
 1 // 將default-active綁定到dfactive上 
 2 <el-menu
 3         :default-active="dfactive"
 4         class="el-menu-demo"
 5         mode="horizontal"
 6         @select="handleSelect"
 7         text-color="#fff"
 8       >
 9 // 截取當前路由第一層路徑的地址
10 data() {
11     return {
12       dfactive:this.$route.path.split("/")[1]
13     };
14   }

這樣就能匹配子路由的鏈接了~~~




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM