路由配置:
{
path:'/space',
name:'space',
component:()=>import('@/views/user-space/space.vue'),
redirect:{
name:'works'
},
children:[
{
path:'works',
name:'works',
component:()=>import('@/views/user-space/menu-list.vue'),
meta:{
login:true
}
},
{
path:'fans',
name:'fans',
component:()=>import('@/views/user-space/fans.vue'),
meta:{
login:true
}
},
{
path:'following',
name:'following',
component:()=>import('@/views/user-space/fans.vue'),
meta:{
login:true
}
},
{
path:'collection',
name:'collection',
component:()=>import('@/views/user-space/menu-list.vue'),
meta:{
login:true
}
}
]
},
布局:HTML
<template>
<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="toggleHander"
>
{{userInfo.isFllowing ? '已关注':'未关注'}}
</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>
</template>
样式:css
<style lang="stylus">
.space
h2
text-align center
margin 20px 0
.user-info
height 210px
background-color #fff
display flex
.user-avatar
width 210px
height 210px
img
width 100%
height 100%
.user-main
width 570px
padding 20px
position relative
h1
font-size 24px
color #333
line-height 44px
.info
font-size 12px
line-height 22px
color #999
a
color #999
.tools
position absolute
right 20px
top 20px
vertical-align top;
a
display inline-block
padding 3px 0
width 50px
color #fff
text-align center
a.follow-at
background-color #ff3232
a.no-follow-at
background-color #999
.user-more-info
width 190px
overflow hidden
padding-top 20px
li
width 81px
height 81px
border-radius 32px
border-bottom-right-radius 0
margin 0px 8px 8px 0px
float left
div
display block
height 81px
width 81px
box-shadow 0px 0px 6px rgba(0,0,0,0.05) inset
border-radius 32px
border-bottom-right-radius 0
span
color #999
line-height 20px
display block
padding-left 14px
padding-top 14px
strong
display block
font-size 18px
color #ff3232
font-family Microsoft Yahei
padding-left 14px
line-height 32px
.user-nav
margin 20px 0 20px 0
.user-info-show
min-height 300px
background #fff
padding-top 20px
.info-empty
width 100%
min-height inherit
display flex
align-items center
justify-content:center;
p
text-align center
font-size 12px
a
text-align center
display block
height 48px
width 200px
line-height 48px
font-size 14px
background #ff3232
color #fff
font-weight bold
margin 0px auto
.el-tabs__item.is-active
color: #ff3232;
.el-tabs__active-bar
background-color: #ff3232;
.el-tabs__nav-wrap::after
background-color: transparent;
</style>
Js:
import {userInfo, toggleFollowing, getMenus, following, fans, collection} from '@/service/api';
let getOtherInfo = {
async works(params){//作品
let data = (await getMenus(params)).data;
data.flag = 'works';
return data;
},
async following(params){//关注
let data = (await following(params)).data;
data.flag = 'following';
return data;
},
async fans(params){//粉丝
let data = (await fans(params)).data;
data.flag = 'fans';
return data;
},
async collection(params){//收藏
let data = (await collection(params)).data;
data.flag = 'collection';
return data;
}
}
//总体思路:
// 1.显示别人的空间
// a.地址栏中如有userID,则显示对应用户的数据
// 2.显示自身的空间
// a.如果没有userID,则默认显示自己的信息(vuex)
// b.如果在菜谱中,点击自己,也是有userId传递的
// c.通过判断是否为自己,如果是,不需要从后端拿,登录时,个人信息已经存在了vuex中
export default {
name: 'Space',
data(){
return {
userInfo:{},
isOwner:false,
activeName:'works',
list:[]
}
},
watch:{
//监听路由变化,来判断路由是否有信息,从而分辨是否为自己的空间
$route:{
async handler(){
let {userId} = this.$route.query;
this.isOwner = !userId || userId == this.$store.state.userInfo.userId;
console.log(this.$route.query);
if(this.isOwner){ // 当前登录的用户
this.userInfo = this.$store.state.userInfo;
}else{
const {data} = await userInfo({userId});
this.userInfo = data;
}
console.log(this.userInfo);
//留存上一次tab的访问信息(根据需求而定)
this.activeName = this.$route.name;
this.getInfo();//请求二级路由的数据
},
immediate:true
}
},
methods:{
async toggleHandler(){
let {data} = await toggleFollowing({followUserId:this.userInfo.userId});
// console.log(data);
//因为关注后,要更新的数据里,还有粉丝,所以整体赋值
this.userInfo = data;
},
tabClickHandler(){
console.log(this.activeName);
//在切换tab时,会发生key值重复的问题,在每次切换tab之前,先去清空数据
this.list = [];
//问题:给后端传递的参数被覆盖(query中的)
this.$router.push({
name:this.activeName,
query:{
...this.$route.query
}
})
},
//调用封装的请求
async getInfo(){
let data = await getOtherInfo[this.activeName]({userId:this.userInfo.userId})
//给组件赋值
console.log(data);
if(this.activeName == data.flag){
this.list = data.list
}
}
}
}
fans组件:
<template>
<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" v-if="item.sign"><span>简介:{{item.sign}}</span>这个人太懒啦!还没有介绍自己</em>
</div>
</router-link>
</ul>
</div>
</template>
<script>
export default {
props:{
info:{
type:Array,
default:()=>[]
},
activeName:{
type:String,
default:'fans'
}
}
}
</script>
<style lang="stylus">
.fans
font-size 12px
.fans li
height 80px
width 950px
border-bottom 1px solid #eee
padding 20px 20px
position relative
.fans lihover
background #fafafa
.fans li a.img
float left
height 80px
width 80px
position relative
.fans li a.img img
height 80px
width 80px
display block
.fans li div.c
float left
height 80px
width 850px
padding-left 14px
.fans li div.c strong.name
display block
height 32px
line-height 32px
font-size 14px
color #333
font-weight bold
.fans li div.c strong.name a
color #333
.fans li div.c strong.name a span
color #ff3232
.fans li div.c strong.name ahover
color #ff3232
text-decoration underline
.fans li div.c p
font-size 14px
color #666
line-height 24px
height 48px
overflow hidden
.fans li div.c p a
color #666
.fans li div.c p ahover
color #ff3232
text-decoration underline
.fans li div.c p strong
font-size 12px
padding-right 10px
.fans li div.c p strong em
color #ff3232
padding-right 4px
.fans li div.c span.time
position absolute
height 20px
line-height 20px
right 20px
top 20px
color #999
.fans li div.c span.time a
color #999
padding-left 10px
display none
.fans li div.c span.time ahover
color #ff3232
.fans li div.c em.info
height 24px
line-height 24px
display block
color #999
.fans li div.c em.info span
color #666
</style>
menu-list组件:
<template>
<div class="menu-list">
<div class="info-empty" v-if="!info.length">
<div v-if="activeName === 'works'">
<p>私房菜不要偷偷享用哦~~制作成菜谱与大家分享吧!</p>
<a href="">发布菜单</a>
</div>
</div>
<div class="info-empty" v-if="!info.length">
<div v-if="activeName === 'collection'">
<p>还没有收藏任何的菜谱,去搜自己喜欢的菜谱,收藏起来吧。</p>
<a href="">菜谱大全</a>
</div>
</div>
<menu-card :margin-left="13" :info='info'></menu-card>
</div>
</template>
<script>
import MenuCard from '@/components/menu-card.vue'
export default {
components: {MenuCard},
props: {
info:{
type:Array,
default:()=>[]
},
activeName:{
type:String,
default:'works'
}
}
}
</script>
menu-card组件:
<template>
<el-row class="menu-card" type="flex" justify="start">
<el-col
style="flex:none;"
:style="{'margin-left':marginLeft+'px'}"
v-for='items in info' :key='items._id'
>
<el-card :body-style="{ padding: '0px' }">
<!-- -->
<router-link :to="{name:'detail',query:{menuId:items._id}}">
<img :src="items.product_pic_url" class="image" style="width: 232px;height: 232px;">
<div style="padding: 14px;" class="menu-card-detail">
<strong>{{items.title}}</strong>
<span>{{items.comments_len}} 评论</span>
<!-- -->
<router-link :to="{name:'space',query:{userId:items.userId}}" tag="em">
{{items.name}}
</router-link>
</div>
</router-link>
</el-card>
</el-col>
</el-row>
</template>
<script>
export default {
name: 'menu-card',
data(){
return{
}
},
props:{
marginLeft: {
type: Number,
default: 22
},
info:{
type: Array,
default:() => []
}
},
}
</script>
<style lang="stylus">
.menu-card
flex-wrap wrap
.el-col-24
width auto
margin-bottom 20px
margin-left: 22px
.menu-card-detail
> *
display block
strong
height 24px
line-height 24px
font-size 14px
font-weight bold
color #333
span
height 26px
line-height 26px
font-size 12px
color #999
em
height 23px
line-height 23px
font-size 12px
color #ff3232
</style>