目的:
1.tab标题可以滑动切换,当屏幕左右滑动时标题也进行相应的切换
2.点击tab标题选择按钮,可以选中相应的标题并展示相应的页面内容
3.关于标题:
a.tab标题共有多个,所以一屏无法全部显示
b.tab内容区左右滑动切换时,tab标题随即做标记(active)
c.当active的标题不在当前屏显示时,要使其能显示到当前屏中
一、当前页面
- XML部分代码
<mp-tabs tabs="{{tabs}}" activeTab="{{activeTab}}" swiperClass="weui-tabs-swiper" bindtabclick="onTabCLick" bindchange="onChange" data-current="index" activeClass="tab-bar-title__selected">
</mp-tabs>
<swiper class="weui-tabs-swiper" circular="true" current="{{activeTab}}" duration="{{duration}}" bindchange="handleSwiperChange">
<swiper-item data-current="0">
111
</swiper-item>
<swiper-item data-current="1">
222
</swiper-item>
<swiper-item data-current="2">
3333
</swiper-item>
<swiper-item data-current="3">
4444
</swiper-item>
<swiper-item data-current="4">
5555
</swiper-item>
<swiper-item data-current="5">
6666
</swiper-item>
<swiper-item data-current="6">
777
</swiper-item>
</swiper>
- css部分代码
.tab-content {
height: 100px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: 40rpx;
}
.weui-tabs-bar__title {
font-size: 30rpx;
color: #96d3ef;
padding: 0px 38rpx;
background: #2ea7e0;
}
.tab-bar-title__selected {
font-size: 30rpx;
color: #ffffff;
}
- JS部分代码
注意:
1.tab标题因一排八个,所以使用 scroll-view组件,使其可横向滚动。
2.tab内容可左右滑动切换,使用swiper组件实现
3.设置data-current属性用于:点击当前项时,通过点击事件swichNav中处理e.dataset.current取到点击的目标值
4.swiper组件的current组件用于控制当前显示哪一页
5.swiper组件绑定change事件switchTab,通过e.detail.current拿到当前页
Page({
data: {
tabs: [],
activeTab: 0,
},
handleSwiperChange: function (e) {
var index = e.detail.current;
this.setData({
activeTab: index
});
this.triggerEvent('change', {
index: index
});
},
onLoad() {
const titles = ['标题1', '标题2', '标题3', '标题4', '标题5', '标题6', '标题7']
const tabs = titles.map(item => ({ title: item }))
this.setData({ tabs })
},
onTabCLick(e) {
const index = e.detail.index
this.setData({ activeTab: index })
},
onChange(e) {
const index = e.detail.index
this.setData({ activeTab: index })
}
})
- json部分代码
{
"usingComponents": {
"mp-tabs": "../../components/tabs/index"
}
}
二、组件内容
- xml部分
<view class="weui-tabs">
<view class="weui-tabs-bar__wrp" wx:if="{{!arrowShow}}">
<scroll-view scroll-x scroll-into-view="item_{{currentView}}" scroll-with-animation="{{animation}}" style="width: calc(100% - 72rpx);">
<view class="weui-tabs-bar__content">
<block wx:for="{{tabs}}" wx:key="title">
<view id="item_{{index}}" class="weui-tabs-bar__item" bindtap="handleTabClick" data-index="{{index}}" data-current="{{index}}">
<view class="weui-tabs-bar__title {{activeTab === index ? 'active' : ''}}">
{{item.title}}
</view>
</view>
</block>
</view>
</scroll-view>
<view class="wehx_arrow" bindtap='arrowShow'>
<text class="iconfont iconfont-white icon-jiantou"></text>
</view>
</view>
<view class="weui-tabs-bar__wrp" wx:if="{{arrowShow}}">
<scroll-view style='font-size:30rpx;line-height:80rpx;'>
<view class="weui-flex__item" style="color:#ffffff;padding-left:38rpx;">请选择</view>
</scroll-view>
<view class="wehx_arrow" bindtap='arrowShow'>
<text class="iconfont iconfont-white icon-shangjiantou" ></text>
</view>
</view>
</view>
<swiper current="0" duration="500" class="swiper-item" catchtouchmove="true" wx:if="{{arrowShow}}" bindtap='arrowShow'>
<!-- 遮罩层 -->
<view class="wehx-mask_background"></view>
<swiper-item class="filter-item" style="z-index:1;background:#ffffff;">
<view class="chose-column">
<view class='chose-column-items'>
<view class="chose-column-item {{index== activeTab ? 'chose' : 'un-chose'}}" wx:for="{{tabItms}}" data-index="{{index}}" wx:key="index" data-current="{{index}}" bindtap="handleTabClick" style="{{(index+1)%3==0?'border-right:0;':''}}">
{{item.name}}
</view>
</view>
</view>
</swiper-item>
</swiper>
- css部分代码如下:
.weui-tabs {
width: 100%;
}
.weui-tabs-bar__wrp {
padding-bottom: 40rpx;
background-color: #2ea7e0;
}
.weui-tabs-bar__content {
white-space: nowrap;
}
.weui-tabs-bar__item {
display: inline-block;
height: 80rpx;
line-height: 80rpx;
}
.weui-tabs-bar__title {
display: inline-block;
}
/* 被选中的元素样式 */
.weui-tabs-bar__title.active{
color: #ffffff;
position: relative;
}
/* 被选中的元素下方加下划线 */
.weui-tabs-bar__title.active::after{
content: "";
display: block;
height: 8rpx;
width: 52rpx;
background: #ffffff;
position: absolute;
bottom: 1rpx;
left: 0rpx;
right: 0;
margin: auto;
border-radius: 16rpx;
}
/* 上下箭头 */
.wehx_arrow {
position: absolute;
top: 0;
right: 0;
background: #2ea7e0;
width: 72rpx;
height: 80rpx;
font-size: 32rpx;
text-align: center;
line-height: 80rpx;
}
/*********tab点击筛选***********/
.wehx-mask_background {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: black;
opacity: 0.5;
}
.swiper-item {
z-index: 2;
width: 100%;
height: 100%;
position: fixed;
left: 0;
bottom: 0;
right: 0;
top: 182rpx;
animation: filterDisplay;
}
@keyframes filterDisplay {
from {
height: 0;
}
to {
height: 40%;
}
}
.filter-item {
z-index:1;background:#ffffff;top:-1rpx;
overflow: hidden;
height:40% !important;
}
.chose-column {
height: auto;
overflow: hidden;
}
.chose-column-item {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
-moz-box-sizing: border-box;/* Firefox */
-webkit-box-sizing: border-box;/* Safari */
float: left;
width: 33.33%;
height:120rpx;
font-size: 26rpx;
text-align: center;
padding: 0 40rpx;
border-right: 1rpx solid #e5e5e5;
border-bottom: 1rpx solid #e5e5e5;
}
.chose {
color: #2ea7e0;
}
.un-chose {
color: gray;
}
.body-view {
padding: 2rpx 20rpx;
font-size: 26rpx;
color: gray;
}
- js部分代码如下:
module.exports =
/******/
(function (modules) { // webpackBootstrap
/******/ // The module cache
/******/
var installedModules = {};
/******/
/******/ // The require function
/******/
function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/
if (installedModules[moduleId]) {
/******/
return installedModules[moduleId].exports;
/******/
}
/******/ // Create a new module (and put it into the cache)
/******/
var module = installedModules[moduleId] = {
/******/
i: moduleId,
/******/
l: false,
/******/
exports: {}
/******/
};
/******/
/******/ // Execute the module function
/******/
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/
module.l = true;
/******/
/******/ // Return the exports of the module
/******/
return module.exports;
/******/
}
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/
__webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/
__webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/
__webpack_require__.d = function (exports, name, getter) {
/******/
if (!__webpack_require__.o(exports, name)) {
/******/
Object.defineProperty(exports, name, {
enumerable: true,
get: getter
});
/******/
}
/******/
};
/******/
/******/ // define __esModule on exports
/******/
__webpack_require__.r = function (exports) {
/******/
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
/******/
}
/******/
Object.defineProperty(exports, '__esModule', {
value: true
});
/******/
};
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/
__webpack_require__.t = function (value, mode) {
/******/
if (mode & 1) value = __webpack_require__(value);
/******/
if (mode & 8) return value;
/******/
if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/
var ns = Object.create(null);
/******/
__webpack_require__.r(ns);
/******/
Object.defineProperty(ns, 'default', {
enumerable: true,
value: value
});
/******/
if (mode & 2 && typeof value != 'string')
for (var key in value) __webpack_require__.d(ns, key, function (key) {
return value[key];
}.bind(null, key));
/******/
return ns;
/******/
};
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/
__webpack_require__.n = function (module) {
/******/
var getter = module && module.__esModule ?
/******/
function getDefault() {
return module['default'];
} :
/******/
function getModuleExports() {
return module;
};
/******/
__webpack_require__.d(getter, 'a', getter);
/******/
return getter;
/******/
};
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/
__webpack_require__.o = function (object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
/******/
/******/ // __webpack_public_path__
/******/
__webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/
return __webpack_require__(__webpack_require__.s = 5);
/******/
})
/************************************************************************/
/******/
({
/***/
5:
/***/
(function (module, exports, __webpack_require__) {
"use strict";
Component({
options: {
addGlobalClass: true,
pureDataPattern: /^_/,
multipleSlots: true
},
properties: {
tabs: {
type: Array,
value: []
},
// tabClass: { type: String, value: '' },
swiperClass: {
type: String,
value: ''
},
// activeClass: { type: String, value: '' },
tabUnderlineColor: {
type: String,
value: '#ffffff'
},
tabActiveTextColor: {
type: String,
value: '#000000'
},
tabInactiveTextColor: {
type: String,
value: '#000000'
},
tabBackgroundColor: {
type: String,
value: '#ffffff'
},
activeTab: {
type: Number,
value: 0
},
swipeable: {
type: Boolean,
value: true
},
animation: {
type: Boolean,
value: true
},
duration: {
type: Number,
value: 500
},
},
data: {
currentView: 0,
arrowShow: false, // 显示/隐藏切换
tabItms: [
{ name: '标题1' },
{ name: '标题2' },
{ name: '标题3' },
{ name: '标题4' },
{ name: '标题5' },
{ name: '标题6' },
{ name: '标题7' },
],
},
observers: {
activeTab: function activeTab(_activeTab) {
var len = this.data.tabs.length;
if (len === 0) return;
var currentView = _activeTab - 1;
if (currentView < 0) currentView = 0;
if (currentView > len - 1) currentView = len - 1;
this.setData({
currentView: currentView
});
}
},
lifetimes: {
created: function created() { }
},
methods: {
handleTabClick: function handleTabClick(e) {
var index = e.currentTarget.dataset.index;
console.log(index)
this.setData({
activeTab: index,
});
this.triggerEvent('tabclick', {
index: index
});
},
//控制下拉按钮的显示与隐藏 自定义
arrowShow: function arrowShow(e) {
var arrowshow = !this.data.arrowShow
// console.log(toggle)
this.setData({
arrowShow: arrowshow
})
},
// 点击筛选框的子元素 跳转至相应的标题内容
swichNav: function swichNav(e) {
var cur = e.currentTarget.dataset.current;
console.log(this.data)
if (this.data.activeTab == cur) { return false; }
else {
this.setData({
activeTab: cur,
})
}
},
// handleSwiperChange: function handleSwiperChange(e) {
// var index = e.detail.current;
// this.setData({
// activeTab: index
// });
// this.triggerEvent('change', {
// index: index
// });
// },
}
});
/***/
})
/******/
});
- json部分代码如下:
{
"component": true,
"usingComponents": {}
}
最终效果: