写一个移动端惯性滑动&回弹Vue导航栏组件 ly-tab


Posted in Javascript onMarch 06, 2018

前段时间写了一个移动端的自适应滑动Vue导航栏组件,觉得有一定实用性,大家可能会用得到(当然有些大佬自己写得更好的话就没必要啦),于是前两天整理了一下,目前已经发布到npm和GitHub上了,点我到npm,点我到GitHub项目 ,有需要的同学可以在项目中 npm install ly-tab -S 或者 yarn add ly-tab 使用,具体用法下面会讲到。

好了,先看看效果吧

写一个移动端惯性滑动&回弹Vue导航栏组件 ly-tab 

好的,开始废话了,实习差不多3个月了,这段时间跟着导师大佬也有接触过一些项目,也学到了不少东西,接触到的项目基本都是移动端项目,而且框架主要用的是Vue。做过移动端或者用过移动端APP(呸,屁话)的同学肯定会发现很多时候都会有类似上面这种有滑动效果的tab导航栏,相信大家肯定在掘金的首页就看到过。

实现思路

当时的项目中恰好也有这种需求,于是我想偷个懒直接使用 Mint-ui 组件库里现成的tabbar和tab-item组件,github上看了下它的实现源码发现只实现了切换功能但不能滑动,so,懒偷不了就只好自己写咯。

其实单单实现tab切换功能是不难的,看mint-ui使用的其实是v-model语法糖,就像下面这样

<ly-tab v-model="selected">
  <ly-tab-item></ly-tab-item>
</ly-tab>

下面是拆解v-model语法糖的实现

<ly-tab :value="selected" @input="selected = arguments[0]">
  <ly-tab-item></ly-tab-item>
</ly-tab>

然后只需要在tab-item组件内实现当自己被点击时,让其父组件也就是ly-tab组件 $emit 一个 input 事件,并传入一个标识每个tab-item的唯一值作为第一个参数,关于这个唯一值,mint-ui的做法需要用户自己手动给每个tab-item通过props传入一个唯一的id值,如下为Mint UI的Demo实现:

<mt-tabbar v-model="selected">
  <mt-tab-item id="订单">
    <img slot="icon" src="http://placehold.it/100x100">
    <span slot="label">订单</span>
  </mt-tab-item>
 </mt-tabbar>

但是,在看过大佬的 vue当中设计Tabbar插件时的思考 后觉得文章中的那种做法会更好一点,因为对于父组件 <ly-tab/> 来说,只要知道点击的是哪个 <ly-tab-item/> 就行了啊,那么我把每个 <ly-tab-item/> 组件的 index 索引值作为它的唯一标识值不就行了吗。

那么问题来了:怎么在tab-item组件内部取到自己的 index 值呢?

首先ly-tab组件的 $children 是一个数组,由于每个 <ly-tab-item/> 组件是依次创建并通过push的方式插入该数组,所以在每个 <ly-tab-item/> 组件创建并push到 $children 时,对于 <ly-tab-item/> 组件来说 (this.$parent.$children.length || 1) - 1 不就是每个 <ly-tab-item/> 组件唯一的 index 值了啊。实际上,到这里点击切换的功能就已经可以实现了。下面贴上tab-item.vue中的代码:

tab-item.vue

<template>
 <a class="ly-tab-item"
    :style="$parent.value === id ? activeStyle : {}"
    @click="$parent.$emit('input', id)">
  <div class="ly-tab-item-icon"><slot name="icon"></slot></div>
  <div class="ly-tab-item-label"><slot></slot></div>
 </a>
</template>
<script>
export default {
 name: 'LyTabItem',
 computed: {
  activeStyle () {
   return {
    color: this.$parent.activeColor,
    borderColor: this.$parent.activeColor,
    borderWidth: this.$parent.lineWidth,
    borderBottomStyle: 'solid'
   }
  }
 },
 data () {
  return {
   id: (this.$parent.$children.length || 1) - 1
  }
 }
}
</script>
<style lang="scss">
.ly-tab-item {
 text-decoration: none;
 text-align: center;
 .ly-tab-item-icon {
  margin: 0 auto 5px;
 }
 .ly-tab-item-label {
  margin: 0 auto 10px;
  line-height: 18px;
 }
}
</style>

关于tab.vue中触摸滑动、惯性滑动以及回弹等效果实现在这里就没办法详细讲了,有兴趣的小伙伴可以到github上查看, 点我去github查看项目 ,如果想看示例demo可以clone项目到本地跑一跑,写得不好的地方欢迎大家指正,如果觉得用得着或者能够帮到大家的话最好了,那也不妨点个star吧,哈哈......

哎哎哎,不对不对,怎么就开始求star了,最重要的还没讲呢—— ly-tab怎么使用呢?

如何使用 ly-tab

小伙伴们如果想使用ly-tab,需要在你的项目中通过npm或者yarn下载安装:

npm install ly-tab -S
or
yarn add ly-tab

接着在main.js中全局引入:

import Vue from 'vue';
import LyTab from 'ly-tab';
Vue.use(LyTab);

之后你就可以在你项目中任意使用 <ly-tab></ly-tab> <ly-tab-item></ly-tab-item> 组件而不需要再次引入了

栗子

<ly-tab v-model="selected" fixBottom>
 <!-- selected是你自己定义的一个在data中用于存放当前tab-item的索引值的变量 -->
 <ly-tab-item v-for="(item, index) in tabList" :key="index">
  {{item.itemName}}
 </ly-tab-item>
</ly-tab>

上面的栗子其实只是tabbar的实现,大家项目中肯定还需要做视图区的切换,在这里简单说一下我目前的做法:

  • 使用Vue-router做router-view的切换
  • 使用动态组件(可以配合异步组件使用)

我暂时的话好像只用过这两种,不知道大家还有其他什么更好的方法,欢迎分享~

配置项

可以给 <ly-tab></ly-tab> 组件传入一些配置项以自定义你想要的效果

配置项 类型 描述 默认值
lineWidth Number fixBottom为false时tabbar底部border-width 1px
activeColor String 激活状态下字体color以及border-bottom-color red
fixBottom Boolean 是否固定在视图底部(为false时不可滑动) false
additionalX Number 近似等于超出边界时最大可拖动距离 50px
reBoundExponent Number 惯性回弹指数(值越大,幅度越大,惯性回弹距离越长) 10
sensitivity Number 惯性滑动时的灵敏度(值越小,阻力越大),可近似认为手松开后速度减为零所需时间 1000ms
reBoundingDuration Number 回弹动画duration 360ms

总结

以上所述是小编给大家介绍的写一个移动端惯性滑动&回弹Vue导航栏组件 ly-tab,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
基础的prototype.js常用函数及其用法
Mar 10 Javascript
通过修改referer下载文件的方法
May 11 Javascript
用JS将搜索的关键字高亮显示实现代码
Nov 08 Javascript
浅析jquery某一元素重复绑定的问题
Jan 03 Javascript
将HTML格式的String转化为HTMLElement的实现方法
Aug 07 Javascript
JavaScript中Date对象的常用方法示例
Oct 24 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
基于Jquery easyui 选中特定的tab
Nov 17 Javascript
微信小程序开发之大转盘 仿天猫超市抽奖实例
Dec 08 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
Feb 20 Javascript
jQuery选择器之子元素过滤选择器
Sep 28 jQuery
js前端图片加载异常兜底方案
Jun 21 Javascript
vue使用xe-utils函数库的具体方法
Mar 06 #Javascript
jQuery+koa2实现简单的Ajax请求的示例
Mar 06 #jQuery
angular4 JavaScript内存溢出问题
Mar 06 #Javascript
webpack+vuex+axios 跨域请求数据的示例代码
Mar 06 #Javascript
vue中本地静态图片路径写法
Mar 06 #Javascript
webpack配置导致字体图标无法显示的解决方法
Mar 06 #Javascript
网页爬虫之cookie自动获取及过期自动更新的实现方法
Mar 06 #Javascript
You might like
简单采集了yahoo的一些数据
2007/02/14 PHP
php实现斐波那契数列的简单写法
2014/07/19 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
YII2框架中日志的配置与使用方法实例分析
2020/03/18 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
List Installed Software Features
2007/06/11 Javascript
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
Jquery方式获取iframe页面中的 Dom元素
2014/05/07 Javascript
jQuery对指定元素中指定字符串进行替换的方法
2015/03/17 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
2016/05/04 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
Ajax验证用户名或昵称是否已被注册
2017/04/05 Javascript
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
2017/07/17 Javascript
基于Bootstrap实现城市三级联动
2017/11/23 Javascript
详解如何用模块化的方式写vuejs
2017/12/16 Javascript
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
2018/01/08 jQuery
在layui中对table中的数据进行判断(0、1)转换为提示信息的方法
2019/09/28 Javascript
javascript简单实现深浅拷贝过程详解
2019/10/08 Javascript
VUE动态生成word的实现
2020/07/26 Javascript
[01:29:31]VP VS VG Supermajor小组赛胜者组第二轮 BO3第一场 6.2
2018/06/03 DOTA
仅利用30行Python代码来展示X算法
2015/04/01 Python
python实现搜索文本文件内容脚本
2018/06/22 Python
转换科学计数法的数值字符串为decimal类型的方法
2018/07/16 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
Python generator生成器和yield表达式详解
2019/08/08 Python
英语教学随笔感言
2014/02/20 职场文书
英语教师个人总结
2015/02/09 职场文书
小程序后台PHP版本部署运行 LNMP+WNMP
2021/04/01 Servers
漫画「狩龙人拉格纳」公开TV动画预告图
2022/03/22 日漫
Win11怎么把合并的任务栏分开 Win11任务栏合并分开教程
2022/04/06 数码科技
docker-compose部署Yapi的方法
2022/04/08 Servers