一、今日分享内容
近日在写一个项目的分类列表页面,想和大家分享一下我做“点击顶部导航栏切换布局”的实现思路。
二、代码展示
布局类(顶部滑动导航栏)
<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。切换布局的时候屏幕会概率闪烁一下。具体原因未查出,有修正版会再次分享。