<template>
<tab :options="tabOpt" :state.sync="stateIndex"></tab>
</template>
<script type="text/babel">
import tab from 'components/tab_touch';
export default {
data(){
tabOpt:undefined,
stateIndex:0
},
components:{
"tab":tab
},
ready(){
this.tabOpt={
count: 2.3,
pin:true,
htmls:[
"<span>白日登山</span>",
"<span>望烽火</span>",
"<span>黄昏饮马</span>",
"<span>傍交河</span>",
"<span>行人刁斗</span>",
"<span>风沙暗</span>",
"<span>公主琵琶</span>",
"<span>幽怨多</span>",
"<span>野营万里</span>",
"<span>无城郭</span>",
"<span>雨雪纷纷</span>",
"<span>连大漠</span>"
],
slideCallback:function (dex) {
console.log(dex);
},
tabClassName:"tab",
tabActiveClassName: "active"
}
}
}
</script>

options参数释义

参数名 简称 是否必填 类型 含义 默认值 其它
count 展示tab数 必填项 数值|一屏中露出tab的个数| 无      
pin 是否固定到顶部 可选项 布尔 当垂直滚动时,该组件即将超出屏幕时是否固定到头部 false  
htmls tab内容 必填项 数组[字符串] 在tab中显示的html  
tabClassName tabClassName 可选项 字符串 单个tab的class名 一般用于自定义样式
tabActiveClassName tabActiveClassName 可选项 字符串

激活的tab的class名

<template>
<div class="fixWrap">
<div class="component-tabsWrap" :id="tabsWrapID"
v-touch:pan="onPan">
<div class="component-tabs" :style="wrapStyle">
<div class="component-tab" v-for="item in options.htmls" track-by="$index" :style="'width:'+tWidth+'px'"
@click.stop="this.state=$index"
:class="[options.tabClassName,$index==state?options.tabActiveClassName:'']">
{{{item}}}
</div>
</div>
</div>
</div>
</template>
<style lang="sass" rel="stylesheet/sass">
@import "tab.sass"
</style>
<script lang="babel" type="text/babel">
var VueTouch = require ('vue-touch');
Vue.use (VueTouch);
import requestAnimFrame from "utils/requestAnimFrame"
const sign = (num)=> {
return num >= 0 ? 1 : -1
}
export default {
props: ["options", "state"],
data(){
return {
tabsWrapID: undefined,//外容器ID
wrapWidth: "", //外容器宽度
tWidth: 0, //每一个选项卡应该有多宽
width: 0, //宽度。
startTransX: 0,
transX: 0, //元素样式偏移。
cssX: 0 //动作中css实际完成的偏移。
}
},
methods: {
init(){
this.wrapWidth = document.getElementById (this.tabsWrapID).offsetWidth;
this.tWidth = this.wrapWidth / this.options.count;
this.width = this.tWidth * this.options.htmls.length;
setTimeout(function(){
this.$el.style["height"]= this.$el.children[0].clientHeight+"px";
}.bind(this),0)
if (this.options.pin) {
var elemRect = this.$el.getBoundingClientRect ();
var windowOffset = this.getWindowOffset ();
var winOffsetY = windowOffset.offsetY;
this.elemOffsetY = elemRect.top + winOffsetY;
document.addEventListener ('scroll', this.isTop);
}
},
onPan(event){
if (this.options.disPan) return;
this.transX = event.deltaX + this.startTransX;
this.cssX = this.transX;
if (event.eventType == 4) {
this.transX = -Math.round (-this.transX / this.tWidth) * this.tWidth; //整格滑动
var start = null;
if (this.transX > 0) {
// 头部回弹
this.transX = 0;
var speed = 24;
requestAnimFrame (step.bind (this));
function step (timestamp) {
this.cssX -= speed;
if (this.cssX > this.transX) requestAnimFrame (step.bind (this));
else this.startTransX = this.cssX = this.transX;
};
}
else if (this.transX < this.wrapWidth - this.width) {
// 尾部回弹
this.transX = this.wrapWidth - this.width;
var speed = 24;
requestAnimFrame (step.bind (this));
function step (timestamp) {
this.cssX += speed;
if (this.cssX < this.transX) requestAnimFrame (step.bind (this));
else this.startTransX = this.cssX = this.transX;
};
}
else {
//整格落位
let speed = 6;
let _sign = sign (this.cssX - this.transX);
if (_sign * (this.cssX - this.transX) > 1) requestAnimFrame (step.bind (this));
else this.cssX = this.transX;
function step (timestamp) {
if (start === null) start = timestamp;
let progress = timestamp - start;
if (progress < 3000) speed *= 1 - progress / 3000;
this.cssX -= _sign * speed;
if (_sign * (this.cssX - this.transX) > 1) requestAnimFrame (step.bind (this));
else this.cssX = this.transX;
};
}
this.startTransX = this.transX; //滑动结束设置下次滑动起始值。
} },
slideTo(dex){
this.state = dex;
let speed = 10;
// 开头几个
if (dex + 1 <= this.options.count) {
this.transX = 0; // 设置应到位置。
if (this.startTransX < this.transX) {
let _sign = sign (this.transX - this.startTransX);
this.cssX = this.transX - _sign * this.tWidth;
requestAnimFrame (step.bind (this));
function step () {
this.cssX += _sign * speed;
if (_sign * (this.cssX - this.transX) < 0) requestAnimFrame (step.bind (this));
else {
this.cssX = this.startTransX = this.transX;
if (this.options.slideCallback) this.options.slideCallback (dex);
}
;
};
}
//无需动画
else {
this.cssX = this.startTransX = this.transX;
if (this.options.slideCallback) this.options.slideCallback (dex);
}
}
// 结尾几个
else if (this.options.htmls.length - dex <= this.options.count) {
this.transX = this.wrapWidth - this.width;// 设置应到位置。
if (this.startTransX > this.transX) {
let _sign = sign (this.transX - this.startTransX);
this.cssX = this.transX - _sign * this.tWidth;
requestAnimFrame (step.bind (this));
function step () {
this.cssX += _sign * speed;
if (_sign * (this.cssX - this.transX) < 0) requestAnimFrame (step.bind (this));
else {
this.cssX = this.startTransX = this.transX;
if (typeof this.options.slideCallback == "function") this.options.slideCallback (dex);
} };
}
else {
this.cssX = this.startTransX = this.transX; //无需动画
if (typeof this.options.slideCallback == "function") this.options.slideCallback (dex);
}
}
//中
else {
this.transX = -this.tWidth * dex;// 设置应到位置。
let _sign = sign (this.transX - this.startTransX);
if (this.tWidth * (dex + 0.5 * (1 - _sign)) + this.startTransX >= 0 && this.tWidth * (dex + 0.5 * (1 - _sign)) + this.startTransX <= this.wrapWidth) {
//无需动画
this.cssX = this.transX = this.startTransX;
if (typeof this.options.slideCallback == "function") this.options.slideCallback (dex);
}
else {
//需要动画
this.cssX = this.transX - _sign * this.tWidth;
requestAnimFrame (step.bind (this));
function step () {
this.cssX += _sign * speed;
if (_sign * (this.cssX - this.transX) < 0) requestAnimFrame (step.bind (this));
else {
this.cssX = this.startTransX = this.transX;
if (typeof this.options.slideCallback == "function") this.options.slideCallback (dex);
}
};
}
}
},
isTop(){
var windowOffset = this.getWindowOffset (),
winOffsetY = windowOffset.offsetY,
isTop;
isTop = this.elemOffsetY <= winOffsetY;
if (isTop) {
this.$el.children[0].style['position'] = 'fixed';
this.$el.children[0].style['top'] = '0';
this.$el.children[0].style['left'] = '0';
}
else {
this.$el.children[0].style['position']='relative';
}
return isTop;
},
getWindowOffset(){
var t;
var win = window;
var pageXOffset = (typeof win.pageXOffset == 'number') ? win.pageXOffset : (((t = doc.documentElement) || (t = body.parentNode)) && typeof t.ScrollLeft == 'number' ? t : body).ScrollLeft;
var pageYOffset = (typeof win.pageYOffset == 'number') ? win.pageYOffset : (((t = doc.documentElement) || (t = body.parentNode)) && typeof t.ScrollTop == 'number' ? t : body).ScrollTop;
return {
offsetX: pageXOffset,
offsetY: pageYOffset
};
},
},
watch: {
options(){
this.tabsWrapID = parseInt (Math.random () * 1e10);
setTimeout (this.init.bind (this), 10);
},
state(val){
this.slideTo(val)
}
},
computed: {
wrapStyle(){
var _str = "";
if (this.width) _str += `width:${this.width}px;`;//宽度
_str += `-webkit-transform:translateX(${this.cssX}px);` //位移。
_str += `transform:translateX(${this.cssX}px);` //位移。
return _str
}
}
}
</script>
<style lang="sass" rel="stylesheet/sass" type="sass">
.fixWrap
z-index: 999
position: relative
.component-tabsWrap
width: 100%
overflow: hidden
min-height: .1rem
position: relative
background: #fff
.component-tabs
height: 100%
display: table
.component-tab
display: table-cell
box-sizing: border-box
text-align: center
vertical-align: middle
</style>

来源:http://blog.csdn.net/keliyxyz/article/details/52208484

vue 插件tab选项卡(转载)的更多相关文章

  1. 微信小程序的wx-charts插件-tab选项卡

    微信小程序的wx-charts插件-tab选项卡 效果: //index.js var wxCharts = require('../../utils/wxcharts-min.js'); const ...

  2. vue实现tab选项卡切换效果

    tab选项卡切换效果: 通过点击事件传入参数,然后通过v-show来进行切换显示 <template> <div class="box"> <div ...

  3. Vue实现tab选项卡

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. vue实现tab选项卡切换

    上代码: <template>   <div class="push">     //点击按钮     <div class="tab&qu ...

  5. 使用jQuery开发tab选项卡插件(可以右键关闭多个标签)

    在前一篇“使用jQuery开发tab选项卡插件”的基础上添加了tab标签右键关闭菜单功能,菜单主要包括:关闭当前标签.关闭左侧标签.关闭右侧标签.关闭其他.关闭全部. 一.插件效果 二.实现思路 为w ...

  6. 使用jQuery开发tab选项卡插件

    为了复习巩固jQuery的插件开发.HTML和CSS方面的知识,做了一个简单的tab选项卡插件,简单记录一下开发.使用的过程,以备日后使用. 一.插件效果 tab选项卡插件常用的功能均已实现,包括:动 ...

  7. 微信小程序-滚动Tab选项卡

    前言:今天呢 给大家详细讲解一下滚动Tab选项卡:左右可滑动切换的效果,希望对大家做项目时候有用! 以前也遇到过这个,但是没有做记录.转载来源于:https://www.jianshu.com/p/9 ...

  8. 很全的vue插件汇总,赶紧收藏下(转)

    Vue是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件特别整理了常用的vue插件,来了个大汇总,方便查找使用,便于工作 ...

  9. 可轮播滚动的Tab选项卡

    前段时间有试着搭建个后台主题ui框架,有用到可支持滚动的Tab选项卡,模仿着H+后台主题ui框架中的代码造轮子改造了下,可惜代码在公司,不能把代码外发出来(感觉这样被限制了很多,对于这样的公司没办法, ...

随机推荐

  1. Java四个常用正则表达

     1.查询   以下是代码片段: String str="abc efg ABC";String regEx="a|f"; //表示a或fPattern p=P ...

  2. 理解JavaScript的运行

    JavaScript可以运行在head和body标签中! HTML的脚本必须放在<script></script>标签中间! 浏览器会解释并执行位于script标签中的脚本! ...

  3. leetcode python 004

    ##  已知l1,l2均为升序数组,##  在两数组l1,l2中寻找第n位数,##  两数组中位数中,前者大于后者,说明后者中位数以下的成员必定在真正中位数之下##  可以将其剔除,剔除a个元素后的两 ...

  4. pytorch加载和保存模型

    在模型完成训练后,我们需要将训练好的模型保存为一个文件供测试使用,或者因为一些原因我们需要继续之前的状态训练之前保存的模型,那么如何在PyTorch中保存和恢复模型呢? 方法一(推荐): 第一种方法也 ...

  5. Centos7下cratedb数据导入导出copy to copy from

    crate 创建表结构: 查看表: show tables; 创建表结构: create table tablename (k1 type,k2 type,k3 type);  (type = int ...

  6. DevExpress v18.1新版亮点——Reporting篇(一)

    用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Reporting v18.1 的新功能,快来下载试用新版本 ...

  7. codeforce949A(顺带vector详细使用介绍)

    A. Zebras time limit per test1 second memory limit per test512 megabytes inputstandard input outputs ...

  8. L252

    How often have you heard the saying, "Stop and smell the roses?" Odds are, you've come acr ...

  9. php优秀框架codeigniter学习系列——CodeIgniter.php概览

    CodeIgniter.php是CI框架的核心文件.它在前端控制器index.php之后运行,加载各类基础组件,执行请求.文件执行完成后,这次请求也就结束了.所以,该文只能对CodeIgniter.p ...

  10. day12作业