vue实现导航栏效果(选中状态刷新不消失)


Posted in Javascript onDecember 13, 2017

Vue导航栏       

用Vue写手机端的项目,经常会写底部导航栏,我这里总结一套比较方便实用的底部导航栏方法,并且可以解决浏览器刷新选中状态消失的问题。也可以选择自适应屏幕。看一下效果,底部的图标全是UI给的选中和未选中样式的图片,根据公司要求,你也可能会用fontsize去写。(全部代码黏贴到本文的最后面了)

vue实现导航栏效果(选中状态刷新不消失)

1、首先把这些小图片放到src/assets路径下面(自动base64编码)

vue实现导航栏效果(选中状态刷新不消失)
vue实现导航栏效果(选中状态刷新不消失)

2、在data()里边定义一个选中对应的变量isSelect,和循环遍历的数组,数组下面放图标对应的文字,和选中,未选中的图片地址。  注意:图片的地址不要直接写,直接写就是字符串,不仅会出现显示不出图片的情况,而且打包之后,还是这里地址,不会变。使用webpack提供的require引入图片地址就可以解决以上问题。

data () { 
 return { 
 isSelect: '首页', 
 nav: [ 
 {title: '首页', 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')}, 
 {title: '创业直播', 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遍历这个nav数组,并且给每个li注册点击事件selectNav(),参数就是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中定义这个事件

methods: { 
 selectNav (title) { 
 this.isSelect = title 
 }

3、这个方法里还可以根据title的值去跳转到相应的路由,这样一个基本的底部导航栏就是实现了。

methods: { 
 selectNav (title) { 
 this.isSelect = title 
 switch (title) { 
 case '首页': this.$router.push('/index') 
 break 
 case '店铺': this.$router.push('/shop') 
 break 
 case '创业直播': this.$router.push('/live') 
 break 
 case '我的': this.$router.push('/my') 
 break 
 } 
 sessionStorage.setItem('isSelect', this.isSelect) 
 } 
 }

但是电脑调试的时候会发现,刷新浏览器后,选中的状态就会消失。(你可能会觉得用户一般不会在手机端刷新页面/或者直接输入路由跳转到相应的页面,如果要追求完美的,请继续往下看)比如,我选中的状态是创业直播:

vue实现导航栏效果(选中状态刷新不消失)

当我点击刷新页面后,就会返回到默认的首页状态,如下。

vue实现导航栏效果(选中状态刷新不消失)

解决办法:

每次点击切换底部导航的时候,把选中的状态存入sessStorage里边。在mounted钩子里把这个状态取出来赋值给这个isSelect变量就可以实现选中状态不消失了。

mounted () { 
 this.isSelect = sessionStorage.getItem('isSelect') 
 }, 
 methods: { 
 selectNav (title) { 
 this.isSelect = title 
 sessionStorage.setItem('isSelect', this.isSelect) 
 } 
 }

经过测试,新的问题又发现了,比如当前在“创业直播”这个状态上,我在浏览器上直接输入“http://localhost:8080/#/shop”,这样用上面的办法就解决不了问题了。最好的办法就是和路由绑定无论点击,还是浏览器上输入路由改变,都正确显示选中状态。

在router/index.js里边映射组件路由时,加上对应的name

routes: [ 
 { 
 path: '/', 
 redirect: '/index' 
 }, 
 { 
 path: '/index', 
 name: '首页', 
 component: index 
 }, 
 { 
 path: '/live', 
 name: '创业直播', 
 component: live 
 }, 
 { 
 path: '/my', 
 name: '我的', 
 component: my 
 }, 
 { 
 path: '/shop', 
 name: '店铺', 
 component: shop 
 } 
]

mounted钩子里边的代码改为:

mounted () { 
 this.isSelect = this.$route.name 
 },

methods方法里边的代码修改为

4、手机端一般要求自适应各种大小的手机端屏幕,你可以选择用媒体查询,或者js控制font-size。这里我用的是js控制font-size,在index.html引入下面的js。

* rem计算方式:设计图尺寸px / 100 = 实际rem 【例: 100px = 1rem,32px = .32rem】 
 */ 
!function (window) { 
 
 /* 设计图文档宽度 */ 
 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; 
 })(); 
 
 /* 添加倍屏标识,安卓为1 */ 
 docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1); 
 
 if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) { 
 /* 添加IOS标识 */ 
 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);

使用方法:

把视觉稿中的px转换成rem;

 rem计算方式:设计图尺寸px / 100 = 实际rem 【例: 100px = 1rem,32px = 0.32rem】;
特别注意:是不需要再除以2的!

无论设计图什么尺寸,算法一致。但需修改js 中 docWidth 变量为设计图宽度;默认设计图文档宽度为750px; 一些不使用rem的CSS属性。包括但不限于:border-width、border-radius、box-shadow、transform、background-size;

附录底部导航栏的代码(样式使用了less预编译):

<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: '首页', 
 nav: [ 
 {title: '首页', 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')}, 
 {title: '创业直播', 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 '首页': this.$router.push('/index') 
 break 
 case '店铺': this.$router.push('/shop') 
 break 
 case '创业直播': 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前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

更多vue学习教程请阅读专题《vue实战教程》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript asp.net 获取当前超链接中的文本
Apr 14 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
Nov 14 Javascript
jQuery+ajax中getJSON() 用法实例
Dec 22 Javascript
浅谈javascript的Array.prototype.slice.call
Aug 31 Javascript
更高效的使用JQuery 这里总结了8个小技巧
Apr 13 Javascript
简单的js计算器实现
Oct 26 Javascript
使用JS正则表达式 替换括号,尖括号等
Nov 29 Javascript
使用gulp搭建本地服务器并实现模拟ajax
Apr 05 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
Aug 16 Javascript
详解ECMAScript typeof用法
Jul 25 Javascript
layui前端时间戳转化实例
Nov 15 Javascript
使用Node.js实现base64和png文件相互转换的方法
Mar 11 Javascript
仿京东快报向上滚动的实例
Dec 13 #Javascript
Angular2使用vscode断点调试ts文件的方法
Dec 13 #Javascript
vue-router路由懒加载和权限控制详解
Dec 13 #Javascript
JS+canvas画一个圆锥实例代码
Dec 13 #Javascript
JS排序算法之冒泡排序,选择排序与插入排序实例分析
Dec 13 #Javascript
实例分析js事件循环机制
Dec 13 #Javascript
javascript实现QQ空间相册展示源码
Dec 12 #Javascript
You might like
PHP下打开URL地址的几种方法小结
2010/05/16 PHP
简单的php中文转拼音的实现代码
2014/02/11 PHP
php创建、获取cookie及基础要点分析
2015/01/26 PHP
php二维数组合并及去重复的方法
2015/03/04 PHP
CentOS下与Apache连接的PHP多版本共存方案实现详解
2015/12/19 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
基于jQuery的树控件实现代码(asp.net+json)
2010/07/11 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
Node.js和MongoDB实现简单日志分析系统
2015/04/25 Javascript
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
JS 实现倒计时数字时钟效果【附实例代码】
2016/03/30 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
js实现常用排序算法
2016/08/09 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
详解Vue.js入门环境搭建
2017/03/17 Javascript
angularjs中的$eval方法详解
2017/04/24 Javascript
原生js封装添加class,删除class的实例
2017/11/06 Javascript
Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解
2017/12/27 Javascript
[03:57]《不朽》——2015DOTA2国际邀请赛—中国军团出征主题曲MV
2015/07/15 DOTA
Python实现子类调用父类的方法
2014/11/10 Python
Python动态加载模块的3种方法
2014/11/22 Python
Python实现简单的获取图片爬虫功能示例
2017/07/12 Python
Python微医挂号网医生数据抓取
2019/01/24 Python
运用PyTorch动手搭建一个共享单车预测器
2019/08/06 Python
在Sublime Editor中配置Python环境的详细教程
2020/05/03 Python
详解基于Scrapy的IP代理池搭建
2020/09/29 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
热能动力工程毕业生自荐信
2013/11/07 职场文书
红领巾心向党演讲稿
2014/09/10 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
党的群众路线教育实践活动总结材料
2014/10/30 职场文书
高中班主任心得体会
2016/01/07 职场文书
纪检干部学习心得体会
2016/01/23 职场文书
使用php的mail()函数实现发送邮件功能
2021/06/03 PHP
英国数字版游戏销量周榜公布 《小缇娜的奇幻之地》登顶
2022/04/03 其他游戏