文章目录
说明
该组件主要是通过一个小抽屉进行用户粉丝与关注列表的展示
前提:这里用了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传进来后再执行fetchList
pageData.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 = []; // 清空 userList
pageData.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=type
FollowersAndFansListRef.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>
标签:username,粉丝,value,列表,关注,Vue3,follwerFansType
From: https://blog.csdn.net/m0_74963840/article/details/143266013