首页 > 其他分享 >Vue3用户关注与粉丝列表展示

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

时间:2024-10-27 11:19:16浏览次数:9  
标签:username 粉丝 value 列表 关注 Vue3 follwerFansType

文章目录

说明

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

前提:这里用了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>

标签:username,粉丝,value,列表,关注,Vue3,follwerFansType
From: https://blog.csdn.net/m0_74963840/article/details/143266013

相关文章

  • 学术小论文,粉丝千问千答,研究生错过后悔一辈子(上)
    做实验数据可以“优化”多少,由于实验室机器不灵敏得自己把数据整好看点,但是老师让发一二区,感觉别人复现不出来我的数据,造假会不会被发现啊人又多大胆,就有多大产,A+B+c+d+e,结果就是符合一种趋势,符合逻辑去年的顶刊是80,那就80.5%,一定要做优化,所有数值一定要符合趋势,符合逻辑三四......
  • 前端 (vue3+ts+vite)
    项目结构 cool-admin  ├──buildvite插件  ├──vite.config.tsvite配置文件  ├──tsconfig.jsontypescript配置文件  ├──src源文件  │ ├──main.ts程序入口  │ ├──App.vue页面挂载入口  │ ......
  • JavaScript CSS Vue3 实现一个简单的Loading
    之前项目用到的,后来换其他效果了。放博客里保存一下。效果视频转GIF之后不太流畅……代码<scriptsetuplang="ts">import{onBeforeUnmount,onMounted,ref}from"vue";import{clamp}from"../scripts/Utils";constmaskDiv=ref<HTMLDivElement>(null)co......
  • vue3使用ts和使用js
    1、使用ts<template> <divstyle="display:flex;margin:20px;"> <divstyle="width:20%;border:1pxsolidrgb(221221221);height:80vh;">1</div> <divstyle="width:60%;display:flex;justify-content:cen......
  • vue3监听和不能使用this问题,uniapp封装请求
    http.js//格式化日期函数exportfunctionrequest(method,url,data){consturls="http://183.6.96.231:29101"; constusername=uni.getStorageSync('username'); consttoken=uni.getStorageSync('token'); uni.showLoading({......
  • Vue3取当前时间和一个小时后的时间。
    constformatDate=(date)=>{//初始化时间   //格式化日期为YYYY-MM-DDHH:mm:ss   constyear=date.getFullYear();   constmonth=String(date.getMonth()+1).padStart(2,'0');//月份从0开始   constday=String(date.getDate())......
  • Vue3中取当前日期并且取当前日期的前10天和后30天。并把每个日期的日放到一个数组里面
    consttoday=newDate();//获取当前日期constdateArray=[];constdayArray=[];//计算前10天for(leti=10;i>0;i--){constpastDate=newDate(today);pastDate.setDate(today.getDate()-i);dateArray.push(......
  • vue3+java+springboot在线考试系统(08169)
    目录功能介绍具体实现截图技术介绍开发核心技术介绍:技术创新点vue3和vue2的区别:核心代码部分展示非功能需求分析系统开发流程软件测试源码获取功能介绍随着社会的发展,系统的管理形势越来越严峻。越来越多的用户利用互联网获得信息,但各种信息鱼龙混杂,信息真假难以辨......
  • 如何把一个python列表(有很多个元素)变成一个excel表格的第一列?
    大家好,我是Python进阶者。一、前言前几天在Python最强王者群有个叫【麦当】的粉丝问了一个关于Python如何把一个python列表(有很多个元素)变成一个excel表格的第一列的问题,这里拿出来给大家分享下,一起学习。二、解决过程这里给出【dcpeng】和【德善堂小儿推拿-瑜亮老师】大佬......
  • 【移动应用开发】界面设计(二)实现水果列表页面
    续上一篇博客【移动应用开发】界面设计(一)实现登录页面-CSDN博客目录一、采用ViewBinding实现一个RecyclerView1.1在app/build.gradle中添加recyclerview依赖,并打开viewBinding(1)在app/build.gradle中添加依赖(2)在app/build.gradle中打开viewBinding功能(3)点击同步Sync,同......