11
This commit is contained in:
82
components/v-tabs/readme.md
Normal file
82
components/v-tabs/readme.md
Normal file
@@ -0,0 +1,82 @@
|
||||
## 调用方式
|
||||
|
||||
- 视图调用
|
||||
|
||||
```html
|
||||
<v-tabs
|
||||
:tabs="[1,2,3,4]"
|
||||
height="45px"
|
||||
v-model="activeTab"
|
||||
color="#333"
|
||||
activeColor="#1abc9c"
|
||||
fontSize="14px"
|
||||
activeFontSize="16px"
|
||||
:lineHeight="4px"
|
||||
:lineScale="0.8"
|
||||
lineColor="#1abc9c"
|
||||
/>
|
||||
```
|
||||
|
||||
- js 调用
|
||||
|
||||
```js
|
||||
import vTabs from '@/components/v-tabs'
|
||||
export default {
|
||||
components: {
|
||||
vTabs,
|
||||
},
|
||||
data() {
|
||||
activeTab: 0
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- 参数说明
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| :-------------: | :--------------: | :-----: | :----------: |
|
||||
| value | String 或 Number | 0 | 必传 |
|
||||
| tabs | Array | [] | tabs 数量 |
|
||||
| height | String | '45px' | tab 高度 |
|
||||
| backgroundColor | String | '' | 选中背景 |
|
||||
| borderRadius | String | 5px | 圆角 |
|
||||
| color | String | #333333 | 默认文字颜色 |
|
||||
| activeColor | String | #333333 | 选中文字颜色 |
|
||||
| fontSize | String | 14px | 默认文字大小 |
|
||||
| activeFontSize | String | 14px | 选中文字大小 |
|
||||
| lineScale | Number | 0.6 | 下划线缩放 |
|
||||
| lineHeight | [Number, String] | 3 | 下划线高度 |
|
||||
| lineColor | Sring | #007AFF | 下划线颜色 |
|
||||
|
||||
|
||||
## 事件
|
||||
|
||||
|事件名称|参数|
|
||||
|:-----:|:-----:|
|
||||
|@change|activeTab|
|
||||
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2020-06-09
|
||||
|
||||
1. 修复小程序端选中的下划线不显示问题
|
||||
2. 新增 tab 高度设置
|
||||
3. `lineHeight` 修改为只支持 `String` 方式
|
||||
|
||||
### 2020-06-11
|
||||
|
||||
1. 添加 `change` 事件
|
||||
2. 修复插件内容问题
|
||||
3. 修复下划线不居中问题
|
||||
|
||||
### 2020-06-11
|
||||
|
||||
1. 添加注释
|
||||
2. 修复 bug
|
||||
|
||||
### 2020-07-05
|
||||
|
||||
1. 新增 `padding` 的可配置
|
||||
2. 修复 `v-model` 双向绑定问题
|
||||
3. 修复初始化下划线没定位的为题
|
||||
241
components/v-tabs/v-tabs.vue
Normal file
241
components/v-tabs/v-tabs.vue
Normal file
@@ -0,0 +1,241 @@
|
||||
<template>
|
||||
<view class="v-tabs" :style="{ height: height }">
|
||||
<scroll-view class="scroll-view" :show-scrollbar="false" scroll-x scroll-with-animation :scroll-left="scrollLeft" style="width: auto; height: 100%; overflow: hidden;">
|
||||
<view class="v-tabs__inner">
|
||||
<view
|
||||
class="v-tabs__item"
|
||||
:style="{
|
||||
color: activeTab == i ? activeColor : color,
|
||||
fontSize: activeTab == i ? activeFontSize : fontSize,
|
||||
backgroundColor: activeTab == i ? backgroundColor : '',
|
||||
borderRadius,
|
||||
padding,
|
||||
|
||||
}"
|
||||
:data-index="i"
|
||||
:class="{ active: activeTab == i }"
|
||||
@tap="handleTapItem"
|
||||
v-for="(v, i) in tabs"
|
||||
:key="i"
|
||||
>
|
||||
<view class="">
|
||||
{{ v }}
|
||||
</view>
|
||||
<view class="bottomborder"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view
|
||||
class="v-tabs__line"
|
||||
:style="{ width: `${lineWidth}px`, height: `${lineHeight}`, backgroundColor: lineColor, transform: `translateX(${lineLeft}px)`, top: `calc(${height} - ${lineHeight})` }"
|
||||
></view> -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* tabs 选项卡
|
||||
* @description tabs选项卡
|
||||
* @property {String|Number} value 双向绑定的选中值
|
||||
* @property {String} height=50px 高度
|
||||
* @property {Array} tabs 选项卡列表 ['测试1', '测试2', '测试3']
|
||||
* @property {String} backgroundColor 选中背景色
|
||||
* @property {String} borderRadius 选中圆角
|
||||
* @property {String} color 默认文字的颜色
|
||||
* @property {String} activeColor 选中文字颜色
|
||||
* @property {String} fontSize 默认文字大小
|
||||
* @property {String} activeFontSize 选中文字大小
|
||||
* @property {Number} lineScale 选中标签下划线的缩放级别
|
||||
* @property {String} lineHeight 选中标签下划线的高度
|
||||
* @property {String} lineColor 选中下划线的颜色
|
||||
*
|
||||
* @event {Function(activeTab)} change 改变标签触发
|
||||
*/
|
||||
export default {
|
||||
name: 'VTabs',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '45px'
|
||||
},
|
||||
tabs: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: 'transparent'
|
||||
},
|
||||
borderRadius: {
|
||||
type: String,
|
||||
default: '5px'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
activeColor: {
|
||||
type: String,
|
||||
default: '#007AFF'
|
||||
},
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: '14px'
|
||||
},
|
||||
activeFontSize: {
|
||||
type: String,
|
||||
default: '14px'
|
||||
},
|
||||
padding: {
|
||||
type: String,
|
||||
default: '10rpx 20rpx'
|
||||
},
|
||||
lineScale: {
|
||||
type: Number,
|
||||
default: 0.6
|
||||
},
|
||||
lineHeight: {
|
||||
type: String,
|
||||
default: '3px'
|
||||
},
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: '#007AFF'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollLeft: 0,
|
||||
activeTab: 0,
|
||||
width: 0,
|
||||
lineLeft: 0,
|
||||
lineWidth: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeTab(newVal) {
|
||||
this.$emit('input', newVal * 1)
|
||||
},
|
||||
value(newVal) {
|
||||
this.activeTab = newVal
|
||||
this.getTabsWidth(0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTapItem(e) {
|
||||
const index = e.currentTarget.dataset.index
|
||||
if (this.activeTab != index) {
|
||||
this.activeTab = index
|
||||
this.getTabsWidth(e.currentTarget.offsetLeft)
|
||||
this.$emit('change', this.activeTab)
|
||||
}
|
||||
},
|
||||
getTabsWidth(offsetLeft) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('.v-tabs')
|
||||
.boundingClientRect(data => {
|
||||
this.width = data.width
|
||||
})
|
||||
.exec()
|
||||
setTimeout(() => {
|
||||
let i = 0
|
||||
let width = 0
|
||||
query
|
||||
.selectAll('.v-tabs__item')
|
||||
.boundingClientRect(data => {
|
||||
width = data.reduce((total, currentValue, currentIndex, arr) => {
|
||||
if (currentIndex < this.activeTab) {
|
||||
total = total + currentValue.width
|
||||
}
|
||||
return total
|
||||
}, 0)
|
||||
const padding = this.padding.split(' ')[0]
|
||||
const res = /(\d+)(upx|rpx|px)/.exec(padding)
|
||||
if (res && (res[2] == 'upx' || res[2] == 'rpx')) {
|
||||
width += uni.upx2px(res[1]) * 2 * this.activeTab
|
||||
} else {
|
||||
width += res[1] * this.activeTab
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
query
|
||||
.select('.v-tabs__item.active')
|
||||
.boundingClientRect(data => {
|
||||
const ol = offsetLeft ? offsetLeft : width
|
||||
if (data.width) {
|
||||
this.lineLeft = ol + (data.width * (1 - this.lineScale)) / 2
|
||||
this.lineWidth = data.width * this.lineScale
|
||||
this.scrollLeft = ol - (this.width - data.width) / 2
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
}, 10)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.activeTab = this.value
|
||||
this.getTabsWidth(0)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-tabs {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
border-bottom: 1rpx solid #dddddd;
|
||||
.v-tabs__inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
background-color: #fefefe;
|
||||
// border-bottom: 1rpx solid #dddddd;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.active{
|
||||
border-radius: 0 !important;
|
||||
.bottomborder{
|
||||
width: 42rpx;
|
||||
height: 6rpx;
|
||||
margin: 0 auto;
|
||||
background-color: #1B66FF;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
display: block !important;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
.v-tabs__item {
|
||||
// display: inline-flex;
|
||||
margin-right: 20upx;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.v-tabs__line {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
transition: all 0.3s linear;
|
||||
border-radius: 4upx;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user