页面左侧显示分类数据,右侧显示每个分类对应的文章列表,点击分类名称,对应右侧文章内容切换显示。点击文章列表跳转到文章详情。最终页面效果如图:

http://localhost:3000/categorieshttp://localhost:3000/categories/id在 pages/cate/cate.vue 中
<template>
<view id="wrapper">
<view class="scroll-view-container">
<scroll-view class="left-scroll-view" scroll-y :style="{height: wh + 'px'}">
<view class="left-scroll-view-item active">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
<view class="left-scroll-view-item">xxxview>
scroll-view>
<scroll-view class="right-scroll-view" scroll-y :style="{height: wh + 'px'}">
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
<view class="left-scroll-view-item">yyyview>
scroll-view>
view>
<my-footer>my-footer>
view>
template>
<script>
export default {
data() {
return {
// 窗口的可用高度 = 屏幕高度 - navigationBar高度 - tabBar 高度
wh: 0
}
},
onLoad() {
// 获取当前系统的信息
const sysInfo = uni.getSystemInfoSync()
// 为 wh 窗口可用高度动态赋值
this.wh = sysInfo.windowHeight
},
methods: {
}
}
</script>
页面效果如下

1、在 data 中定义分类数据节点
data() {
return {
// 分类数据列表
categories: []
}
}
2、调用获取分类列表数据的方法
onLoad() {
// 调用获取分类列表数据的方法
this.getCategoriesList()
}
3、定义获取分类列表数据的方法
methods: {
// 发起请求
async getCategoriesList() {
const { data: res } = await uni.$http.get('/categories')
this.categories = res.data.categories
}
}
1、循环出所有分类
<scroll-view class="left-scroll-view" scroll-y :style="{height: wh + 'px'}">
<block v-for="(item, index) in categories" :key="index">
<view class="left-scroll-view-item">{{item.name}}view>
block>
scroll-view>
2、在 data 中定义默认选中项的索引
data() {
return {
// 当前选中项的索引,默认让第一项被选中
active: 0
}
}
3、循环渲染结构时,为选中项动态添加 .active 类名
<block v-for="(item, index) in categories" :key="index">
<view :class="['left-scroll-view-item', i === active ? 'active' : '']">{{item.name}}view>
block>
4、为分类的 Item 项绑定点击事件处理函数 changeActive
<block v-for="(item, index) in categories" :key="index">
<view :class="['left-scroll-view-item', index === active ? 'active' : '']" @click="changeActive(index)">{{item.name}}view>
block>
5、定义 changeActive 事件处理函数,动态修改选中项的索引
methods: {
// 选中项改变的事件处理函数
changeActive(index) {
this.active = index
}
}
1、在 data 中定义文章列表的数据节点和当前分类的 id
data() {
return {
// 文章列表
articlesList: [],
// 当前分类的id
currentId: 1,
}
}
2、点击分类的 item 项时,传入当前分类的 id
<block v-for="(item, index) in categories" :key="index">
<view :class="['left-scroll-view-item', index === active ? 'active' : '']"
@click="changeActive(index, item.id)">{{item.name}}view>
block>
3、修改 changeActive 方法,在点击切换分类之后,为分类id数据赋值
methods: {
changeActive(i, id) {
this.active = i
this.currentId = id
}
}
4、定义获取每个分类对应的文章列表数据的方法
methods: {
// 每个栏目对应的所有文章
async initArticle() {
const {
data: res
} = await uni.$http.get(`/categories/${this.currentId}`)
this.articlesList = res.data.articles
},
}
5、在 onLoad 和 changeActive 中分别调用 initArticle 方法
onLoad() {
this.initArticle()
},
methods: {
changeActive(i, id) {
this.active = i
this.currentId = id
this.initArticle()
}
}
6、完善 html 渲染
<scroll-view class="right-scroll-view" scroll-y :style="{height: wh + 'px'}">
<view class="list-item" v-for="(article, index) in articlesList" :key="index">
<navigator class="cate-url" :url="'../article/article?id=' + article.id">
<view class="list-title">{{article.title | ellipsis(30)}}view>
<view class="list-desc">
<view>{{article.views}} 阅读 · {{article.commentCount}} 评论view>
<view>{{article.createdAt | date_format}}view>
view>
navigator>
view>
scroll-view>
7、美化样式
.right-scroll-view {
.list-item {
display: flex;
flex-direction: column;
border-top: 1px solid rgb(238, 238, 238);
background-color: #fff;
width: 100%;
.list-title {
padding: 15px 10px;
font-size: 16px;
font-weight: bold;
color: #222226;
}
.list-desc {
display: flex;
justify-content: space-between;
padding: 0 10px 10px 10px;
font-size: 15px;
color: #999aaa;
}
}
.list-item:first-child {
border-top: none;
}
}
scroll-view ::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
color: transparent;
}