[TOC]
#### CubeUi Tab 滑屏切换组件
* [ ] 核心算法
滑动的距离 = 滑动的X坐标 / 滑动区域宽度 * tab导航栏宽度
1. 定义组件
~~~
<template>
<div class="tab">
<!-- tabbar 导航切换区 -->
<cube-tab-bar
v-model="selectedLabel"
:data="tabs"
:showSlider=true
:useTransition=false
class="border-bottom-1px"
ref="tabbar"
>
</cube-tab-bar>
<!-- swiper 滑动区 -->
<div class="silde-wrapper">
<cube-slide
:loop=false
:showDots=false
:autoPlay=false
:initialIndex="index"
@change="onChange"
@scroll="onScroll"
:options="scrollOptions"
ref="slide"
>
<cube-slide-item v-for="(tab, index) in tabs" :key="index">
<!-- tab.component 组件 tab.data 数据 -->
<component :is="tab.component" :data="tab.data"></component>
</cube-slide-item>
</cube-slide>
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: "tab",
props: {
tabs: {
type: Array,
default() {
return {}
}
},
initIndex: {
type: Number,
default: 0
}
},
data () {
return {
index: this.initIndex,
// BScroll 配置
scrollOptions: {
probeType: 3, //滚动动画运行过程中实时派发 scroll 事件
listenScroll: true, // 监听 BScroll 滚动
directionLockThreshold: 0 // 锁定滚动
}
}
},
methods: {
// slide 滑动结束会派发当前索引
onChange(current) {
this.index = current
},
// slide 滚动时派发
onScroll(pos) {
// 横向滚动距离
let posX = Math.abs(pos.x)
// tabbar 宽度
const tabbarWidth = this.$refs.tabbar.$el.clientWidth
// slide 宽度
const slideWidth = this.$refs.slide.slide.scrollerWidth
// 计算滚动距离 = posX / slideWidth * tabbarWidth
const transForm = posX / slideWidth * tabbarWidth
// 改变 cube-tab-bar 组件的下划线的 transformX
this.$refs.tabbar.setSliderTransform(transForm)
}
},
computed: {
// 计算索引
selectedLabel: {
get() {
return this.tabs[this.index].label
},
set(newVal) {
this.index = this.tabs.findIndex((value) => {
return value.label === newVal
})
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
.tab
display flex
flex-direction column
height 100%
>>> .cube-tab
color #666
font-size 30px
padding 20px 0
.silde-wrapper
flex 1
overflow hidden
</style>
~~~
*****
2. 外部调用
~~~
<template>
<div id="app">
<v-header />
<tab :tabs="tabs" :initIndex="currentIndex" />
</div>
</template>
<script>
import vheader from '@/components/vheader'
import tab from '@/components/tab/tab'
import { goods } from '@/api'
import good from '@/components/goods/goods'
import rating from '@/components/ratings/rating'
import seller from '@/components/seller/seller'
export default {
name: 'app',
data() {
return {
currentIndex: 0
}
},
computed: {
tabs() {
return [
{
label: '商品',
component: good
},
{
label: '评论',
component: rating
},
{
label: '商家',
component: seller
}
]
}
},
components: {
'v-header': vheader,
tab
}
}
</script>
<style lang="stylus">
#app
width 100%
height 100%
overflow hidden
</style>
~~~
- 起步
- 环境搭建
- mock数据
- 基础
- 生命周期
- 过滤器
- 过渡动画
- keyframes动画
- 动画JS钩子
- 路由
- 导航守卫
- 全局守卫
- 监听器
- 自定义组件
- 获取焦点
- mixins
- mixins抽离vuex
- 国际化
- 动态组件
- Dom
- 扩展
- 安装devTools
- scss
- Nuxt引用多个UI库
- vuex
- vuex命名空间
- vuex定义
- cli
- 安装与卸载
- 环境变量
- 杂项
- Mock数据
- FeHelper
- git
- 反向代理
- 本地存储
- stylus
- 常用mixins
- jsonp
- 配置
- mock配置
- 跨域配置
- 自定义路径
- px2rem
- 代理后端请求
- 常用算法
- 字母排序城市数据
- 倒计时
- 通讯录数据结构
- 请求
- axios防止多次请求
- 封装axios请求
- axios使用
- 封装axios
- 插件
- BetterScroll
- 高德定位
- polyfill
- fastClick
- LazyLoad
- storageCache
- moment
- keyFrameAnimation
- vueSwiper
- 组件
- Loading组件
- header组件
- 仿有道App导航
- SupportIcon
- 仿饿了么购物车跳动
- 购物车小球缓动
- 小球飞入购物车
- 仿音乐歌手列表
- 唱片飞入效果
- 搜索组件
- 仿美团PC搜索框
- 页面布局
- stickyFooter
- 背景色渐变
- 背景虚化
- Ui组件
- CubeUi
- CreateApi
- tab滑屏切换
- 索引列表
- BScroll
- BScroll左右联动导航
- vant
- 函数库
- 常用Dom函数库
- axios封装
- 格式化音乐播放时长
- 搜索节流
- time格式化
- JS基础
- window对象中的高度
- JS中的宽高
- 常用正则
- nuxt
- nuxtVuex
- 监听页面滚动
- 监听body滚动
- 监听局部滚动