工作需要做一个带滑块效果的导航栏,初步想法是用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;
出现数据,至此组件效果基本实现,代码结构稍显混乱,感觉有很大的优化空间,望各位大佬提出建议~
原文地址:https://www.cnblogs.com/Keyrt/p/10910511.html
时间: 2024-10-08 12:28:39