一、介绍
个人空间包含上面的基础信息和下面的发布、关注等。
二、过程
首先获取数据进行渲染,监听路由变化,来判断路由是否有userId,如果有则代表不是自己的空间,则通过api调用后端获取数据。如果没有,则代表是自己的空间,则获取vuex里的userInfo。在data里面创建一个名为userInfo的对象,然后把获取到的数据进行赋值。
watch:{
// 监听路由变化,来判断路由是否有信息,从而分辨是否为自己的空间
$route:{
async handler(){
let {userId} =this.$route.query
this.isowner=!userId||userId==this.$store.state.userInfo.userId
if(!userId){//当前登录的用户
this.userInfo=this.$store.state.userInfo
}else{
const data=await userInfo({userId})
this.userInfo=data.data
}
this.activeName=this.$route.name
this.getInfo()
console.log(this.userInfo);
},
immediate:true
}
},
渲染:
<div class="space">
<h2>欢迎来到我的美食空间</h2>
<div class="user-info">
<div class="user-avatar">
<img :src="userInfo.avatar" alt="">
</div>
<div class="user-main">
<h1>{{userInfo.name}}</h1>
<span class="info">
<em>{{userInfo.createdAt}}</em>
|
<router-link :to="{name:'edit'}" v-if='isowner'>编辑个人资料</router-link>
</span>
<div class="tools" v-if="!isowner">
<!-- follow-at no-follow-at-->
<a href="javascript:;" class="follow-at"
:class="{'no-follow-at':userInfo.isFollowing}"
@click='taggleHandler'
>
{{userInfo.isFollowing ? '已关注':'未关注'}}
</a>
</div>
</div>
<ul class="user-more-info">
<li>
<div>
<span>关注</span>
<strong>{{userInfo.following_len}}</strong>
</div>
</li>
<li>
<div>
<span>粉丝</span>
<strong>{{userInfo.follows_len}}</strong>
</div>
</li>
<li>
<div>
<span>收藏</span>
<strong>{{userInfo.collections_len}}</strong>
</div>
</li>
<li>
<div>
<span>发布菜谱</span>
<strong>{{userInfo.work_menus_len}}</strong>
</div>
</li>
</ul>
</div>
<!-- v-model="activeName" -->
<el-tabs class="user-nav" v-model="activeName" @tab-click="tabClickHandler">
<el-tab-pane label="作品" name="works"></el-tab-pane>
<el-tab-pane label="粉丝" name="fans"></el-tab-pane>
<el-tab-pane label="关注" name="following"></el-tab-pane>
<el-tab-pane label="收藏" name="collection"></el-tab-pane>
</el-tabs>
<div class="user-info-show">
<!-- 作品 & 收藏 布局 -->
<!-- <menu-card :margin-left="13"></menu-card> -->
<!-- 粉丝 & 关注 布局 -->
<!-- <Fans></Fans> -->
<router-view :info='list' :activeName='activeName'></router-view>
</div>
</div>
下面的tab切换需要配置路由,因为作品和收藏的布局基本一样,粉丝和关注的布局基本一样,所以用的是同一个组件:
{
path:'/space',
name:"space",
title:'作者',
component:()=>import ('@/views/user-space/space.vue'),
redirect:'/space/works',
children:[
{
path:'works',
name:'works',
component:()=>import ('@/views/user-space/menu-list')
},{
path:'fans',
name:'fans',
component:()=>import ('@/views/user-space/fans')
},{
path:'following',
name:'following',
component:()=>import ('@/views/user-space/fans')
},{
path:'collection',
name:'collection',
component:()=>import ('@/views/user-space/menu-list')
}
]
}
给tab切换的地方添加一个点击事件tabClickHandler,让他点击的时候进行路由跳转。因为是使用的element渲染的,所以绑定点击事件需要使用@tab-click
tabClickHandler(){
//问题:在切换tab是,会发生key值重复的问题,在每次切换tab是,先清空数据
this.list=[];
// 问题:给后端传递的参数被覆盖(query中的)
this.$router.push({
name:this.activeName,
query:{
...this.$route.query
}
})
},
在监听路由里面调用getInfo方法调用封装的请求,this.activeName是当前点击的哪一个按钮,然后获取数据,赋值给list:
async getInfo(){
let data=await getOtherInfo[this.activeName]({userId:this.userInfo.userId})
if(this.activeName===data.flag){
this.list=data.list
}
}
封装:
const getOtherInfo={
async works(params){//作品
let data=(await getMenus(params)).data
data.flag='works'
return data
},
async fans(params){//粉丝
let data=(await fans(params)).data
data.flag='fans'
return data
},
async following(params){//关注
let data=(await following(params)).data
data.flag='following'
return data
},
async collection(params){//收藏
let data=(await collection(params)).data
data.flag='collection'
return data
}
}
通过父传子的方法向组件中传递数据list,在子组件中通过props获取传递的数据info和activeName:
props:{
info:{
type:Array,
default:()=>[]
},
activeName:{
type:String,
default:'fans'
}
}
首先是作品和收藏,因为用的是同一个组件,所以要判断到底是什么,从而在没有数据的情况下显示的是,发布作品还是菜谱大全。在拥有数据的情况下,隐藏它,显示数据。又因为数据的显示方式和首页的一样所以用的是同一个组件menu-card,需要通过父传子传递参数。
<div class="menu-list">
<div class="info-empty" v-if="activeName==='works'&&!info.length">
<div>
<p>私房菜不要偷偷享用哦~~制作成菜谱与大家分享吧!</p>
<a href="">发布菜单</a>
</div>
</div>
<div class="info-empty" v-if="activeName==='collection'&&!info.length">
<div>
<p>还没有收藏任何的菜谱,去搜自己喜欢的菜谱,收藏起来吧。</p>
<a href="">菜谱大全</a>
</div>
</div>
<menu-card :info='info' :margin-left="13"></menu-card>
menu-card:
<template>
<el-row class="menu-card" type="flex" justify="start">
<el-col
style="flex:none;"
:style="{'margin-left':marginLeft+'px'}"
v-for='item in info' :key='item._id'
>
<el-card :body-style="{ padding: '0px' }">
<router-link :to='{name:"detail",query:{memuId:item._id}}'>
<img :src="item.product_pic_url" class="image" style="width: 232px;height: 232px;">
<div style="padding: 14px;" class="menu-card-detail">
<strong>{{item.title}}</strong>
<span>{{item.comments_len}} 评论</span>
<router-link :to="{name:'space',query:{userId:item.userId}}" tag="em">
{{item.name}}
</router-link>
</div>
</router-link>
</el-card>
</el-col>
</el-row>
</template>
<script>
export default {
name: 'menu-card',
props:{
marginLeft: {
type: Number,
default: 22
},
info:{
type: Array,
default:() => []
}
}
}
</script>
接下来是粉丝和关注,同样需要判断,显示的是什么和有没有数据。它的显示数据没有写在别的组件,所以可以直接在fans里面渲染
<div class="fans">
<div class="info-empty" v-if='!info.length'>
<div>
<p v-if="activeName==='fans'">还没有被关注哦!多发布菜谱,更容易被找到。</p>
<p v-if="activeName==='following'">还没有关注别人哦!可以预览菜谱,找到别人</p>
</div>
</div>
<ul class="fans clearfix" >
<router-link
v-for="item in info"
:key="item.userId"
:to="{name:'space',query:{userId:item.userId}}" tag="li" >
<a href="javascript:;" class="img">
<img :src="item.avatar"></a>
<div class="c">
<strong class="name">
<router-link :to="{name:'space',query:{userId:item.userId}}">{{item.name}}</router-link>
</strong>
<em class="info"><span>粉丝:</span> {{item.follows_len}} | <span>关注:</span>{{item.following_len}}</em>
<em class="info"><span>简介:</span>{{item.sign?item.sign:'这个人太懒了!还没有介绍自己'}}</em>
</div>
</router-link>
</ul>
</div>
总结:
到这里就介绍完了,祝大家生活愉快