前言:
项目简介:项目是关于知识学习的培训平台,有课程和资料模块,课程和资料的详情页均展示对应的课程或资料目录,目录支持多层级(无限层级),展示方式与B站上的视频目录同理,只不过我们需要无限级。如果一个层级目录下有好几个子级,点击这个层级目录可以展开或折叠。点击对应的子级目录时,当前被点击的那条要变色,代表此时正在看。
一、项目中想要的效果
下图展示项目中需要实现的效果:

右侧的按钮支持展开与折叠:

二、实现思路
我们可以将此功能作为组件抽离出来,因为目录是无限层级的,每一个子级都会比父级缩进一定间距。每一层级样式也都差不多,只是背景色和字体需要调整一下。
三、接口返回的数据结构
附上接口返回的数据结构,帮助理解:

三、实现方案
备注:此处将以微信小程序项目作为示例进行演示说明。
- 首先将目录部分作为组件使用,组件命名为
chapterList
,然后在详情页引入:

wxml
<!-- 资料目录 -->
<view class="courseList">
<view class="subtitle">资料列表</view>
<block wx:for="{{detailsList}}" wx:key="index">
<chapterList listData="{{item}}" step="1" playCourseChapterId="{{courseInfo.playCourseChapterId}}" classification="{{courseInfo.classification}}" bindgetFileId="getNewFileId"></chapterList>
</block>
</view>

js
// 查看资料详情
getCourseInfo:function(){
var that = this
https.get(api.getCourseInfo, obj).then((res) => {
const returndata = res.data
let detailsList = this.formatList(returndata.details, returndata.playCourseChapterId)
that.setData({
playCourseChapterId: returndata.playCourseChapterId, // 初始赋值
courseInfo: returndata,
detailsList,
});
})
},
其中,formatList
方法是用来判断选中的是哪条数据,根据唯一值playCourseChapterId
来判断。然后手动给此对象加一个属性selected
,后面会用来做样式的判断,代码如下:

js
formatList(list = [], playCourseChapterId) {
circle(list)
function circle(_list) {
_list.forEach(item => {
if (item.children && item.children.length) {
circle(item.children)
} else {
item.selected = false
if (item.chapterId === playCourseChapterId) {
item.selected = true
}
}
})
}
return list
},
- 在
chapterList
组件中也要引用chapterList
组件:

- 在
chapterList
组件中获取上面的select
的值,添加不同的样式,如果select=true
,根据需求展示被选中的样式,比如我们的需求是,字体颜色变蓝。 - 需要注意的是,所有需要父子组件传的事件,也要在
chapterList
组件中再接收一遍。
最后,希望对大家有帮助!