??总体思路
1.显示别人的空间
? a.地址栏中如有userid?则显示对应的用户数据
?2.显示自身空间
?????a.如果没有userid??则默认显示自己信息
?????b.如果在菜谱中?点击自己?也是有userid传递
????c.通过判断是否为自己的?如果是,不需要后端拿,登录时,个人信息
?3.代码展示
<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="toggleHandler"
>
{{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>
</template>
<script>
import {userInfo, toggleFollowing, getMenus, following, fans, collection} from '@/service/api';
const 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 则默认显示自己信息
// b.如果在菜谱中 点击自己 也是有userid传递
//c.通过判断是否为自己的 如果是,不需要后端拿,登录时,个人信息
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.userId
if(this.isOwner){//判断当前登录的用户
this.userInfo=this.$store.state.userInfo;
}else{
const {data}=await userInfo({userId})
this.userInfo=data;
}
// console.log(this.userInfo)
//可以留存上一次tad的访问信息
this.activeName=this.$route.name;
// console.log(this.activeName)
this.getInfo(); //请求二级路由
},
immediate:true
}
},
methods:{
async toggleHandler(){
const {data}=await toggleFollowing({followUserId:this.userInfo.userId})
console.log(data)
// 因为关注后,要更新的数据里,还有粉丝,所有整体赋值
this.userInfo=data;
},
tabClickHandler(){
this.list =[];
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;
}
}
}
}
</script>
<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>
?注意:watch 中用到了初始化监听
监听分为初始化监听,和深度监听
属性immediate和deep
immediate与handler watch的特点是当被监听变量变化时才是执行函数,而在初始化(只有变化才会执行)的时候并不会执行,使用handler与immediate的作用是
当immediate为false时,与之前的效果相同
deep就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。?
2.点击 作品? 粉丝? 关注? 收藏 进行数据加载和显示
<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" >
<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>
?
|