纸通宝小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

128 lines
3.1 KiB

Component({
properties: {
// 数据源
tabData: {
type: Array,
value: [],
observer: "dataChange"
},
// 是否可以超出滚动
tabIndex: {
type: Number,
value: 0,
observer: "tabIndexChange"
},
// 是否可以超出滚动
scroll: {
type: Boolean,
value: false
},
lineHeight: {
type: Number,
value: 3,
},
// view宽度
padding: {
type: Number,
value: 0,
},
// tab高度
size: {
type: Number,
value: 90,
observer: "sizeChange"
},
// 颜色
color: {
type: String,
value: ""
},
lineType: {
type: Number,
value: 0,
},
disable: {
type: Boolean,
value: false
}
},
data: {
/* 未渲染数据 */
tabItems: [], // 所有 tab 节点信息
/* 渲染数据 */
scrolling: true, // 控制 scroll-view 滚动以在异步加载数据的时候能正确获得 dom 信息
needTransition: false, // 下划线是否需要过渡动画
translateX: 0, // 下划 line 的左边距离
lineWidth: 0, // 下划 line 宽度
scrollLeft: 0, // scroll-view 左边滚动距离
},
methods: {
/**
* 切换菜单
*/
toggleTab(e) {
if(this.data.disable){
return
}
this.triggerEvent('change', {index: e.currentTarget.dataset.index});
this.scrollByIndex(e.currentTarget.dataset.index);
},
/**
* 滑动到指定位置
* @param tabIndex: 当前激活的tabItem的索引
* @param needTransition: 下划线是否需要过渡动画, 第一次进来应设置为false
*/
scrollByIndex(tabIndex, needTransition = true) {
let item = this.data.tabItems[tabIndex];
if (!item) return;
let itemWidth = item.width || 0,
itemLeft = item.left || 0;
this.setData({needTransition: needTransition})
if(this.data.padding){
itemLeft -= this.data.padding
}
if (this.data.scroll) { // 超出滚动的情况
// 保持滚动后当前 item '尽可能' 在屏幕中间
let scrollLeft = itemLeft - (this.data.windowWidth - itemWidth) / 2;
this.setData({ tabIndex: tabIndex, scrollLeft: scrollLeft, translateX: itemLeft, lineWidth: itemWidth })
} else { // 不超出滚动的情况
this.setData({ tabIndex: tabIndex, translateX: itemLeft, lineWidth: itemWidth })
}
},
/**
* 监听数据变化, 如果改变重新初始化参数
*/
dataChange(newVal, oldVal) {
this.setData({ scrolling: false })
// 异步加载数据时候, 延迟执行 init 方法, 防止基础库 2.7.1 版本及以下无法正确获取 dom 信息
setTimeout(() => this.init(), 10)
},
/**
* 监听 tabIndex 变化, 做对应处理
*/
tabIndexChange(newVal, oldVal) {
this.scrollByIndex(newVal)
},
/**
* 监听 tab 高度变化, 最小值为80rpx
*/
sizeChange(newVal, oldVal) {
if (newVal <= 60) {
this.setData({size: 60})
}
},
/**
* 初始化函数
*/
init() {
const {windowWidth} = wx.getSystemInfoSync()
this.setData({windowWidth: windowWidth || 375})
this.createSelectorQuery().selectAll(".tabs__item-child").boundingClientRect((res) => {
this.setData({ scrolling: true, tabItems: res })
this.scrollByIndex(this.data.tabIndex, false)
}).exec()
}
}
})