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 相关文章推荐
jquery选择checked在ie8普通模式下的问题
Feb 12 Javascript
ExtJS4如何给同一个formpanel不同的url
May 02 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
Sep 27 Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
Aug 25 Javascript
JS 实现 ajax 异步浏览器兼容问题
Jan 21 Javascript
基于JQuery和原生JavaScript实现网页定位导航特效
Apr 03 jQuery
Ionic + Angular.js实现图片轮播的方法示例
May 21 Javascript
浅谈开发eslint规则
Oct 01 Javascript
微信小程序实现文字跑马灯
May 26 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
vue 解决遍历对象显示的顺序不对问题
Nov 07 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
May 15 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数据库开发知多少
2006/10/09 PHP
php读取目录所有文件信息dir示例
2014/03/18 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
php生成条形码的图片的实例详解
2017/09/13 PHP
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
有趣的JavaScript数组长度问题代码说明
2011/01/20 Javascript
js左侧三级菜单导航实例代码
2013/09/13 Javascript
动态加载脚本提升javascript性能
2014/02/24 Javascript
微信中一些常用的js方法汇总
2015/03/12 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
JS创建事件的三种方法(实例代码)
2016/05/12 Javascript
星期几的不同脚本写法(推荐)
2016/06/01 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
jQuery Easyui使用(二)之可折叠面板动态加载无效果的解决方法
2016/08/17 Javascript
原生js的RSA和AES加密解密算法
2016/10/08 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
基于JS实现9种不同的面包屑和分布式多步骤导航效果
2017/02/21 Javascript
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
Vue 表情包输入组件的实现代码
2019/01/21 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
Python random模块(获取随机数)常用方法和使用例子
2014/05/13 Python
Python查找函数f(x)=0根的解决方法
2015/05/07 Python
Django的session中对于用户验证的支持
2015/07/23 Python
Python实现压缩与解压gzip大文件的方法
2016/09/18 Python
在python中对变量判断是否为None的三种方法总结
2019/01/23 Python
涂鸦板简单实现 Html5编写属于自己的画画板
2016/07/05 HTML / CSS
九州传奇上机题
2014/07/10 面试题
新闻专业大学生找工作的自我评价
2013/10/30 职场文书
师德师风自我剖析材料
2014/09/27 职场文书
幼儿园校园小喇叭广播稿
2014/10/17 职场文书
代办出身证明书
2014/10/21 职场文书
会议通知范文
2015/04/15 职场文书
叶问观后感
2015/06/15 职场文书
Redis基本数据类型Set常用操作命令
2022/06/01 Redis