fjrcloud-community-app/pages/community/dynamics.vue

291 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 社区动态页面 -->
<template>
<s-layout title="社区动态" :bgStyle="{ backgroundColor:'#F8EDE8' }" color="#333333">
<view class="community-dynamics-page">
<!-- Tab 切换栏 -->
<view class="tab-bar">
<view
class="tab-item"
v-for="(tab, index) in tabList"
:key="index"
:class="{ active: currentTab === index }"
@tap="switchTab(index)"
>
<text class="tab-text">{{ tab }}</text>
<view class="tab-indicator" v-if="currentTab === index"></view>
</view>
</view>
<!-- 动态列表 - 独立滚动区域 -->
<scroll-view class="dynamics-list" scroll-y :style="{ height: scrollViewHeight + 'px' }">
<view class="list-inner">
<view
class="dynamics-item"
v-for="(item, index) in dynamicsList"
:key="index"
@tap="goDetail(item)"
>
<!-- 封面图 -->
<image class="item-cover" :src="item.cover" mode="aspectFill" />
<!-- 内容区 -->
<view class="item-content">
<text class="item-title">{{ item.title }}</text>
<view class="item-footer">
<text class="item-views">{{ item.views }}</text>
<text class="item-date">{{ item.date }}</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="dynamicsList.length === 0">
<text class="empty-text"></text>
</view>
</view>
</scroll-view>
</view>
</s-layout>
</template>
<script setup>
import { ref, onMounted, nextTick, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
// 列表滚动区域高度单位px通过JS计算后绑定到scroll-view
const scrollViewHeight = ref(0);
// Tab 列表
const tabList = ref(['全部', '物业', '业委会', '社区']);
const currentTab = ref(0);
// 动态列表
const dynamicsList = ref([
{
id: 1,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 2,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 3,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 4,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 5,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 6,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
},
{
id: 7,
title: '社区动态标题xxxx操作手册--如何邀请访客',
cover: '/static/img/guest.png',
views: '1.2万播放',
date: '2021/02/21'
}
]);
// 页面加载
onLoad((options) => {
if (options.tab) {
currentTab.value = parseInt(options.tab);
}
loadDynamicsList();
});
// 页面渲染完成后计算scroll-view的精确高度
onMounted(() => {
const instance = getCurrentInstance();
nextTick(() => {
const sysInfo = uni.getSystemInfoSync();
// 获取tab栏的实际渲染高度
uni.createSelectorQuery()
.in(instance)
.select('.tab-bar')
.boundingClientRect((rect) => {
if (rect) {
// scroll-view高度 = 屏幕可用高度 - tab栏高度 - tab栏距离顶部的高度
scrollViewHeight.value = sysInfo.windowHeight - rect.height - rect.top;
}
})
.exec();
});
});
// 切换 Tab
function switchTab(index) {
currentTab.value = index;
loadDynamicsList();
}
// 加载动态列表
async function loadDynamicsList() {
// TODO: 调用API获取动态列表
}
// 跳转详情
function goDetail(item) {
uni.navigateTo({
url: `/pages/community/dynamics-detail?id=${item.id}`
});
}
</script>
<style lang="scss" scoped>
/* 页面容器 - 伪元素渐变向上覆盖到导航栏 */
.community-dynamics-page {
position: relative;
&::before {
// content: '';
// position: absolute;
// left: 0;
// right: 0;
// height: calc(100% + 176rpx);
background: linear-gradient(180deg, #F8EDE8 0%, #FFFFFF 30%);
// z-index: -1;
}
}
/* Tab 切换栏 */
.tab-bar {
display: flex;
align-items: center;
justify-content: space-around;
padding: 36rpx 50rpx;
// background-color: #FFFFFF;
.tab-item {
position: relative;
padding: 8rpx 16rpx;
.tab-text {
font-size: 30rpx;
color: #999999;
transition: all 0.3s;
}
&.active .tab-text {
font-size: 32rpx;
font-weight: 600;
color: #333333;
}
.tab-indicator {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 6rpx;
background: linear-gradient(90deg, #FF7F69 0%, #FC5A5D 100%);
border-radius: 3rpx;
}
}
}
/* 动态列表 - scroll-view高度由JS动态绑定 */
.dynamics-list {
/* 高度由 :style="{ height: scrollViewHeight + 'px' }" 控制 */
}
/* 列表内容包裹层 - 负责padding间距 */
.list-inner {
padding: 24rpx 32rpx;
}
/* 动态项 */
.dynamics-item {
display: flex;
background-color: #FFFFFF;
border-radius: 31rpx;
padding: 24rpx;
margin-bottom: 19rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
.item-cover {
width: 305rpx;
height: 168rpx;
border-radius: 19rpx;
flex-shrink: 0;
}
.item-content {
flex: 1;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.item-title {
font-size: 30rpx;
font-weight: 500;
color: #333333;
line-height: 1.5;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.item-footer {
display: flex;
align-items: center;
justify-content: space-between;
.item-views {
font-size: 24rpx;
color: #999999;
}
.item-date {
font-size: 24rpx;
color: #999999;
}
}
}
}
/* 空状态 */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
padding: 200rpx 0;
.empty-text {
font-size: 28rpx;
color: #999999;
}
}
</style>