feat(fittingRoom): 新增试衣间功能
- 添加 fittingRoom 存储模块,用于管理试衣间状态和数据 - 实现试衣间页面布局和基础功能,包括轮播图、标签页、衣服网格等组件 - 开发选择模特和上传衣服功能 - 优化页面样式和交互
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
## 2.2.2(2024-12-10)
|
||||
1. [修复]修复`change`事件不生效的bug
|
||||
## 2.2.1(2024-11-13)
|
||||
1. [修复]修复摇树打包出现的bug
|
||||
## 2.2.0(2024-07-19)
|
||||
1. [修改]增加节流函数,控制tab的点击间隔
|
||||
## 2.1.9(2024-06-14)
|
||||
1. [修改]当`current`初始值大于`tabs.length`或者小于`0`,自动设置`current`的值为`0`
|
||||
2. [抛弃]压缩包方式的源码不提供维护了,只维护`uni_modules`中的源码
|
||||
## 2.1.8(2024-06-07)
|
||||
1. [新增]支持`vue3`了
|
||||
## 2.1.6(2024-06-06)
|
||||
1. [修复]当有`fixed`属性之后,在支付宝小程序无法滚动的bug
|
||||
## 2.1.5(2023-11-02)
|
||||
1. [修复]修复`change`和`v-model`绑定的值不同步
|
||||
2. [修复]暂时停用`activeFontSize`选项
|
||||
3. [修改]修改默认激活的文字不加粗
|
||||
## 2.1.4(2023-10-12)
|
||||
1. [修改]修改计算方式
|
||||
2. [新增]外部可以通过`this.$refs.tabs.update()`方法主动更新
|
||||
## 2.1.3(2023-09-11)
|
||||
1. [新增]支持自定义插槽模式,具体可以查看示例代码使用方式。[gitee demo](https://github.com/xfjpeter/uni-plugins/blob/3e2bd062163f664889122fd74b8bd6ccad6a97f1/pages/tabs/tabs.vue#L47C10-L50C16) 或 [github demo](https://github.com/xfjpeter/uni-plugins/blob/3e2bd062163f664889122fd74b8bd6ccad6a97f1/pages/tabs/tabs.vue#L47C10-L50C16)
|
||||
## 2.1.2(2023-06-12)
|
||||
1. [新增]添加`z-index`参数控制层级大小,默认1993
|
||||
2. [说明]以后该插件只更新`uni_modules`方式的,`zip`方式的不提供更新了
|
||||
## 2.1.1(2022-09-16)
|
||||
1. 将插件更新为`uni_modules`方式
|
||||
## 2.1.0(2022-08-12)
|
||||
1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下)
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabs: [{ id: 1, name: '' }]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.0.10(2022-01-27)
|
||||
|
||||
1. 更新属性line-animation设置为false可以不要动画,这是好多朋友问到,特此加上
|
||||
|
||||
## 2.0.9(2020-10-12)
|
||||
|
||||
1. 修复 v-tabs 第一次可能出现第一个标签显示不完整的情况
|
||||
2. 修改了 pages/tabs/order 示例文件
|
||||
|
||||
## 2.0.8(2020-09-21)
|
||||
|
||||
1. 修复添加 fixed 属性后,滚动条无效
|
||||
2. 修复选项很少的情况下,下划线计算计算错误
|
||||
3. 新增 paddingItem 属性,设置选项左右边距(上下边距需要设置 height 属性,或者设置 padding 属性)
|
||||
|
||||
## 2.0.7(2020-09-17)
|
||||
|
||||
1. 紧急修复 bug,横向滑动不了的情况
|
||||
|
||||
## 2.0.6(2020-09-16)
|
||||
|
||||
1. 新增 fixed 属性,是否固定在顶部,示例地址:pages/tabs/tabs-static
|
||||
2. 优化之前的页面结构
|
||||
|
||||
## 2.0.5(2020-09-09)
|
||||
|
||||
1. 修复 width 错误,dom 加载的时候没有及时获取到 data 属性导致的 。
|
||||
|
||||
## 2.0.4(2020-08-29)
|
||||
|
||||
1. 优化异步改变 tabs 后,下划线不初始化问题
|
||||
2. github 地址上有图 2 的源码,需要的自行下载,页面路径:pages/tabs/order.vue
|
||||
|
||||
## 2.0.3(2020-08-20)
|
||||
|
||||
1. 优化 节点查询 和 选中渲染
|
||||
2. 优化支付宝中 createSelectorQuery() 的影响
|
||||
|
||||
**特别说明:**
|
||||
|
||||
> 支付宝中平铺方法和其他方法不能在一个页面中出现,不然有一个显示错误(具体什么原因没查到,有好心的人发现了,望告知一下,感谢
|
||||
|
||||
## 2.0.2(2020-08-19)
|
||||
|
||||
1. 优化 change 事件触发机制
|
||||
|
||||
## 2.0.1(2020-08-16)
|
||||
|
||||
1. 修改默认高度为 70rpx
|
||||
2. 新增属性 bgColor,可设置背景颜色,默认 #fff
|
||||
3. 新增整个 tab 的 padding 属性,默认 0
|
||||
|
||||
## 2.0.0(2020-08-13)
|
||||
|
||||
1. 全新的 v-tabs 2.0
|
||||
2. 支持 H5 小程序 APP
|
||||
3. 属性高度可配置
|
||||
|
||||
## 1.3.2(2020-07-21)
|
||||
|
||||
1. 新增 auto 的配置,是否平铺 tab
|
||||
2. 修复文档上的错误示例(感谢 lushgwe@163.com 的反馈)
|
||||
|
||||
## 1.3.0(2020-07-05)
|
||||
|
||||
1. 新增 padding 的可配置
|
||||
2. 修复 v-model 双向绑定问题
|
||||
3. 修复初始化下划线没定位的为题
|
||||
|
||||
## 1.2.0(2020-06-19)
|
||||
|
||||
1. 添加注释
|
||||
2. 修复 bug
|
||||
|
||||
## 1.1.8(2020-06-11)
|
||||
|
||||
1. 添加 change 事件
|
||||
2. 修复插件内容问题
|
||||
3. 修复下划线不居中问题
|
||||
|
||||
## 1.1.6(2020-06-11)
|
||||
|
||||
1. 添加 change 事件
|
||||
2. 修复插件内容问题
|
||||
|
||||
## 1.1.4(2020-06-11)
|
||||
|
||||
1. 添加 change 事件
|
||||
2. 修复插件内容问题
|
||||
|
||||
## 1.1.2(2020-06-11)
|
||||
|
||||
1. 添加 change 事件
|
||||
|
||||
## 1.1.1(2020-06-09)
|
||||
|
||||
1. 修复小程序端选中的下划线不显示问题
|
||||
2. 新增 tab 高度设置
|
||||
3. lineHeight 修改为只支持 String 方式
|
||||
|
||||
## 1.1.0(2020-06-09)
|
||||
|
||||
1. 修复小程序端选中的下划线不显示问题
|
||||
2. 新增 tab 高度设置
|
||||
3. lineHeight 修改为只支持 String 方式
|
||||
|
||||
## 1.0.0(2020-06-04)
|
||||
|
||||
1. 更新插件1.0.0
|
||||
@@ -0,0 +1,100 @@
|
||||
export default {
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
modelValue: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
tabs: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
},
|
||||
padding: {
|
||||
type: String,
|
||||
default: '0'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333'
|
||||
},
|
||||
activeColor: {
|
||||
type: String,
|
||||
default: '#2979ff'
|
||||
},
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: '28rpx'
|
||||
},
|
||||
activeFontSize: {
|
||||
type: String,
|
||||
default: '32rpx'
|
||||
},
|
||||
bold: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
scroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '70rpx'
|
||||
},
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: '#2979ff'
|
||||
},
|
||||
lineHeight: {
|
||||
type: [String, Number],
|
||||
default: '10rpx'
|
||||
},
|
||||
lineScale: {
|
||||
type: Number,
|
||||
default: 0.5
|
||||
},
|
||||
lineRadius: {
|
||||
type: String,
|
||||
default: '10rpx'
|
||||
},
|
||||
pills: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pillsColor: {
|
||||
type: String,
|
||||
default: '#2979ff'
|
||||
},
|
||||
pillsBorderRadius: {
|
||||
type: String,
|
||||
default: '10rpx'
|
||||
},
|
||||
field: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
paddingItem: {
|
||||
type: String,
|
||||
default: '0 22rpx'
|
||||
},
|
||||
lineAnimation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 1993
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 启动一个微任务。
|
||||
*
|
||||
* 该函数旨在兼容不同环境下的微任务调度。微任务是一种在主任务(如事件循环中的回调)之后,但在下一次渲染之前执行的JavaScript任务。
|
||||
* 它们对于异步编程和性能优化非常重要。此函数尝试使用三种不同的方法来调度微任务,取决于环境的支持情况。
|
||||
*
|
||||
* @param {Function} callback - 待执行的微任务回调函数。
|
||||
*/
|
||||
export function startMicroTask(callback) {
|
||||
// 如果队列微任务是可用的,直接使用队列微任务的方法来调度回调。
|
||||
if (typeof queueMicrotask === 'function') {
|
||||
queueMicrotask(callback)
|
||||
} else if (typeof MutationObserver === 'function') {
|
||||
// 如果MutationObserver可用,使用它来创建一个微任务。
|
||||
// 这是一种旧的兼容性方法,因为MutationObserver在较早的浏览器版本中就已经支持。
|
||||
const node = document.createElement('div')
|
||||
const observer = new MutationObserver(callback)
|
||||
observer.observe(node, { childList: true })
|
||||
node.textContent = 'xfjpeter'
|
||||
} else {
|
||||
// 如果以上两种方法都不可用,退回到使用setTimeout来模拟微任务。
|
||||
// 这是最后的选择,因为setTimeout不是真正的微任务,但它可以在不支持微任务的环境中提供类似的功能。
|
||||
setTimeout(callback, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 函数节流器。
|
||||
* 通过限制函数调用的频率,防止在高频率事件(如窗口滚动或鼠标移动)中过多调用给定的函数,从而优化性能。
|
||||
*
|
||||
* @param {Function} fn 要节流的函数。
|
||||
* @param {number} delay 延迟的毫秒数,在这段时间内只能调用一次给定的函数。
|
||||
* @returns {Function} 返回一个新的节流函数,它将控制原始函数的调用频率。
|
||||
*/
|
||||
/**
|
||||
* 函数节流器
|
||||
* @param {Function} fn 要节流的函数
|
||||
* @param {number} delay 延迟的毫秒数
|
||||
* @returns {Function} 返回节流后的函数
|
||||
*/
|
||||
export function throttle(fn, delay) {
|
||||
// 用于存储定时器ID
|
||||
let timeoutId
|
||||
// 用于记录上一次函数执行的时间
|
||||
let lastExecuted = 0
|
||||
|
||||
// 返回一个节流函数
|
||||
return function () {
|
||||
// 保存当前上下文和参数
|
||||
const context = this
|
||||
const args = arguments
|
||||
// 获取当前时间
|
||||
const now = Date.now()
|
||||
// 计算剩余时间
|
||||
const remaining = delay - (now - lastExecuted)
|
||||
|
||||
// 实际执行函数的内部函数
|
||||
function execute() {
|
||||
lastExecuted = now
|
||||
// 在当前上下文中调用原始函数,并传入参数
|
||||
fn.apply(context, args)
|
||||
}
|
||||
|
||||
// 如果剩余时间小于等于0,表示可以执行函数
|
||||
if (remaining <= 0) {
|
||||
// 如果存在定时器,则清除定时器
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId)
|
||||
timeoutId = null
|
||||
}
|
||||
// 执行函数
|
||||
execute()
|
||||
} else {
|
||||
// 如果不存在定时器,则设置定时器
|
||||
if (!timeoutId) {
|
||||
timeoutId = setTimeout(() => {
|
||||
timeoutId = null
|
||||
// 执行函数
|
||||
execute()
|
||||
}, remaining)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 函数防抖动封装。
|
||||
* 函数防抖(debounce)是指在事件被触发n秒后,才执行回调,如果在这n秒内事件又被触发,则重新计时。
|
||||
* 主要用于限制函数调用的频率,常用于输入事件处理函数(如输入框的keyup事件)和窗口大小调整事件等。
|
||||
*
|
||||
* @param {Function} fn 需要被延迟执行的函数。
|
||||
* @param {number} delay 延迟执行的时间,单位为毫秒。
|
||||
* @returns {Function} 返回一个经过防抖动处理的函数。
|
||||
*/
|
||||
export function debounce(fn, delay) {
|
||||
// 用于存储定时器的变量
|
||||
let timer = null
|
||||
|
||||
// 返回一个封装函数
|
||||
return function () {
|
||||
// 如果定时器存在,则清除之前的定时器
|
||||
if (timer) clearTimeout(timer)
|
||||
|
||||
// 设置新的定时器,延迟执行原函数
|
||||
timer = setTimeout(() => {
|
||||
// 使用apply确保函数在正确的上下文中执行,并传递所有参数
|
||||
fn.apply(this, arguments)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<view class="v-tabs">
|
||||
<scroll-view
|
||||
:id="getDomId"
|
||||
:scroll-x="scroll"
|
||||
:scroll-left="scroll ? scrollLeft : 0"
|
||||
:scroll-with-animation="scroll"
|
||||
:style="{ position: fixed ? 'fixed' : 'relative', zIndex, width: '100%' }">
|
||||
<view
|
||||
class="v-tabs__container"
|
||||
:style="{
|
||||
display: scroll ? 'inline-flex' : 'flex',
|
||||
whiteSpace: scroll ? 'nowrap' : 'normal',
|
||||
background: bgColor,
|
||||
height,
|
||||
padding
|
||||
}">
|
||||
<view
|
||||
:class="['v-tabs__container-item', { disabled: !!v.disabled }, { active: current == i }]"
|
||||
v-for="(v, i) in tabs"
|
||||
:key="i"
|
||||
:style="{
|
||||
color: current == i ? activeColor : color,
|
||||
fontSize: current == i ? fontSize : fontSize,
|
||||
fontWeight: bold && current == i ? 'bold' : '',
|
||||
justifyContent: !scroll ? 'center' : '',
|
||||
flex: scroll ? '' : 1,
|
||||
padding: paddingItem
|
||||
}"
|
||||
@click="change(i)">
|
||||
<slot :row="v" :index="i">{{ field ? v[field] : v }}</slot>
|
||||
</view>
|
||||
<template v-if="!!tabs.length">
|
||||
<view
|
||||
v-if="!pills"
|
||||
:class="['v-tabs__container-line', { animation: lineAnimation }]"
|
||||
:style="{
|
||||
background: lineColor,
|
||||
width: lineWidth + 'px',
|
||||
height: lineHeight,
|
||||
borderRadius: lineRadius,
|
||||
transform: `translate3d(${lineLeft}px, 0, 0)`
|
||||
}" />
|
||||
<view
|
||||
v-else
|
||||
:class="['v-tabs__container-pills', { animation: lineAnimation }]"
|
||||
:style="{
|
||||
background: pillsColor,
|
||||
borderRadius: pillsBorderRadius,
|
||||
width: currentWidth + 'px',
|
||||
transform: `translate3d(${pillsLeft}px, 0, 0)`,
|
||||
height
|
||||
}" />
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- fixed 的站位高度 -->
|
||||
<view class="v-tabs__placeholder" :style="{ height: fixed ? height : '0', padding }"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { startMicroTask, throttle } from './utils'
|
||||
import props from './props'
|
||||
/**
|
||||
* v-tabs
|
||||
* @property {Number} value 选中的下标
|
||||
* @property {Array} tabs tabs 列表
|
||||
* @property {String} bgColor = '#fff' 背景颜色
|
||||
* @property {String} color = '#333' 默认颜色
|
||||
* @property {String} activeColor = '#2979ff' 选中文字颜色
|
||||
* @property {String} fontSize = '28rpx' 默认文字大小
|
||||
* @property {String} activeFontSize = '28rpx' 选中文字大小
|
||||
* @property {Boolean} bold = [true | false] 选中文字是否加粗
|
||||
* @property {Boolean} scroll = [true | false] 是否滚动
|
||||
* @property {String} height = '60rpx' tab 的高度
|
||||
* @property {String} lineHeight = '10rpx' 下划线的高度
|
||||
* @property {String} lineColor = '#2979ff' 下划线的颜色
|
||||
* @property {Number} lineScale = 0.5 下划线的宽度缩放比例
|
||||
* @property {String} lineRadius = '10rpx' 下划线圆角
|
||||
* @property {Boolean} pills = [true | false] 是否胶囊样式
|
||||
* @property {String} pillsColor = '#2979ff' 胶囊背景色
|
||||
* @property {String} pillsBorderRadius = '10rpx' 胶囊圆角大小
|
||||
* @property {String} field 如果是对象,显示的键名
|
||||
* @property {Boolean} fixed = [true | false] 是否固定
|
||||
* @property {String} paddingItem = '0 22rpx' 选项的边距
|
||||
* @property {Boolean} lineAnimation = [true | false] 下划线是否有动画
|
||||
* @property {Number} zIndex = 1993 默认层级
|
||||
*
|
||||
* @event {Function(current)} change 改变标签触发
|
||||
*/
|
||||
export default {
|
||||
name: 'VTabs',
|
||||
props,
|
||||
// #ifdef VUE3
|
||||
emits: ['update:modelValue', 'change'],
|
||||
// #endif
|
||||
data() {
|
||||
return {
|
||||
lineWidth: 30,
|
||||
currentWidth: 0, // 当前选项的宽度
|
||||
lineLeft: 0, // 滑块距离左侧的位置
|
||||
pillsLeft: 0, // 胶囊距离左侧的位置
|
||||
scrollLeft: 0, // 距离左边的位置
|
||||
container: { width: 0, height: 0, left: 0, right: 0 }, // 容器的宽高,左右距离
|
||||
current: 0, // 当前选中项
|
||||
scrollWidth: 0 // 可以滚动的宽度
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getDomId() {
|
||||
const len = 16
|
||||
const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
|
||||
const maxPos = $chars.length
|
||||
let pwd = ''
|
||||
for (let i = 0; i < len; i++) {
|
||||
pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
|
||||
}
|
||||
return `xfjpeter_${pwd}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// #ifdef VUE3
|
||||
modelValue: {
|
||||
// #endif
|
||||
// #ifdef VUE2
|
||||
value: {
|
||||
// #endif
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.current = newVal > -1 && newVal < this.tabs.length ? newVal : 0
|
||||
this.$nextTick(this.update)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换事件
|
||||
change: throttle(function(index) {
|
||||
const isDisabled = !!this.tabs[index].disabled
|
||||
if (this.current !== index && !isDisabled) {
|
||||
this.current = index
|
||||
// #ifdef VUE3
|
||||
this.$emit('update:modelValue', index)
|
||||
// #endif
|
||||
// #ifdef VUE2
|
||||
this.$emit('input', index)
|
||||
// #endif
|
||||
this.$emit('change', index)
|
||||
}
|
||||
}, 300),
|
||||
createQueryHandler() {
|
||||
let query
|
||||
// #ifndef MP-ALIPAY
|
||||
query = uni.createSelectorQuery().in(this)
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
query = uni.createSelectorQuery()
|
||||
// #endif
|
||||
|
||||
return query
|
||||
},
|
||||
update() {
|
||||
const _this = this
|
||||
startMicroTask(() => {
|
||||
// 没有列表的时候,不执行
|
||||
if (!this.tabs.length) return
|
||||
_this
|
||||
.createQueryHandler()
|
||||
.select(`#${this.getDomId}`)
|
||||
.boundingClientRect(data => {
|
||||
const { width, height, left, right } = data || {}
|
||||
// 获取容器的相关属性
|
||||
this.container = { width, height, left, right: right - width }
|
||||
_this.calcScrollWidth()
|
||||
_this.setScrollLeft()
|
||||
_this.setLine()
|
||||
})
|
||||
.exec()
|
||||
})
|
||||
},
|
||||
// 计算可以滚动的宽度
|
||||
calcScrollWidth(callback) {
|
||||
const view = this.createQueryHandler().select(`#${this.getDomId}`)
|
||||
view.fields({ scrollOffset: true })
|
||||
view
|
||||
.scrollOffset(res => {
|
||||
if (typeof callback === 'function') {
|
||||
callback(res)
|
||||
} else {
|
||||
// 获取滚动条的宽度
|
||||
this.scrollWidth = res.scrollWidth
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
},
|
||||
// 设置滚动条滚动的进度
|
||||
setScrollLeft() {
|
||||
this.calcScrollWidth(res => {
|
||||
// 动态读取 scrollLeft
|
||||
let scrollLeft = res.scrollLeft
|
||||
this.createQueryHandler()
|
||||
.select(`#${this.getDomId} .v-tabs__container-item.active`)
|
||||
.boundingClientRect(data => {
|
||||
if (!data) return
|
||||
// 除开当前选项外容器的一半宽度
|
||||
let curHalfWidth = (this.container.width - data.width) / 2
|
||||
let scrollDiff = this.scrollWidth - this.container.width
|
||||
// 在原有滚动条的基础上 + (当前元素距离左侧的距离 - 计算的一半宽度) - 容器的外边距之类的
|
||||
scrollLeft += data.left - curHalfWidth - this.container.left
|
||||
// 已经滚动在左侧了
|
||||
if (scrollLeft < 0) scrollLeft = 0
|
||||
// 已经超出右侧了
|
||||
else if (scrollLeft > scrollDiff) scrollLeft = scrollDiff
|
||||
this.scrollLeft = scrollLeft
|
||||
})
|
||||
.exec()
|
||||
})
|
||||
},
|
||||
setLine() {
|
||||
this.calcScrollWidth(res => {
|
||||
const scrollLeft = res.scrollLeft
|
||||
this.createQueryHandler()
|
||||
.select(`#${this.getDomId} .v-tabs__container-item.active`)
|
||||
.boundingClientRect(data => {
|
||||
if (!data) return
|
||||
if (this.pills) {
|
||||
this.currentWidth = data.width
|
||||
this.pillsLeft = scrollLeft + data.left - this.container.left
|
||||
} else {
|
||||
this.lineWidth = data.width * this.lineScale
|
||||
this.lineLeft = scrollLeft + data.left + (data.width - data.width * this.lineScale) / 2 - this.container.left
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-tabs {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
/* #ifdef H5 */
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
&__container {
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
&-item {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
transition: all 0.3s;
|
||||
white-space: nowrap;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
&-line {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&-pills {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
&-line,
|
||||
&-pills {
|
||||
&.animation {
|
||||
transition: all 0.3s linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"id": "v-tabs",
|
||||
"displayName": "自定义 tab 选项卡 2",
|
||||
"version": "2.2.2",
|
||||
"description": "自定义 tab ,支持多种样式,支持 h5 小程序 app",
|
||||
"keywords": [
|
||||
"v-tabs",
|
||||
"tab",
|
||||
"选项卡"
|
||||
],
|
||||
"repository": "https://github.com/xfjpeter/uni-plugins",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": "1207791534"
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "n"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "n",
|
||||
"app-uvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "n",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"钉钉": "y",
|
||||
"快手": "y",
|
||||
"飞书": "y",
|
||||
"京东": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
## 插件说明
|
||||
|
||||
> 这是 `v-tabs` 插件的升级版本,参数上有很大变动,支持 `H5` `小程序` `手机端`,如果是在之前的插件上升级的话,请注意参数的变更,触发的事件没有变更。
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 1、最基本用法
|
||||
|
||||
- 视图文件
|
||||
|
||||
```html
|
||||
<v-tabs v-model="current" :tabs="tabs" @change="changeTab"></v-tabs>
|
||||
```
|
||||
|
||||
- 脚本文件
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
current: 0,
|
||||
tabs: ['军事', '国内', '新闻新闻', '军事', '国内', '新闻', '军事', '国内', '新闻']
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeTab(index) {
|
||||
console.log('当前选中的项:' + index)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2、平铺整个屏幕
|
||||
|
||||
- 视图文件
|
||||
|
||||
```html
|
||||
<v-tabs v-model="activeTab" :scroll="false" :tabs="['全部', '进行中', '已完成']"></v-tabs>
|
||||
```
|
||||
|
||||
- 脚本文件
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
activeTab: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3、胶囊用法
|
||||
|
||||
- 视图文件
|
||||
|
||||
```html
|
||||
<v-tabs v-model="current" :tabs="tabs" :pills="true" line-height="0" activeColor="#fff" @change="changeTab"></v-tabs>
|
||||
```
|
||||
|
||||
- 脚本文件
|
||||
|
||||
```js
|
||||
data() {
|
||||
return {
|
||||
current: 2,
|
||||
tabs: [
|
||||
'军事',
|
||||
'国内',
|
||||
'新闻新闻',
|
||||
'军事',
|
||||
'国内',
|
||||
'新闻',
|
||||
'军事',
|
||||
'国内',
|
||||
'新闻',
|
||||
],
|
||||
},
|
||||
methods: {
|
||||
changeTab(index) {
|
||||
console.log('当前选中索引:' + index)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 文档说明
|
||||
|
||||
### 1、属性说明
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| :---------------: | :-----: | :-------: | :-----------------------------------------------------------------------: |
|
||||
| tabs | Array | [] | 控制 tab 的列表 |
|
||||
| value | Number | 0 | 必传(双向绑定的值) |
|
||||
| color | String | '#333' | 默认文字颜色 |
|
||||
| activeColor | String | '#2979ff' | 选中文字的颜色 |
|
||||
| fontSize | String | '28rpx' | 默认文字大小(rpx 或 px)(弃用) |
|
||||
| bold | Boolean | true | 是否加粗选中项 |
|
||||
| scroll | Boolean | true | 是否显示滚动条,平铺设置 false |
|
||||
| height | String | '70rpx' | tab 高度(rpx 或 px) |
|
||||
| lineHeight | String | '10rpx' | 滑块高度(rpx 或 px) |
|
||||
| lineColor | String | '#2979ff' | 滑块的颜色 |
|
||||
| lineScale | Number | 0.5 | 滑块宽度缩放值 |
|
||||
| lineRadius | String | '10rpx' | 滑块圆角宽度(rpx 或 px) |
|
||||
| pills | Boolean | false | 是否开启胶囊 |
|
||||
| pillsColor | String | '#2979ff' | 胶囊背景颜色(rpx 或 px) |
|
||||
| pillsBorderRadius | String | '10rpx' | 胶囊圆角宽度(rpx 或 px) |
|
||||
| field | String | '' | 如果 tabs 子项是对象,输入需要展示的键名 |
|
||||
| bgColor | String | '#fff' | 背景色,支持 linear-gradient 渐变 |
|
||||
| padding | String | '0' | 整个 tab padding 属性 |
|
||||
| fixed | Boolean | false | 是否固定在顶部 |
|
||||
| paddingItem | String | '0 22rpx' | 选项的边距(设置上下不生效,需要设置高度) |
|
||||
| lineAnimation | Boolean | true | 是否需要 line 和 pills 的动画,在隐藏页面后默认移动到第一个的时候比较实用 |
|
||||
| zIndex | Number | 1993 | 控制 tab 的层级,默认1993 |
|
||||
|
||||
### 1.1 `tabs`参数展开说明
|
||||
|
||||
#### 1.1.1 当`tabs`仅仅是单纯的数组时候,没有什么特别的地方
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabs: ['全部', '待付款', '待消费', '已完成', '已评价', '已过期', '已退款']
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.1.2 当`tabs`使用的数组对象的方式,特定参数需要注意一下
|
||||
|
||||
- `disabled` 参数,可以控制按钮是否可以点击
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabs: [
|
||||
{ id: 1, name: '待付款', disabled: false },
|
||||
{ id: 2, name: '待收货', disabled: false },
|
||||
{ id: 3, name: '待评价', disabled: false },
|
||||
{ id: 4, name: '退款/售后', disabled: true },
|
||||
{ id: 5, name: '我的订单', disabled: false }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2、事件说明
|
||||
|
||||
| 名称 | 参数 | 说明 |
|
||||
| :----: | :---: | :--------------------------------: |
|
||||
| change | index | 改变选中项触发, index 选中项的下标 |
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2.2.2(2024-12-10)
|
||||
1. [修复]修复`change`事件不生效的bug
|
||||
|
||||
### 2.2.1(2024-11-13)
|
||||
1. [修复]修复摇树打包出现的bug
|
||||
|
||||
### 2.2.0(2024-07-19)
|
||||
1. [修改]增加节流函数,控制tab的点击间隔
|
||||
|
||||
### 2.1.9(2024-06-14)
|
||||
1. [修改]当`current`初始值大于`tabs.length`或者小于`0`,自动设置`current`的值为`0`
|
||||
2. [抛弃]压缩包方式的源码不提供维护了,只维护`uni_modules`中的源码
|
||||
|
||||
### 2.1.8(2024-06-06)
|
||||
1. [新增]支持`vue3`了
|
||||
|
||||
### 2.1.6(2024-06-06)
|
||||
1. [修复]使用`fixed`属性之后,在支付宝小程序无法滚动的bug
|
||||
|
||||
### 2.1.5(2023-11-02)
|
||||
1. [修复]修复`change`和`v-model`绑定的值不同步
|
||||
2. [修复]暂时停用`activeFontSize`选项
|
||||
3. [修改]修改默认激活的文字不加粗
|
||||
|
||||
### 2.1.4(2023-10-12)
|
||||
1. [修改]修改计算方式
|
||||
2. [新增]外部可以通过`this.$refs.tabs.update()`方法主动更新
|
||||
|
||||
### 2.1.3(2023-09-11)
|
||||
1. [新增]支持自定义插槽模式,具体可以查看示例代码使用方式。[gitee demo](https://github.com/xfjpeter/uni-plugins/blob/master/pages/tabs/tabs.vue#L47-L50) 或 [github demo](https://github.com/xfjpeter/uni-plugins/blob/master/pages/tabs/tabs.vue#L47-L50)
|
||||
|
||||
### 2.1.2(2023-06-12)
|
||||
1. [新增]添加`z-index`参数控制层级大小,默认1993
|
||||
2. [说明]以后该插件只更新`uni_modules`方式的,`zip`方式的不提供更新了,如果需要的请到 [gitee uni-plugins](https://gitee.com/xfjpeter/uni-plugins) 或 [github uni-plugins](https://github.com/xfjpeter/uni-plugins)下载源码,自行使用
|
||||
|
||||
### 2.1.1(2022-09-16)
|
||||
|
||||
1. 将插件更新为`uni_modules`方式
|
||||
|
||||
### 2022-08-12
|
||||
|
||||
1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下)
|
||||
|
||||
```js
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tabs: [{ id: 1, name: '' }]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2022-01-27
|
||||
|
||||
1. 更新属性`line-animation`设置为`false`可以不要动画,这是好多朋友问到,特此加上
|
||||
|
||||
### 2020-09-24
|
||||
|
||||
1. 修复 `v-tabs` 第一次可能出现第一个标签显示不完整的情况
|
||||
2. 修改了 `pages/tabs/order` 示例文件
|
||||
|
||||
### 2020-09-21
|
||||
|
||||
1. 修复添加 `fixed` 属性后,滚动条无效
|
||||
2. 修复选项很少的情况下,下划线计算计算错误
|
||||
3. 新增 `paddingItem` 属性,设置选项左右边距(上下边距需要设置 `height` 属性,或者设置 `padding` 属性)
|
||||
|
||||
**写在最后:**
|
||||
欢迎各位老铁反馈 bug ,本人后端 PHP 一枚,只是应为感兴趣前端,自己琢磨,自己搞。如果你在使用的过程中有什么不合理,需要优化的,都可以在下面评论(或加我 QQ: 1207791534),本人看见后回复、修正,感谢。
|
||||
|
||||
### 2020-09-17
|
||||
|
||||
1. 紧急修复 bug,横向滑动不了的情况
|
||||
|
||||
### 2020-09-16
|
||||
|
||||
1. 新增 `fixed` 属性,是否固定在顶部,示例地址:`pages/tabs/tabs-static`
|
||||
2. 优化之前的页面结构
|
||||
|
||||
**注意:**
|
||||
|
||||
1. 使用 `padding` 属性的时候,尽量不要左右边距,会导致下划线位置不对
|
||||
2. 如果不绑定 `v-model` 会导致 `change` 事件改变的时候,下划线不跟随问题
|
||||
|
||||
### 2020-09-09
|
||||
|
||||
1. 修复 `width` 错误,dom 加载的时候没有及时获取到 `data` 属性导致的。
|
||||
|
||||
### 2020-08-29
|
||||
|
||||
1. 优化异步改变 `tabs` 后,下划线不初始化问题
|
||||
2. `github` 地址上有图 2 的源码,需要的自行下载,页面路径:`pages/tabs/order`
|
||||
|
||||
### 2020-08-20
|
||||
|
||||
1. 优化 `节点查询` 和 `选中渲染`
|
||||
2. 优化支付宝中 `createSelectorQuery()` 的影响
|
||||
|
||||
### 2020-08-19
|
||||
|
||||
1. 优化 `change` 事件触发机制
|
||||
|
||||
### 2020-08-16
|
||||
|
||||
1. 修改默认高度为 `70rpx`
|
||||
2. 新增属性 `bgColor`,可设置背景颜色,默认 `#fff`
|
||||
3. 新增整个 `tab` 的 `padding` 属性,默认 `0`
|
||||
|
||||
### 2020-08-13
|
||||
|
||||
1. 全新的 `v-tabs 2.0`
|
||||
2. 支持 `H5` `小程序` `APP`
|
||||
3. 属性高度可配置
|
||||
|
||||
## 预览
|
||||
|
||||

|
||||

|
||||
Reference in New Issue
Block a user