vue—顶部选项卡功能的组件封装

效果图:

 

 页面可以左右滑动,上面选项卡主题也会跟着动

功能实现:

  子组件:  

<template>
    <view>
        <!-- 顶部选项卡功能 -->
        <view class="uni-tab-bar">
            <scroll-view scroll-x="true" class="uni-swiper-tab">
                <block v-for="(tab,index) in tabBars" :key="tab.id">
                    <view class="swiper-tab-list" :class="{'active':(tabIndex==index)}" @tap="tabtap(index)">
                        {{tab.name}}
                        <!-- 分割线 -->
                        <view class="swiper-tab-line"></view>
                    </view>
                </block>
            </scroll-view>
        </view>
    </view>
</template>

<script>
    export default {
        props:{
            tabBars:Array,
            tabIndex:Number
        },
        methods: {
            // tabbar点击事件
            tabtap(index){
                // this.tabIndex=index;
                this.$emit('tabtap',index)
            }
        }
    }
</script>

<style scoped>
    .uni-swiper-tab{
        border-bottom: 1rpx solid #EEEEEE;
    }
    .swiper-tab-list{
        color: #969696;
        font-weight: bold;
    }
    .uni-tab-bar .active{
        color: #343434;
    }
    .active .swiper-tab-line{
        border-bottom: 6rpx solid #FEDE33;
        width: 80rpx;
        margin: auto;
        border-top: 6rpx solid #FEDE33;
        border-radius: 20rpx;
    }
</style>

 父组件:

<template>
    <view>
        <!-- 引入顶部选项卡组件 -->
        <swiper-top-tab :tabBars="tabBars" :tabIndex="tabIndex" @tabtap="tabtap"></swiper-top-tab>
        <view class="uni-tab-bar">
            <!-- 页面滑动功能(选项卡也会跟着变化) -->
            <!-- swiper时进行左右滚动的,scroll-view来进行上下的滚动 -->
            <swiper class="swiper-box" :style="{height:(swiperheight+'px')}" :current="tabIndex" @change="tabChange">
                <swiper-item v-for="(items,index) in newslist" :key="index">
                    <scroll-view scroll-y="true" class="list">
                        <!--图文、列表样式  -->
                        <block v-for="(item,index1) in items.list" :key="index1">
                            <!-- 引入图文列表组件 -->
                            <index-list :item="item" :index="index1"></index-list>
                        </block>
                    </scroll-view>
                </swiper-item>
            </swiper>
        </view>    
    </view>
</template>

<script>
    import indexList from "../../components/index/index-list.vue"; 
    import swiperTopTab from "../../components/index/swiper-top-tab.vue"; 
    export default {
        components:{
            indexList,
            swiperTopTab
        },
        data() {
            return {
                // 实际应用中接收后端传来的数据
                swiperheight:550, //默认页面窗口高度
                tabIndex:0, //默认选中第一个
                tabBars:[
                    {name:"关注",id:"guanzhu"},
                    {name:"推荐",id:"tuijian"},
                    {name:"体育",id:"tiyu"},
                    {name:"热点",id:"redian"},
                    {name:"财经",id:"caijing"},
                    {name:"娱乐",id:"yule"},
                ],
                newslist:[
                    {
                        // 关注
                        list:[
                            {
                                userpic:"../../static/demo/userpic/12.jpg",
                                username:"昵称",
                                isguanzhu:false,
                                title:"我是标题",
                                type:"img", //img:图文  video:视频
                                titlepic:"../../static/demo/datapic/11.jpg",
                                playnum:"20w",
                                long:"2:47", //播放时长
                                infonum:{
                                    index:0, //0:没有操作 1:顶  2:踩
                                    dingnum:11,
                                    cainum:11,
                                },
                                commentnum:10,
                                sharenum:10,
                            },
                            {
                                userpic:"../../static/demo/userpic/12.jpg",
                                username:"昵称",
                                isguanzhu:true,
                                title:"我是标题",
                                type:"video", //img:图文  video:视频
                                titlepic:"../../static/demo/datapic/11.jpg",
                                playnum:"20w",
                                long:"2:47", //播放时长
                                infonum:{
                                    index:1, //0:没有操作 1:顶  2:踩
                                    dingnum:11,
                                    cainum:11,
                                },
                                commentnum:10,
                                sharenum:10,
                            }
                        ],
                    },
                    {
                        // 推荐
                        list:[
                            {
                                userpic:"../../static/demo/userpic/12.jpg",
                                username:"昵称",
                                isguanzhu:true,
                                title:"我是标题",
                                type:"video", //img:图文  video:视频
                                titlepic:"../../static/demo/datapic/11.jpg",
                                playnum:"20w",
                                long:"2:47", //播放时长
                                infonum:{
                                    index:1, //0:没有操作 1:顶  2:踩
                                    dingnum:11,
                                    cainum:11,
                                },
                                commentnum:10,
                                sharenum:10,
                            }
                        ],
                    },
                    {
                        // 体育
                        list:[
                            {
                                userpic:"../../static/demo/userpic/12.jpg",
                                username:"昵称",
                                isguanzhu:true,
                                title:"我是标题",
                                type:"video", //img:图文  video:视频
                                titlepic:"../../static/demo/datapic/11.jpg",
                                playnum:"20w",
                                long:"2:47", //播放时长
                                infonum:{
                                    index:1, //0:没有操作 1:顶  2:踩
                                    dingnum:11,
                                    cainum:11,
                                },
                                commentnum:10,
                                sharenum:10,
                            }
                        ],
                    },
                    {
                        list:[],
                    },
                ]
            }
        },
        onLoad() {
            // 注意这里的this指向不是全局的,仅在这个方法中生效(如果使用箭头函数就不会出现这种情况)
            // let that = this;
            uni.getSystemInfo({
                success: (res)=> {
                    // 这里是为了上下滚动时候不会出现顶部选项卡内容被隐藏的问题
                    let height=res.windowHeight-50; //res.windowHeight获取的值单位是px
                    this.swiperheight=height;   //这里记住不能使用ES5的书写方式,而是使用箭头函数来写(否则会出现this指向问题)
                    // console.log(res.windowHeight);
                    // console.log(height);
                    console.log(this.swiperheight);
                }
            });
        },
        methods: {
            // tabbar点击事件
            tabtap(index){
                this.tabIndex=index;
            },
            // 页面滑动事件
            tabChange(e){
                // console.log(JSON.stringify(e.detail));
                this.tabIndex=e.detail.current;
            }
        }
    }
</script>

<!-- uniapp在编译的时候会把子组件和父组件合并成同一个文件,一个组件的CSS可能会污染另一个组件的CSS,所以这时候需要使用scoped限制样式的作用域 -->
<style scoped>
</style>
View Code
一个小小后端的爬行痕迹
原文地址:https://www.cnblogs.com/heikedeblack/p/14649440.html