uniapp实现点击导航栏切换布局内容

一、今日分享内容

        近日在写一个项目的分类列表页面,想和大家分享一下我做“点击顶部导航栏切换布局”的实现思路。

二、代码展示

        布局类(顶部滑动导航栏)

<view class="wrapper">
	<view class="scroller">
		<scroll-view class="scroll" scroll-x="true">
			<view v-for="(item,index) in grabeCate" :key="index" class="scrollitem">
				<!-- url="/pages/details/details" -->
				<text :class="'navigator_item'+(currentTab==index ? 'active' : '')" :data-current="index" @tap.stop="getcate">{{item.name}}</text>
			</view>
		</scroll-view>
	</view>
</view>

        布局类(下方内容类)

<view class="public_list goodList" v-if="search">
	<template v-if="currentTab==0">
		<view class="item acea-row" v-for="(item,index) in subjectCate" :key="index" @click="goDetail(item)">
		    <view class="pictrue">
				<image :src="item.image" mode="aspectFill"></image>
			</view>
			<view class="text">
				<view class="title acea-row row-middle">
					<view class="name line1" v-text="item.title"></view>
				</view>
				<view class="labelList">
					<text class="labelItem" v-for="(label,index) in item.labelmm" :key="index">{{label}}</text>
				</view>
				<view class="acea-row row-middle row-between">
					<view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
					<view class="free" v-else>免费</view>
					<view class="num">{{item.browse_count}}人已学习</view>
				</view>
			</view>
		</view>
		<!--加载loadding-->
		<Loadmore :visible="loadding"></Loadmore>
	</template>
	<template v-else>
		<view class="nav">
			<view class="img">
				<view class="pictrue">
					<image src="../../static/course/all.png" mode="aspectFit"></image>
				</view>
				<text class="name">全部</text>
			</view>
		</view>
		<view class="item acea-row" v-for="(item,index) in subjectCate" :key="index" @click="goDetail(item)">
			<view class="pictrue">
				<image :src="item.image" mode="aspectFill"></image>
			</view>
			<view class="text">
				<view class="title acea-row row-middle">
					<view class="name line1" v-text="item.title"></view>
				</view>
				<view class="labelList">
					<text class="labelItem" v-for="(label,index) in item.labelmm" :key="index">{{label}}</text>
				</view>
				<view class="acea-row row-middle row-between">
					<view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
					<view class="free" v-else>免费</view>
					<view class="num">{{item.browse_count}}人已学习</view>
				</view>
			</view>
		</view>
		<!--加载loadding-->
		<Loadmore :visible="loadding"></Loadmore>
	</template>
</view>

        逻辑类(data数据)

data() {
    return {
		grabeCate: [{ //中间滑动条分类
			id: 0,
			name: '全部'
		}],
		subjectCate: [], //下方分类数据
		currentTab: 0, //点谁谁高亮,唯一导航标记
		loadding: false, //加载动画
		keyword: '', //搜索关键字
		searchCate: [], //搜索后的数据
		search: true//搜索结果展示
	};
},

逻辑类(方法)

getcate(e) {
	// 点击切换导航栏
	this.subjectCate = []
	// console.log(e)
	let cur = e.currentTarget.dataset.current;
	// console.log(cur)
	if (this.currentTab == cur) {
		return false;
	}

	this.currentTab = cur;
	console.log(this.currentTab)
    //定义的请求数据方法
	this.getCateIndex(true);
},
三、思路梳理

        实现思路如下:

我顶部滑动导航栏用scroll-view做,scroll-x="true"是横向滑动。

这里我只写了1个Item,Item里面放很多个点击对象。像这样:

<scroll-view class="scroll" scroll-x="true">
                        <view v-for="(item,index) in grabeCate" :key="index" class="scrollitem">
                            <!-- url="/pages/details/details" -->
                            <text :class="'navigator_item'+(currentTab==index ? 'active' : '')" :data-current="index"
                                @tap.stop="getcate">{{item.name}}</text>
                        </view>
                    </scroll-view>

        其中,绑定动态样式,标记是点击了哪个导航。:class="'navigator_item'+(currentTab==index ? 'active' : '')"。

currentTab我在data中定义了默认是0,也就是默认选中第一个。

:data-current="index"动态传点中的导航下标给方法getcate。也就是循环grabeCate数组后每个东西有个下标,点了之后会把它传给getcate方法进行下一步处理。

        JS中,我方法接到传过来的参数进行处理

getcate(e) {
                // 点击切换导航栏
                this.subjectCate = []
                // console.log(e)
                let cur = e.currentTarget.dataset.current;
                // console.log(cur)
                if (this.currentTab == cur) {
                    return false;
                }

                this.currentTab = cur;
                // console.log(this.currentTab)

                this.getCateIndex(true);
            },

        拿到我当时点击的是哪个东西 let cur = e.currentTarget.dataset.current;

将拿到的点击对象下标赋给data中的currentTab         this.currentTab = cur;

页面再进行渲染,就切换成了新的选中布标。:class="'navigator_item'+(currentTab==index ? 'active' : '')"

        再就是调用数据请求方法。this.getCateIndex(true);

数据请求中获取相对应Item的id是:

let item = this.grabeCate[this.currentTab].id。

其中this.grabeCate是我导航条的数据,this.currentTab是我当时点到的导航条的对象下标

        最后,页面布局切换,是根据data中的currentTab不同而切换。

v-if="currentTab==0"        我这里只写两个布局,一个是全部,一个是分类。0是全部,其他都是分类。所以只判断了是不是0。

四、完整代码展示

        最后的最后。将我所有的代码都展示出来,供各位大佬指正。

布局:

<template>
    <view id="app" class="goodsClass" v-cloak>
        <!-- 顶部搜索框和分栏 -->
        <view class="header">
            <view class="search acea-row row-middle">
                <view class="pictrue">
                    <image src="../../static/course/logo.gif" mode="aspectFit"></image>
                </view>
                <view class="form">
                    <view class="label">
                        <image class="img" src="../../static/course/search.png" mode="aspectFit"></image>
                        <input v-model="keyword" placeholder="输入课程名称" class="input" />
                    </view>
                    <view class="submit" @click="getkeyword(keyword)">
                        搜索
                    </view>
                </view>
            </view>
            <view class="wrapper">
                <view class="scroller">
                    <scroll-view class="scroll" scroll-x="true">
                        <view v-for="(item,index) in grabeCate" :key="index" class="scrollitem">
                            <!-- url="/pages/details/details" -->
                            <text :class="'navigator_item'+(currentTab==index ? 'active' : '')" :data-current="index"
                                @tap.stop="getcate">{{item.name}}</text>
                        </view>
                    </scroll-view>
                </view>
            </view>
            <!-- 全部(分类) -->
            <view class="public_list goodList" v-if="search">
                <template v-if="currentTab==0">
                    <view class="item acea-row" v-for="(item,index) in subjectCate" :key="index" @click="goDetail(item)">
                        <view class="pictrue">
                            <image :src="item.image" mode="aspectFill"></image>
                        </view>
                        <view class="text">
                            <view class="title acea-row row-middle">
                                <view class="name line1" v-text="item.title"></view>
                            </view>
                            <view class="labelList">
                                <text class="labelItem" v-for="(label,index) in item.labelmm"
                                    :key="index">{{label}}</text>
                            </view>
                            <view class="acea-row row-middle row-between">
                                <view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
                                <view class="free" v-else>免费</view>
                                <view class="num">{{item.browse_count}}人已学习</view>
                            </view>
                        </view>
                    </view>
                    <!--加载loadding-->
                    <Loadmore :visible="loadding"></Loadmore>
                </template>
                <template v-else>
                    <view class="nav">
                        <view class="img">
                            <view class="pictrue">
                                <image src="../../static/course/all.png" mode="aspectFit"></image>
                            </view>
                            <text class="name">全部</text>
                        </view>
                    </view>
                    <view class="item acea-row" v-for="(item,index) in subjectCate" :key="index" @click="goDetail(item)">
                        <view class="pictrue">
                            <image :src="item.image" mode="aspectFill"></image>
                        </view>
                        <view class="text">
                            <view class="title acea-row row-middle">
                                <view class="name line1" v-text="item.title"></view>
                            </view>
                            <view class="labelList">
                                <text class="labelItem" v-for="(label,index) in item.labelmm"
                                    :key="index">{{label}}</text>
                            </view>
                            <view class="acea-row row-middle row-between">
                                <view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
                                <view class="free" v-else>免费</view>
                                <view class="num">{{item.browse_count}}人已学习</view>
                            </view>
                        </view>
                    </view>
                    <!--加载loadding-->
                    <Loadmore :visible="loadding"></Loadmore>
                </template>
            </view>
            <!-- 全部(搜索) -->
            <view class="public_list goodList" v-else>
                <template v-if="currentTab==0">
                    <view class="item acea-row" v-for="(item,index) in searchCate" :key="index" @click="goDetail(item)">
                        <view class="pictrue">
                            <image :src="item.image" mode="aspectFill"></image>
                        </view>
                        <view class="text">
                            <view class="title acea-row row-middle">
                                <view class="name line1" v-text="item.title"></view>
                            </view>
                            <view class="labelList">
                                <text class="labelItem" v-for="(label,index) in item.labelmm"
                                    :key="index">{{label}}</text>
                            </view>
                            <view class="acea-row row-middle row-between">
                                <view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
                                <view class="free" v-else>免费</view>
                                <view class="num">{{item.browse_count}}人已学习</view>
                            </view>
                        </view>
                    </view>
                    <!--加载loadding-->
                    <Loadmore :visible="loadding"></Loadmore>
                </template>
                <template v-else>
                    <view class="nav">
                        <view class="img">
                            <view class="pictrue">
                                <image src="../../static/course/all.png" mode="aspectFit"></image>
                            </view>
                            <text class="name">全部</text>
                        </view>
                    </view>
                    <view class="item acea-row" v-for="(item,index) in searchCate" :key="index" @click="goDetail(item)">
                        <view class="pictrue">
                            <image :src="item.image" mode="aspectFill"></image>
                        </view>
                        <view class="text">
                            <view class="title acea-row row-middle">
                                <view class="name line1" v-text="item.title"></view>
                            </view>
                            <view class="labelList">
                                <text class="labelItem" v-for="(label,index) in item.labelmm"
                                    :key="index">{{label}}</text>
                            </view>
                            <view class="acea-row row-middle row-between">
                                <view class="money" v-if="item.money > 0">¥<text>{{item.money}}</text></view>
                                <view class="free" v-else>免费</view>
                                <view class="num">{{item.browse_count}}人已学习</view>
                            </view>
                        </view>
                    </view>
                    <!--加载loadding-->
                    <Loadmore :visible="loadding"></Loadmore>
                </template>
            </view>
        </view>
    </view>
</template>

JS类

<script>
    import request from "../../utils/request.js" //导入请求
    import Loadmore from "@/components/loadmore/loadmore";
    export default {
        components: {
            Loadmore
        },
        data() {
            return {
                grabeCate: [{ //中间滑动条分类
                    id: 0,
                    name: '全部'
                }],
                subjectCate: [], //下方分类数据
                currentTab: 0, //点谁谁高亮,唯一导航标记
                loadding: false, //加载动画
                keyword: '', //搜索关键字
                searchCate: [], //搜索后的数据
                search: true//搜索结果展示
            };
        },
        onLoad() {
            this.getCateList() //获取顶部滑动分类
            this.getCateIndex() //获取二级分类页全部数据
        },
        methods: {
            async getCateList() {
                // 获取顶部分类滑动栏数据
                const res = await request('special/get_grade_cate')
                this.grabeCate = this.grabeCate.concat(res.data)
                console.log(this.grabeCate)
            },
            getcate(e) {
                // 点击切换导航栏
                this.subjectCate = []
                // console.log(e)
                let cur = e.currentTarget.dataset.current;
                // console.log(cur)
                if (this.currentTab == cur) {
                    return false;
                }

                this.currentTab = cur;
                // console.log(this.currentTab)

                this.getCateIndex(true);
            },
            async getCateIndex(refresh) {
                // 请求二级分类数据
                this.loadding = true;
                this.search = true;
                // console.log(refresh)
                let item = this.grabeCate[this.currentTab].id
                // 点上边分类,请求二级分类数据
                const res = await request('special/get_special_list?gradeId=' + item +
                    '&subjectId=0&search=&page=1&limit=10')
                this.subjectCate = (refresh ? res.data : this.subjectCate.concat(res.data));
                // 请求到的二级数据
                console.log(this.subjectCate)
                if (this.subjectCate) {
                    this.loadding = false;
                }
            },
            async getkeyword(keyword) {
                // 搜索二级分类数据
                this.loadding = true;
                this.search = false;
                let item = this.grabeCate[this.currentTab].id
                // 点上边分类,请求二级分类数
                const res = await request('special/get_special_list?gradeId=' + item +
                    '&subjectId=0&search=' + keyword + '&page=1&limit=10')
                this.searchCate = res.data
                // 请求到的二级数据
                console.log(this.searchCate)
                if (this.searchCate) {
                    this.loadding = false;
                }
            },
            goDetail(item){
                // 点击item项跳转详情页
                let detail = item
                // console.log("点击拿到的数据"+JSON.stringify(detail))
                uni.navigateTo({
                    url: "/pages/details/details?detail=" + encodeURIComponent(JSON.stringify(detail))
                })
            }
        }
    }
</script>

五、总结

        我做这个分享仅供各位参考,如有大佬望赐教。

另外,我做完这个页面有个bug。切换布局的时候屏幕会概率闪烁一下。具体原因未查出,有修正版会再次分享。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
UniApp中,通过使用Swiper组件可以实现头部导航栏的滑动效果。首先,在app.vue文件中引入全局样式,可以在其中设置导航栏的样式和布局。可以通过设置组件内部CSS开启导航栏底部阴影效果。接下来,可以结合Swiper组件来实现头部导航栏的滑动切换效果。Swiper组件可以用于创建可滑动的视图容器,可以配合导航栏标签页的切换实现用户在页面之间的滑动切换。这样可以实现更好的效果。所以,通过设置导航栏的样式和布局以及使用Swiper组件,可以实现UniApp头部导航栏的滑动效果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [uniapp常用组件——顶部导航选项栏(可滑动)](https://blog.csdn.net/poppingJ/article/details/108361892)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [uni-app顶部导航(可滑动)](https://blog.csdn.net/maoge_666/article/details/129952640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [TCPView 是一个 Windows 程序,它将显示系统上所有 TCP 和 UDP 终结点的详细列表,包括 tcp 连接](https://download.csdn.net/download/fyq158797/88280042)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乡下小菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值