[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滾動
- 監聽局部滾動