Vue 仿B站滑动导航
仿照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站滑动导航的更多相关文章
- iOS仿今日头条滑动导航
之前写了篇博客网易首页导航封装类.网易首页导航封装类优化,今天在前两个的基础上仿下今日头条. 1.网易首页导航封装类中主要解决了上面导航的ScrollView和下面的页面的ScrollView联动的问 ...
- 2017年11月8日最新仿互站导航t5友价商城-9套模板首页都增加微信登陆
今天测试效果如下,直接看图吧,入口在下方,点击图片直达 把9套餐模板都添加了微信首页登陆,仿互站的导航,操作比互站还要方便,官方一直对https 支持不太友好,索性把所有的https bug都修复了, ...
- 仿腾讯QQ竖直滑动导航菜单
菜单就像qq软件的分组,鼠标经过自动显示相应组的内容. 效果体验网址:http://keleyi.com/a/bjad/nf86w2dv.htm 以下是源代码: <html> <he ...
- (https专业版)2018年1月5日高仿互站仿友价T5虚拟交易+实物交易商城-站长交易源码送手机版程序10套模版+首页微信登陆+头部下拉导航
(https专业版)2018年1月5日高仿互站仿友价T5虚拟交易+实物交易商城-站长交易源码送手机版程序10套模版+首页微信登陆+头部下拉导航 首页支持微信登陆,只有第8套模板支持(endv模板),后 ...
- Nuxt|Vue仿探探/陌陌卡片式滑动|vue仿Tinder拖拽翻牌效果
探探/Tinder是一个很火的陌生人社交App,趁着国庆假期闲暇时间倒腾了个Nuxt.js项目,项目中有个模块模仿探探滑动切换界面效果.支持左右拖拽滑动like和no like及滑动回弹效果. 一览效 ...
- vue 仿今日头条
vue 仿今日头条 为了增加移动端项目的经验,近一周通过 vue 仿写今日头条,以下就项目实现过程中遇到的问题以及解决方法给出总结,有什么不正确的地方,恳请大家批评指正^ _ ^!,代码仓库地址为 g ...
- 我的Vue之旅、05 导航栏、登录、注册 (Mobile)
第一期 · 使用 Vue 3.1 + TypeScript + Router + Tailwind.css 构建手机底部导航栏.仿B站的登录.注册页面. 代码仓库 alicepolice/Vue-05 ...
- jquery仿天猫商城左侧导航菜单
之前看到有博友写了一个仿天猫商城左侧导航菜单,可惜不提供免费下载,也没有代码.以前自己也写过类似的效果,只是都是一小块一小块的,现在重新拼凑.我将一步一步的实现拼凑过程,希望对你有所帮助. Demo在 ...
- 一款基于jQuery的仿百度首页滑动选项卡
今天给大家分享一款基于jQuery的仿百度首页滑动选项卡.这款选项卡适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
随机推荐
- ROS_Kinetic_21 使用Qt Creator Plug in即ros_qtc_plugin
更为详细版本请参考: http://blog.csdn.net/zhangrelay/article/details/52214411 结合看更为具体. 首先,先上原版参考: 1 http://wik ...
- FND Debug Log(FND_LOG_MESSAGES)
之前每个模块记录日志的方式都不同,都会把日志写到不同的文件中,对于User来说很麻烦,需要记住很多的配置,现在越来越多的模块使用FND Logging来存储日志,比如WIP,RCV,OAF...FND ...
- react-native版本升级
时刻将React Native更新到最新的版本,可以获得更多API.视图.开发者工具以及其他一些好东西(译注:官方开发任务繁重,人手紧缺,几乎不会对旧版本提供维护支持,所以即便更新可能带来一些兼容上的 ...
- Jquery EasyUI +Ajax +Json +一般处理程序 实现数据的前台与后台的交互 --- 善良公社项目
经过上一篇博客,本节主要是来看实现的功能是后台的数据通过json数据传过来,前台修改的数据再传回数据库之后页面再次更新table中的数据: 图示: 实例:前台的代码 <%--表格显示区--%&g ...
- Socket编程实践(8) --Select-I/O复用
五种I/O模型介绍 (1)阻塞I/O[默认] 当上层应用App调用recv系统调用时,如果对等方没有发送数据(Linux内核缓冲区中没有数据),上层应用Application1将阻塞;当对等方发送了数 ...
- XML Publisher Report Issues, Recommendations and Errors
In this Document Purpose Questions and Answers References APPLIES TO: Oracle Process Manufactu ...
- (NO.00002)iOS游戏精灵战争雏形(十一)
为了在子弹触碰到目标时做一些事情,我们必须要设置碰撞回调. 首先在MainScene.h的类接口中添加碰撞协议: @interface MainScene : CCNode <CCPhysics ...
- 4.4、Libgdx使用方法查询运行环境相关属性
(原文:http://www.libgdx.cn/topic/46/4-4-libgdx%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E6%9F%A5%E8%AF%A2%E ...
- (三十八)从私人通讯录引出的细节II -数据逆传 -tableView点击 -自定义分割线
项目中的警告是不会影响app发布的,例如引入第三方类库很容易引入警告. 细节1:跳转的数据传递. prepareForSegue: sender: 方法是在执行segue后,跳转之前调用这个方法,一般 ...
- Dynamics CRM OData方式进行增删改查时报错的问题
今天在通过OData终结点update记录的时候报"Error processing request stream. The request should be a valid top-le ...