文章目录
- 说明
- 功能描述:
- 代码
说明
该组件主要是通过一个小抽屉进行用户粉丝与关注列表的展示
前提:这里用了elementPlus的组件库所以需要配置好elementPlus的组件库环境
这里采用的是根据传入的用户名进行查询。也可以修改为根据传入的用户id进行查询
功能描述:
- 抽屉窗:
- 使用
el-drawer
实现一个侧边弹出窗口,用于显示用户的粉丝和关注列表。 - 抽屉标题会根据确定的
follwerFansType
属性动态显示为“粉丝列表”或“关注列表”。 - 用户信息展示:
- 使用
el-card
和el-table
组件,以表格形式展示粉丝或关注列表的用户数据。 - 每个用户信息行包括头像、用户名、简介等,头像和用户名可以点击并截图到用户的个人页面。
- 操作按钮:
- 根据
follwerFansType
显示不同的按钮状态:- 如果是粉丝列表,且双方相互关注,则显示“已互关”按钮。
- 如果是粉丝列表,且当前用户仅被对方关注,则显示“取消关注”按钮。
- 否则,显示“关注”按钮。
- 点击关注或取消关注按钮可直接执行关注或取消关注的操作。
- 分页功能:
- 使用自定义的分页组件
sy-pagination
,当翻页时,通过handlePage
方法触发分页请求并更新列表数据。 - 数据获取与监听:
fetchList
根据follwerFansType
动态获取粉丝或关注列表的方法。- 通过
watch
监听follwerFansType
的变化,若变化则清空列表数据并重新请求。 - 另外加载新的数据时,会根据当前页面码和用户筛选条件查询数据,并更新总记录数。
- 关注与取消关注:
followUser
方法用于新增关注者。unfollowUser
方法通过确认弹窗执行取消关注操作,成功后会更新用户的关注状态。
代码
<template><el-drawer v-model="drawer" title="粉丝与关注列表" :with-header="false" size="26.5%"><el-card class="followersAndfans-list"><template #header><div class="card-header"><span v-if="props.follwerFansType==='fans'">粉丝列表</span><span v-else>关注列表</span></div></template><el-table :data="userList" style="width: 100%"><!-- 粉丝名和简介列 --><el-table-column label="信息" width="300"><template #default="scope"><div class="user-info"><img :src="scope.row.picture" alt="picture" class="picture" @click="navigateToUserProfile(scope.row)" /><div class="user-details"><span class="username" @click="navigateToUserProfile(scope.row)">{{ scope.row.username }}</span><p class="bio">{{ scope.row.description }}</p></div></div></template></el-table-column><!-- 关注按钮列 --><el-table-column label="操作" width="100"><template #default="scope"><el-button v-if="scope.row.follower && follwerFansType==='fans'" type="primary" @click="unfollowUser(scope.row)" size="small" aria-disabled="true">已互关</el-button><el-button v-else-if="scope.row.follower" type="primary" @click="unfollowUser(scope.row)" size="small" aria-disabled="true">取消关注</el-button><el-button v-else type="success" size="small" @click="followUser(scope.row)">关注</el-button></template></el-table-column></el-table></el-card><!-- 分页按钮 --><sy-pagination:page="pageData.page":total="pageData.total":pageSize="pageData.pageSize"@changePage="handlePage"/></el-drawer>
</template><script setup>
import { onMounted, pushScopeId, ref, watch } from 'vue';
import { fetchFollowersList } from '@/api';
import { fetchFansList } from '@/api';
import { follwerAndFans } from '@/api';
import { Unfollow } from '@/api';
const { proxy } = getCurrentInstance();
// 定义并初始化 drawer 变量
const drawer = ref(false);
const userList = ref([]);// 定义props
const props = defineProps({username: {type: String,required: true},follwerFansType: {type: String,required: true,}
});const pageData = ref({username: props.username,page: 1,pageSize: 10,total: 0
});const navigateToUserProfile = (user) => {// 跳转到点击的用户个人页面const userProfileUrl = `/userProfile/${user.id}`;window.open(userProfileUrl, '_blank'); // 在新标签页打开
};// 获取列表数据(即用户数据)
async function fetchList(){await nextTick();// 确保 DOM 更新完成,即确保先将follwerFansType传进来后再执行fetchListpageData.value.username = props.username;if (props.follwerFansType==="fans") {//获取粉丝列表fetchFansList(pageData.value).then(res=>{userList.value.push(...res.data.records);pageData.value.total = res.data.total;})} else {//获取关注列表fetchFollowersList(pageData.value).then(res=>{userList.value.push(...res.data.records);pageData.value.total = res.data.total;})}
};// 监听 follwerFansType 的变化
watch(() => props.follwerFansType, (newVal, oldVal) => {if (newVal !== oldVal) {userList.value = []; // 清空 userListpageData.value.page = 1; // 重置分页信息//校验传入follwerFansType是否变化,变化才重新获取数据,避免重复查询fetchList();}else{return;}
});//分页查询
function handlePage(page) {pageData.value.page++;fetchList();
}; // 新增关注和粉丝
function followUser(user) {follwerAndFans({followerName:user.username,fanName:props.username}).then(res=>{proxy.$modal.msgSuccess(res.msg);})user.follower = true;
}//取消关注
const unfollowUser = (user) => {ElMessageBox.confirm('确定要取消关注吗?', '系统提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {Unfollow({followerName:user.username,fanName:props.username}).then(res=>{proxy.$modal.msgSuccess(res.msg);user.follower = false;})}).catch(() => {});
};// 暴露父组件需要调用的属性何方法
defineExpose({ drawer,fetchList,watch});</script><style scoped>
.picture {width: 50px;height: 50px;border-radius: 50%;margin-right: 10px;
}.user-info {display: flex;align-items: center;
}.user-details {display: flex;flex-direction: column;
}.username {font-weight: bold;
}.bio {color: #999;font-size: 12px;
}
</style>
父组件调用:
引入并声明所需的变量:
import FollowersAndFansList from './FollowersAndFansList.vue';
const FollowersAndFansListRef = ref(null);
const follwerFansType = ref(null);
在需要的地方使用:
<div><FollowersAndFansList :follwerFansType="follwerFansType" :username="user.username" ref="FollowersAndFansListRef" />
</div>
点击后展示的函数
//点击展示关注或者粉丝列表
function followersOrfansHandleClick(type) {if (FollowersAndFansListRef.value) {follwerFansType.value=typeFollowersAndFansListRef.value.drawer = true;FollowersAndFansListRef.value.watch();}
}
为粉丝或者关注添加相应的点击事件,即可
<el-col :span="6"><div class="grid-content ep-bg-purple"><a class="topBtnItem hand-style" @click="followersOrfansHandleClick('followers')"><el-badge :value="count.followed" :max="100" class="item">关注</el-badge></a></div></el-col><el-col :span="6"><div class="grid-content ep-bg-purple"><a class="topBtnItem hand-style" @click="followersOrfansHandleClick('fans')"><el-badge :value="count.fans" :max="100" class="item">粉丝</el-badge></a></div></el-col>