以下示范了 swiper 嵌套,swiper 内使用 scroll-view,自制 tabbar 控制 swiper。

注意要点。swiper 套 swiper 的时候,内部的 swiper 需要加一个 wrap 外层,要不然它的 swiper-item 高度不能达到 100%。

注意踩坑。截至目前的开发者工具版本 v1.01.171013,有一个不知能不能算 Bug 的问题,scroll-view 的第一个子元素如果有 margin-top,即使 scroll-view 内部未满也会导致其抖动。在官方社区发了个帖,然而依旧老样子,官方没人理我。

目前觉得只有一个小遗憾,实机上 swiper 切换时有点卡顿,或者说 transition 的时间稍稍长了点。

微信小程序

let title = ['标题1', '标题2', '标题3'];

Page({
    data: {
        // index:全局下标 inner:内部滑块下标 outer:外部滑块下标 # 第一个外部滑块里套了两个内部滑块
        swiperSelected: { index: 0, inner: 0, outer: 0 },

        titleSlider: {
            width: 100 / title.length,        // 百分比
            left: 0
        },

        text_title: title
    },
    bindTitleTap: function (e) {
        let id = e.currentTarget.dataset.id,
            swiperSelected = this.data.swiperSelected,
            titleSlider = this.data.titleSlider;

        console.info('当前点击:', id);

        if (swiperSelected.index !== id) {
            swiperSelected.index = id;

            if (id < 2) {
                // 内部滑块
                swiperSelected.inner = id;
                swiperSelected.outer = 0;
            } else {
                // 外部滑块
                swiperSelected.outer = 1;
            }

            titleSlider.left = titleSlider.width * id;

            this.setData({
                swiperSelected,
                titleSlider
            });
        }
    },
    forbidSwiperMove: function () {
        // 禁止左右滑动
    }
});
<view class="weui-flex titles">
    <block wx:for="{{text_title}}" wx:key="*this">
        <text class="{{index === swiperSelected.index ? 'selected' : ''}}" data-id="{{index}}" bindtap="bindTitleTap">{{item}}</text>
    </block>
    <view class="title-slider" style="width: {{titleSlider.width}}%; left: {{titleSlider.left}}%;"></view>
</view>
<swiper class="outer" current="{{swiperSelected.outer}}">
    <swiper-item class="outer" catchtouchmove="forbidSwiperMove">
        <view class="weui-cells">
            <view class="weui-cell" hover-class="weui-cell_active">
                <view class="weui-cell__bd">共享标题</view>
            </view>
        </view>
        <view class="swiper-wrap">
            <swiper class="inner" current="{{swiperSelected.inner}}">
                <swiper-item catchtouchmove="forbidSwiperMove">
                    <scroll-view scroll-y="true" enable-back-to-top="true">
                        <view class="placeholder"></view>
                        <view class="weui-cells">
                            <view class="weui-cell">
                                <view class="weui-cell__bd">测试1</view>
                            </view>
                        </view>
                    </scroll-view>
                </swiper-item>
                <swiper-item catchtouchmove="forbidSwiperMove">
                    <scroll-view scroll-y="true" enable-back-to-top="true">
                        <view class="placeholder"></view>
                        <view class="weui-cells">
                            <view class="weui-cell">
                                <view class="weui-cell__bd">测试2</view>
                            </view>
                        </view>
                    </scroll-view>
                </swiper-item>
            </swiper>
        </view>
    </swiper-item>
    <swiper-item class="outer" catchtouchmove="forbidSwiperMove">
        <scroll-view scroll-y="true" enable-back-to-top="true">
            <view class="placeholder"></view>
            <view class="weui-cells">
                <view class="weui-cell">
                    <view class="weui-cell__bd">测试3</view>
                </view>
            </view>
        </scroll-view>
    </swiper-item>
</swiper>
.titles {
    position: relative;
    z-index: 1;

    background-color: #fcfcfc;
    box-shadow: 0 1px 2px rgba(150, 150, 150, .3);

    justify-content: space-around;
}

.titles text {
    font-size: 32rpx;
    line-height: 80rpx;

    box-sizing: border-box;
    height: 80rpx;
    padding: 0 5px;

    text-align: center;

    flex: auto;
}

.titles text.selected {
    color: #46c01b;
}

.title-slider {
    position: absolute;
    bottom: 0;

    transition: left .5s;
}

.title-slider::after {
    position: absolute;
    bottom: 0;
    left: 50%;

    width: 4em;
    height: 2px;
    margin-left: -2em;

    content: '';

    background-color: #46c01b;
}

swiper.outer {
    height: calc(100vh - 80rpx);
    background-color: red;
}

swiper.inner {
    position: absolute;

    width: 100%;
    height: 100%;
    background-color: #aaa;
}

swiper-item.outer {
    display: flex;
    flex-direction: column;
}

scroll-view {
    height: 100%;
}

scroll-view .weui-cells {
    margin-top: 0;
    margin-bottom: 1.17647059em;
}

.swiper-wrap {
    position: relative;

    flex: auto;
}