当前位置: 首页 > article >正文

Vue3用户关注与粉丝列表展示

文章目录

    • 说明
    • 功能描述:
    • 代码

说明

该组件主要是通过一个小抽屉进行用户粉丝与关注列表的展示

前提:这里用了elementPlus的组件库所以需要配置好elementPlus的组件库环境

这里采用的是根据传入的用户名进行查询。也可以修改为根据传入的用户id进行查询

功能描述:

  • 抽屉窗
  • 使用el-drawer实现一个侧边弹出窗口,用于显示用户的粉丝和关注列表。
  • 抽屉标题会根据确定的follwerFansType属性动态显示为“粉丝列表”或“关注列表”。
  • 用户信息展示
  • 使用el-cardel-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>

http://www.kler.cn/news/367276.html

相关文章:

  • 量子机器学习:颠覆性的前沿技术
  • 什么是命名实体识别?
  • Maven项目管理工具-初始+环境配置
  • 表达式求值(2020cspj)
  • Android调用系统相机录像并设置参数
  • 论文笔记:LaDe: The First Comprehensive Last-mile Delivery Dataset from Industry
  • 前端页面手机端触摸屏操作
  • 【C/C++ explicit关键字】为什么有了explicit关键字的构造函数 就不能再有 其无参构造函数
  • 神经架构搜索:自动化设计神经网络的方法
  • Mysql5.7变为GreatSQL 8.0.32-25过程中,SQL语句报错及解决方案
  • 原生页面引入Webpack打包JS
  • uniApp 加载google地图 并规划路线
  • 仕考网:25年初级会计师备考建议
  • 十分钟了解Android Handler、Looper、Message
  • Java虚拟机:JVM介绍
  • 微服务与多租户详解:架构设计与实现
  • Spring微服务学习笔记之Spring Cloud Alibaba远程服务调用实战
  • 基于SSM的儿童教育网站【附源码】
  • 【华为HCIP实战课程二十三】中间到中间系统协议IS-IS原理与配置详解,网络工程师
  • 霜降时节,网络防护也需“御寒”
  • 【LeetCode:43. 字符串相乘 + 模拟】
  • 408算法题leetcode--第38天
  • Promise、async、await 、异步生成器的错误处理方案
  • 挂耳式耳机品牌排行榜前十名有哪些?平价开放式耳机品牌推荐!
  • 【CSS3】css开篇基础(5)
  • 今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 10月27日,星期日