project init

This commit is contained in:
zxy
2024-02-02 10:24:54 +08:00
commit 21a84c3035
253 changed files with 25212 additions and 0 deletions

View 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. 修复初始化下划线没定位的为题

View 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>