vue實(shí)現(xiàn)導(dǎo)航欄效果(選中狀態(tài)刷新不消失)
Vue導(dǎo)航欄
用Vue寫手機(jī)端的項(xiàng)目,經(jīng)常會(huì)寫底部導(dǎo)航欄,我這里總結(jié)一套比較方便實(shí)用的底部導(dǎo)航欄方法,并且可以解決瀏覽器刷新選中狀態(tài)消失的問(wèn)題。也可以選擇自適應(yīng)屏幕??匆幌滦Ч撞康膱D標(biāo)全是UI給的選中和未選中樣式的圖片,根據(jù)公司要求,你也可能會(huì)用fontsize去寫。(全部代碼黏貼到本文的最后面了)

1、首先把這些小圖片放到src/assets路徑下面(自動(dòng)base64編碼)


2、在data()里邊定義一個(gè)選中對(duì)應(yīng)的變量isSelect,和循環(huán)遍歷的數(shù)組,數(shù)組下面放圖標(biāo)對(duì)應(yīng)的文字,和選中,未選中的圖片地址。 注意:圖片的地址不要直接寫,直接寫就是字符串,不僅會(huì)出現(xiàn)顯示不出圖片的情況,而且打包之后,還是這里地址,不會(huì)變。使用webpack提供的require引入圖片地址就可以解決以上問(wèn)題。
data () {
return {
isSelect: '首頁(yè)',
nav: [
{title: '首頁(yè)', url: require('../../assets/common/首頁(yè)@2x.png'), url_one: require('../../assets/common/首頁(yè)_active@2x.png')},
{title: '店鋪', url: require('../../assets/common/店鋪@2x.png'), url_one: require('../../assets/common/店鋪_active@2x.png')},
{title: '創(chuàng)業(yè)直播', url: require('../../assets/common/直播@2x.png'), url_one: require('../../assets/common/直播_active@2x.png')},
{title: '我的', url: require('../../assets/common/我的@2x.png'), url_one: require('../../assets/common/我的_active@2x.png')}
]
}
},
html遍歷這個(gè)nav數(shù)組,并且給每個(gè)li注冊(cè)點(diǎn)擊事件selectNav(),參數(shù)就是title。
<ul>
<li v-for="item in nav" @click="selectNav(item.title)">
<img :src="isSelect === item.title ? item.url_one : item.url" alt="item.title">
<p :class="isSelect === item.title ? 'active' : ''">{{item.title}}</p>
</li>
</ul>
在methods中定義這個(gè)事件
methods: {
selectNav (title) {
this.isSelect = title
}
3、這個(gè)方法里還可以根據(jù)title的值去跳轉(zhuǎn)到相應(yīng)的路由,這樣一個(gè)基本的底部導(dǎo)航欄就是實(shí)現(xiàn)了。
methods: {
selectNav (title) {
this.isSelect = title
switch (title) {
case '首頁(yè)': this.$router.push('/index')
break
case '店鋪': this.$router.push('/shop')
break
case '創(chuàng)業(yè)直播': this.$router.push('/live')
break
case '我的': this.$router.push('/my')
break
}
sessionStorage.setItem('isSelect', this.isSelect)
}
}
但是電腦調(diào)試的時(shí)候會(huì)發(fā)現(xiàn),刷新瀏覽器后,選中的狀態(tài)就會(huì)消失。(你可能會(huì)覺(jué)得用戶一般不會(huì)在手機(jī)端刷新頁(yè)面/或者直接輸入路由跳轉(zhuǎn)到相應(yīng)的頁(yè)面,如果要追求完美的,請(qǐng)繼續(xù)往下看)比如,我選中的狀態(tài)是創(chuàng)業(yè)直播:

當(dāng)我點(diǎn)擊刷新頁(yè)面后,就會(huì)返回到默認(rèn)的首頁(yè)狀態(tài),如下。

解決辦法:
每次點(diǎn)擊切換底部導(dǎo)航的時(shí)候,把選中的狀態(tài)存入sessStorage里邊。在mounted鉤子里把這個(gè)狀態(tài)取出來(lái)賦值給這個(gè)isSelect變量就可以實(shí)現(xiàn)選中狀態(tài)不消失了。
mounted () {
this.isSelect = sessionStorage.getItem('isSelect')
},
methods: {
selectNav (title) {
this.isSelect = title
sessionStorage.setItem('isSelect', this.isSelect)
}
}
經(jīng)過(guò)測(cè)試,新的問(wèn)題又發(fā)現(xiàn)了,比如當(dāng)前在“創(chuàng)業(yè)直播”這個(gè)狀態(tài)上,我在瀏覽器上直接輸入“http://localhost:8080/#/shop”,這樣用上面的辦法就解決不了問(wèn)題了。最好的辦法就是和路由綁定無(wú)論點(diǎn)擊,還是瀏覽器上輸入路由改變,都正確顯示選中狀態(tài)。
在router/index.js里邊映射組件路由時(shí),加上對(duì)應(yīng)的name
routes: [
{
path: '/',
redirect: '/index'
},
{
path: '/index',
name: '首頁(yè)',
component: index
},
{
path: '/live',
name: '創(chuàng)業(yè)直播',
component: live
},
{
path: '/my',
name: '我的',
component: my
},
{
path: '/shop',
name: '店鋪',
component: shop
}
]
mounted鉤子里邊的代碼改為:
mounted () {
this.isSelect = this.$route.name
},
methods方法里邊的代碼修改為
4、手機(jī)端一般要求自適應(yīng)各種大小的手機(jī)端屏幕,你可以選擇用媒體查詢,或者js控制font-size。這里我用的是js控制font-size,在index.html引入下面的js。
* rem計(jì)算方式:設(shè)計(jì)圖尺寸px / 100 = 實(shí)際rem 【例: 100px = 1rem,32px = .32rem】
*/
!function (window) {
/* 設(shè)計(jì)圖文檔寬度 */
var docWidth = 750;
var doc = window.document,
docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var recalc = (function refreshRem () {
var clientWidth = docEl.getBoundingClientRect().width;
/* 8.55:小于320px不再縮小,11.2:大于420px不再放大 */
docEl.style.fontSize = Math.max(Math.min(20 * (clientWidth / docWidth), 11.2), 8.55) * 5 + 'px';
return refreshRem;
})();
/* 添加倍屏標(biāo)識(shí),安卓為1 */
docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1);
if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
/* 添加IOS標(biāo)識(shí) */
doc.documentElement.classList.add('ios');
/* IOS8以上給html添加hairline樣式,以便特殊處理 */
if (parseInt(window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/)[1], 10) >= 8)
doc.documentElement.classList.add('hairline');
}
if (!doc.addEventListener) return;
window.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
}(window);
使用方法:
把視覺(jué)稿中的px轉(zhuǎn)換成rem;
rem計(jì)算方式:設(shè)計(jì)圖尺寸px / 100 = 實(shí)際rem 【例: 100px = 1rem,32px = 0.32rem】;
特別注意:是不需要再除以2的!
無(wú)論設(shè)計(jì)圖什么尺寸,算法一致。但需修改js 中 docWidth 變量為設(shè)計(jì)圖寬度;默認(rèn)設(shè)計(jì)圖文檔寬度為750px; 一些不使用rem的CSS屬性。包括但不限于:border-width、border-radius、box-shadow、transform、background-size;
附錄底部導(dǎo)航欄的代碼(樣式使用了less預(yù)編譯):
<template>
<div class="common_foot">
<ul>
<li v-for="item in nav" @click="selectNav(item.title)">
<img :src="isSelect === item.title ? item.url_one : item.url" alt="item.title">
<p :class="isSelect === item.title ? 'active' : ''">{{item.title}}</p>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
isSelect: '首頁(yè)',
nav: [
{title: '首頁(yè)', url: require('../../assets/common/首頁(yè)@2x.png'), url_one: require('../../assets/common/首頁(yè)_active@2x.png')},
{title: '店鋪', url: require('../../assets/common/店鋪@2x.png'), url_one: require('../../assets/common/店鋪_active@2x.png')},
{title: '創(chuàng)業(yè)直播', url: require('../../assets/common/直播@2x.png'), url_one: require('../../assets/common/直播_active@2x.png')},
{title: '我的', url: require('../../assets/common/我的@2x.png'), url_one: require('../../assets/common/我的_active@2x.png')}
]
}
},
mounted () {
this.isSelect = this.$route.name
},
methods: {
selectNav (title) {
this.isSelect = this.$route.name
switch (title) {
case '首頁(yè)': this.$router.push('/index')
break
case '店鋪': this.$router.push('/shop')
break
case '創(chuàng)業(yè)直播': this.$router.push('/live')
break
case '我的': this.$router.push('/my')
break
}
}
}
}
</script>
<style lang="less" scoped>
.common_foot>ul{
position: fixed;
bottom: 0;
z-index: 1000;
height: 0.98rem;
width: 100%;
overflow: hidden;
background-color: white;
li{
float: left;
width: 25%;
height: 100%;
text-align: center;
cursor: pointer;
padding: 0.15rem 0 0.13rem 0;
}
p{font-size: 0.2rem;color: #7f7f7f;}
img{
width: 0.48rem;
height: 0.45rem;
}
.active{
color: #ffd100;
}
}
</style>
本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。
關(guān)于vue.js組件的教程,請(qǐng)大家點(diǎn)擊專題vue.js組件學(xué)習(xí)教程進(jìn)行學(xué)習(xí)。
更多vue學(xué)習(xí)教程請(qǐng)閱讀專題《vue實(shí)戰(zhàn)教程》
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Vue實(shí)現(xiàn)自定義下拉菜單功能
- 詳解Vue用自定義指令完成一個(gè)下拉菜單(select組件)
- vue下拉菜單組件(含搜索)的實(shí)現(xiàn)代碼
- vue實(shí)現(xiàn)帶過(guò)渡效果的下拉菜單功能
- vue實(shí)現(xiàn)下拉菜單樹(shù)
- 解決vue動(dòng)態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問(wèn)題
- vue實(shí)現(xiàn)nav導(dǎo)航欄的方法
- vue使用ElementUI時(shí)導(dǎo)航欄默認(rèn)展開(kāi)功能的實(shí)現(xiàn)
- Vue實(shí)現(xiàn)導(dǎo)航欄菜單
- vue實(shí)現(xiàn)導(dǎo)航欄下拉菜單
相關(guān)文章
vue使用ArcGis?API?for?js創(chuàng)建地圖實(shí)現(xiàn)示例
這篇文章主要為大家介紹了vue使用ArcGis?API?for?js創(chuàng)建地圖實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Vue項(xiàng)目中token驗(yàn)證登錄(前端部分)
這篇文章主要為大家詳細(xì)介紹了Vue項(xiàng)目中token驗(yàn)證登錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Vue.set()和this.$set()使用和區(qū)別
我們發(fā)現(xiàn)Vue.set()和this.$set()這兩個(gè)api的實(shí)現(xiàn)原理基本一模一樣,那么Vue.set()和this.$set()的區(qū)別是什么,本文詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06
vue路由切換之淡入淡出的簡(jiǎn)單實(shí)現(xiàn)
今天小編就為大家分享一篇vue路由切換之淡入淡出的簡(jiǎn)單實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
vue cli實(shí)現(xiàn)項(xiàng)目登陸頁(yè)面流程詳解
CLI是一個(gè)全局安裝的npm包,提供了終端里的vue命令。它可以通過(guò)vue create快速搭建一個(gè)新項(xiàng)目,或者直接通過(guò)vue serve構(gòu)建新想法的原型。你也可以通過(guò)vue ui通過(guò)一套圖形化界面管理你的所有項(xiàng)目2022-10-10
vue router中mode history、base的作用說(shuō)明
這篇文章主要介紹了vue router中mode history、base的作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Ant Design Vue pro 動(dòng)態(tài)路由的實(shí)現(xiàn)和打包方式
這篇文章主要介紹了Ant Design Vue pro 動(dòng)態(tài)路由的實(shí)現(xiàn)和打包方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
vue-router的導(dǎo)航守衛(wèi)使用最新講解
這篇文章主要介紹了vue-router的導(dǎo)航守衛(wèi)使用講解,vue-router提供了許多編程式導(dǎo)航的API,其中最常見(jiàn)的導(dǎo)航API有很多種,本文給大家詳細(xì)講解,需要的朋友可以參考下2022-12-12
如何在Vue.js中實(shí)現(xiàn)標(biāo)簽頁(yè)組件詳解
這篇文章主要給大家介紹了關(guān)于如何在Vue.js中實(shí)現(xiàn)標(biāo)簽頁(yè)組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01

