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.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
随机推荐
- Android开发技巧——PagerAdapter的再次简单封装
这次再对内容为View的ViewPager的适配器PagerAdapter进行简单的封装,支持List数据和SparseArray的数据,带更新视图功能. 首先,先贴上最上面的抽象类代码: /* * ...
- UNIX环境高级编程——管道和FIFO的额外属性
一个描述符能以两种方式设置成非阻塞. (1)调用open时可以指定O_NONBLOCK标志. writefd = open(FIFO1,O_WRONLY | O_NONBLOCK,0); (2)如果一 ...
- Mybatis插件原理分析(一)
我们首先介绍一下Mybatis插件相关的几个类,并对源码进行了简单的分析. Mybatis插件相关的接口或类有:Intercept.InterceptChain.Plugin和Invocation,这 ...
- 怎样写一个与Windows10 IE11兼容的标准BHO?
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...
- Chapter 3 Protecting the Data(2):分配列级权限
原文出处:http://blog.csdn.net/dba_huangzj/article/details/39577861,专题目录:http://blog.csdn.net/dba_huangzj ...
- 总账balance表
SELECT gb.period_net_dr, --期间发生额 gb.period_net_cr, --期间发生额 gb.project_to_date_dr, --账户 ...
- cocos2D v3.x 中action的回调block变化
cocos2D v2.x中有带参数的回调block: id blk = [CCCallBlockN actionWithBlock:^(CCNode *node){ node.position = o ...
- Erlang cowboy 入门参考
Erlang cowboy 入门参考 cheungmine,2014-10-28 本文翻译自: http://ninenines.eu/docs/en/cowboy/HEAD/guide/gettin ...
- 采购,接收数据收集SQL汇总(从订单->接收->INVOICE所有数据关联SQL)
INDEX OF QUERIES Source Document: Purchase Order: 1: po_headers_all (sql) 2: po_lines_all (sql) 3: p ...
- Leetcode_278_First Bad Version
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/49719255 You are a product mana ...