仿照B站制作的滑动导航功能,进行了部分优化,例如可定制默认选中元素,并将选中元素居中显示,可动态更改数据,可定制回调函数取的下标和选中元素内容,可根据需求制作N级联动

已开发成插件,使用方法与源码请前往github------传送门

注:此项目依托于swiper

vue-tabbar-slide.vue

template:

<div class="tabbar-slide-wrapper">
<div class="swiper-container" :class="options.container">
<div class="swiper-wrapper">
<div :style="[slideStyle, {'color': (index == slideOptions.slideIndex) ? slideStyle.checkedColor : slideStyle.color}]" :class="[index == slideOptions.slideIndex ? 'swiper-slide-checked' : '', 'swiper-slide']" v-for="(item, index) in options.slideData" :key="index">{{item}}</div>
<!-- 下划线 -->
<div :style="{width: slideStyle.width, height: downLineStyle.downLineHeight, background: downLineStyle.downLineColor}" ref="slideDownLine" class="slide-down-line"></div>
</div>
</div>
<div class="tabbar-slide-container"></div>
</div>

script:

import Swiper from 'swiper'
import '../../node_modules/swiper/dist/css/swiper.min.css' export default {
name: 'vueTabbarSlide',
props: ['options'],
data () {
return {
mySwiper: null,
//数据
slideArr: this.options.slideData || ['slide1', 'slide2', 'slide3', 'slide4', 'slide5', 'slide6', 'slide7', 'slide8', 'slide9', 'slide10', 'slide11', 'slide12', 'slide13'],
//样式
slideStyle: {
//宽度
width: this.options.width || '80px',
//高度
height: this.options.height || '40px',
//垂直高度
lineHeight: this.options.height || '40px',
//文本排列方式
textAlign: this.options.textAlign || 'center',
//字体大小
fontSize: this.options.fontSize || '14px',
//字体格式
fontFamily: this.options.fontFamily || 'Microsoft YaHei',
//默认字体颜色
color: this.options.color || '#333',
//选中字体颜色
checkedColor: this.options.checkedColor || '#00a0e9'
},
downLineStyle: {
//下划线高度
downLineHeight: this.options.downLineHeight || '2px',
//下划线颜色
downLineColor: this.options.downLineColor || '#00a0e9',
},
//选项
slideOptions: {
slideIndex: this.options.index || 0
},
//下划线
slideDownLine: null
}
},
watch: {
options: {
//此处不要用箭头函数,this会跑偏 ^_^
handler: function(newValue, oldValue) {
if (this.mySwiper) {
this.mySwiper.destroy(true, false)
}
this.mySwiper = new Swiper(`.${this.options.container}`, {
slidesPerView: "auto",
freeMode: true,
freeModeMomentumRatio: 0.5,
observer: true,
observeParents: false,
on: {
init: () => {
//默认选中
this.slideOptions.slideIndex = this.options.index || 0
//下划线
this.$refs.slideDownLine.style.transform = `translateX(${this.slideOptions.slideIndex*parseInt(this.slideStyle.width)}px)`
//回调函数
this.$emit("callback", event, this.slideOptions.slideIndex, this.options.slideData[this.slideOptions.slideIndex])
},
tap: () => {
//滑动时间
this.mySwiper.setTransition(300)
//滑动
this.slide(swiperWidth, maxTranslate, maxWidth)
//更改class
this.slideOptions.slideIndex = this.mySwiper.clickedIndex
//下划线
this.$refs.slideDownLine.style.transform = `translateX(${this.slideOptions.slideIndex*parseInt(this.slideStyle.width)}px)`
//回调函数
this.$emit("callback", event, this.mySwiper.clickedIndex, event.target.innerText)
}
}
});
//swiper可视宽度
const swiperWidth = this.mySwiper.width
//swiper最大移动距离
const maxTranslate = swiperWidth - (parseInt(this.options.width) * this.options.slideData.length)
//
const maxWidth = -maxTranslate + swiperWidth / 2
   },
   deep: true
}
},
methods: {
slide(swiperWidth, maxTranslate, maxWidth) {
//点击的slide
const slide = this.mySwiper.slides[this.mySwiper.clickedIndex]
//点击的slide offsetLeft距离浏览器左边距离
const slideLeft = slide.offsetLeft
//点击的slide的可视宽度
const slideWidth = slide.clientWidth
// 被点击slide的中心点
const slideCenter = slideLeft + slideWidth / 2
//当中心点距离少于一半宽度时
if (slideCenter < swiperWidth / 2) { this.mySwiper.setTranslate(0) } else if (slideCenter > maxWidth) { this.mySwiper.setTranslate(maxTranslate) } else { const nowTlanslate = slideCenter - swiperWidth / 2 this.mySwiper.setTranslate(-nowTlanslate) }
//选中颜色
slide.style.color = this.downLineStyle.downLineColor
}
}
}

App.vue

template:

<div id="app">
<vue-tabbar-slide :options="options" @callback="callback"></vue-tabbar-slide>
<vue-tabbar-slide1 :options="options1" @callback="callback1"></vue-tabbar-slide1> <div @click="getData">点击获取数据</div>
<div>第一行下标及数据{{callbackHtml}},<br>第二行下标及数据{{callbackHtml1}}</div>
</div>

script:

import vueTabbarSlide from './lib/vueTabbarSlide'

export default {
name: 'app',
data () {
return {
options: {
container: 'mySlide1',
slideData: [],
width: '80px',
index: 1
},
options1: {
container: 'mySlide2',
slideData: [],
width: '80px',
index: 1
},
callbackHtml: '',
callbackHtml1: ''
}
},
components: {
vueTabbarSlide: vueTabbarSlide,
vueTabbarSlide1: vueTabbarSlide
},
methods: {
getData () {
this.options.slideData = ['data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7', 'data8', 'data9', 'data10']
this.options1.slideData = ['data11', 'data21', 'data31', 'data41', 'data51', 'data61']
},
callback (event, index, val) {
this.callbackHtml = index + ';' + val
},
callback1 (event, index, val) {
this.callbackHtml1 = index + ';' + val
},
}
}

在使用中有问题请先去github中查看是否更新到最新版本

如果在新版本中未解决,欢迎您在此或github中给我issure,这样会让我开心很长时间,我也会在第一时间认真解决您的问题

最后,感谢您阅读至此。

Vue 仿B站滑动导航的更多相关文章

  1. iOS仿今日头条滑动导航

    之前写了篇博客网易首页导航封装类.网易首页导航封装类优化,今天在前两个的基础上仿下今日头条. 1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问 ...

  2. 2017年11月8日最新仿互站导航t5友价商城-9套模板首页都增加微信登陆

    今天测试效果如下,直接看图吧,入口在下方,点击图片直达 把9套餐模板都添加了微信首页登陆,仿互站的导航,操作比互站还要方便,官方一直对https 支持不太友好,索性把所有的https bug都修复了, ...

  3. 仿腾讯QQ竖直滑动导航菜单

    菜单就像qq软件的分组,鼠标经过自动显示相应组的内容. 效果体验网址:http://keleyi.com/a/bjad/nf86w2dv.htm 以下是源代码: <html> <he ...

  4. (https专业版)2018年1月5日高仿互站仿友价T5虚拟交易+实物交易商城-站长交易源码送手机版程序10套模版+首页微信登陆+头部下拉导航

    (https专业版)2018年1月5日高仿互站仿友价T5虚拟交易+实物交易商城-站长交易源码送手机版程序10套模版+首页微信登陆+头部下拉导航 首页支持微信登陆,只有第8套模板支持(endv模板),后 ...

  5. Nuxt|Vue仿探探/陌陌卡片式滑动|vue仿Tinder拖拽翻牌效果

    探探/Tinder是一个很火的陌生人社交App,趁着国庆假期闲暇时间倒腾了个Nuxt.js项目,项目中有个模块模仿探探滑动切换界面效果.支持左右拖拽滑动like和no like及滑动回弹效果. 一览效 ...

  6. vue 仿今日头条

    vue 仿今日头条 为了增加移动端项目的经验,近一周通过 vue 仿写今日头条,以下就项目实现过程中遇到的问题以及解决方法给出总结,有什么不正确的地方,恳请大家批评指正^ _ ^!,代码仓库地址为 g ...

  7. 我的Vue之旅、05 导航栏、登录、注册 (Mobile)

    第一期 · 使用 Vue 3.1 + TypeScript + Router + Tailwind.css 构建手机底部导航栏.仿B站的登录.注册页面. 代码仓库 alicepolice/Vue-05 ...

  8. jquery仿天猫商城左侧导航菜单

    之前看到有博友写了一个仿天猫商城左侧导航菜单,可惜不提供免费下载,也没有代码.以前自己也写过类似的效果,只是都是一小块一小块的,现在重新拼凑.我将一步一步的实现拼凑过程,希望对你有所帮助. Demo在 ...

  9. 一款基于jQuery的仿百度首页滑动选项卡

    今天给大家分享一款基于jQuery的仿百度首页滑动选项卡.这款选项卡适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览   ...

随机推荐

  1. (七十五)CoreLocation(一)在iOS7和iOS8设备上获取授权

    苹果在iOS8上更新了CoreLocation的授权获取方式,在原来的基础上,不仅需要调用授权函数,还需要对info.plist进行相应的配置. 在iOS上获取经纬度使用的是CoreLocationM ...

  2. java设计模式---备忘录模式

    一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...

  3. iOS平台添加Google Admob -1/2(Unity3D开发之七)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=567 Unity调用iOS还是非 ...

  4. mysql filesort 的解决方案

    在explain我们所使用的sql的时候,经常会遇到using filesort这种情况,原以为是由于有相同列值的原因引起,结果昨天看到公司的一个sql,跟同事讨论了下加上自己又做了一些测试,突然发现 ...

  5. 调用awk的三种方式

    调用awk的三种方式 调用awk有三种方式,一种为Shell命令行方式,另外两种是将awk程序写入脚本文件,然后执行该脚本文件.三种方式的命令格式归纳如下: 一.在Shell命令行输入命令调用awk, ...

  6. Mahout推荐算法之SlopOne

    Mahout推荐算法之SlopOne 一.       算法原理 有别于基于用户的协同过滤和基于item的协同过滤,SlopeOne采用简单的线性模型估计用户对item的评分.如下图,估计UserB对 ...

  7. 分布式进阶(十二)Docker固定Container IP

    使用pipework工具. 前提:每个Container所做的工作现在还很少,可以不用save.commit. 为了便于通信,自定义一个网桥(192.168.1.180/24),使之IP与宿主主机IP ...

  8. UIEvent&nbsp;UIResponder&nbsp;UI_04

    1.事件(UIEvent),是由硬件设备捕捉到用户对设备的操作,把这个操作抽象成一个事件对象     ios中三大事件:触Touches摸晃动事件Motion,远程控制事件RemoteControl: ...

  9. C++ Primer 有感(new和delete表达式)

    定义变量时,必须指定其数据类型和名字.而动态创建对象时,只需指定其数据类型,而不必为该对象命名.取而代之的是,new表达式返回指向性创建的指针. 1.动态创建对象的默认初始化 对于类类型的对象,用该类 ...

  10. Android数据库Realm实践

    Android开发中常用的数据库有5个: 1. OrmLite OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM.支持JDBC连接,Spring以及Android平台. ...