需求背景
点击相应的tab,页面自动滑到指定位置
效果
html
<view class="diary-list-container">
<!-- tabs栏 -->
<DiaryListTabsComponent :tab-list="tabList" @selectTab="selectTab" />
<!-- 日记列表 -->
<view class="diary-main">
<view class="content-column">
<DiaryItemComponent
class="content-item"
ref="DiaryItemComponent"
v-for="item in diaryList.filter((_, index) => index % 2 === 0)"
:key="item.id"
:id="item.type"
:diaryInfo="item"
/>
</view>
<view class="content-column">
<DiaryItemComponent
class="content-item"
ref="DiaryItemComponent"
v-for="item in diaryList.filter((_, index) => index % 2 === 1)"
:key="item.id"
:id="item.type"
:diaryInfo="item"
/>
</view>
</view>
<!-- 发布日记+号 -->
<DragToSnapContainer
:initX="-10"
:initY="-80"
moveViewClass="move-view"
:contentWidth="136"
:contentHeight="136"
>
<view class="write-diary">
<image
class="add-diary-icon"
src="https://ihairpic.yongxianghui.net/front_resource/patientImg/add-diary-icon.png"
/>
</view>
</DragToSnapContainer>
</view>
css
.diary-list-container {
min-height: 100vh;
background: #f7faff;
padding-top: 96px;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.diary-main {
padding: 24px;
//columns: 2;
//column-gap: 14px;
display: flex;
justify-content: space-between;
.content-column {
display: flex;
flex-direction: column;
align-items: center;
}
}
.write-diary {
position: absolute;
width: 136px;
height: 136px;
right: 18px;
bottom: 162px;
.add-diary-icon {
width: 136px;
height: 136px;
}
}
}
js
definePageConfig({
navigationBarTitleText: "发友日记",
});
@Component({
components: { DiaryItemComponent, DragToSnapContainer, DiaryListTabsComponent },
})
export default class DiaryListPage extends BasePage {
name: "DiaryListPage";
/** tabs数据 */
tabList = [
{ id: 1, label: "日记标签1", type: 1 },
{ id: 2, label: "日记标签2", type: 2 },
{ id: 3, label: "日记标签3", type: 3 },
{ id: 4, label: "日记标签4", type: 4 },
{ id: 5, label: "日记标签5", type: 5 },
];
/** 日记列表 */
diaryList = [
{
id: 1,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)",
count: 1100,
type: 1,
},
{
id: 2,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(发际线整形(种植头发改 善M型额头)发际线整形(发际线整形(种植头发改 善M型额头)",
count: 1200,
type: 1,
},
{
id: 3,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test2.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)发际线整形(发际线整形(种植头发改 善M型额头)",
count: 1300,
type: 2,
},
{
id: 4,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)",
count: 1400,
type: 2,
},
{
id: 5,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(发际线整形(种植头发改 善M型额头)发际线整形(发际线整形(种植头发改 善M型额头)",
count: 1500,
type: 3,
},
{
id: 6,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test2.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)",
count: 1600,
type: 3,
},
{
id: 7,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(发际线整形(种植头发改 善M型额头)发际线整形(发际线整形(种植头发改 善M型额头)",
count: 1700,
type: 4,
},
{
id: 8,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)",
count: 1800,
type: 4,
},
{
id: 9,
img: "https://ihairpic.yongxianghui.net/front_resource/patientImg/diary-test-img.png",
name: "谢朴肉",
title: "发际线整形(种植头发改 善M型额头)",
count: 1900,
type: 5,
},
];
async init(option: Record<string, string>): Promise<void> {
super.init(option);
this.getPosition();
}
/** 当前选中tab */
activeTab: number = 1;
/** 切换tab */
selectTab(item) {
this.activeTab = item.id;
let top = this.domInfoList.find((i) => i.type == item.type).top;
Taro.pageScrollTo({
scrollTop: top - 48 - 12,
duration: 300,
});
}
domInfoList: any[] = [];
/** 获取dom信息 */
getPosition() {
Taro.nextTick(() => {
const query = Taro.createSelectorQuery();
query
.selectAll(".content-item")
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec((res) => {
this.domInfoList = res[0].map((_) => {
return {
top: _.top,
type: _.id,
};
});
});
});
}
}