? ? ? ? ? 美食杰项目目前已经进行到白热化阶段,我呢是感觉越写越有劲,越写越有意思了,对于一个开发者而言,最开心的事莫过于写出来一些满意的效果了吧。
? ? ? ? 今日分享接上之前个人信息页,前面已经说过了上半部分,今天分享的就是下半部分的功能(以他人空间为实例,自己空间大致一样),大致东西不是很多,但还是那两句老话没注意细节,上图
? ?
?
?今天的任务就是上面两张图中,我画框框的部分的功能和细节的处理。。。
大致介绍:
1.首先tab切换实现上面tab功能,用二级路由来实现。
2.根据路由的切换来渲染不同的数据到相同的模板中。
tab切换
首先得配置路由,使得进入个人空间时展示默认组件,这里使用到路由重定向,然后配置二级路由,可以在tab切换时变换不同组件:
{
path:'/space',
name:'space',
component:() => import ('@/views/user-space/space'),
redirect:'/space/works',
children:[
{
path:'works',
name:'works',
component: () => import('@/views/user-space/menu-list'),
meta: {
login: true
}
},
{
path: 'fans',
name: 'fans',
meta: {
login: true
},
component: () => import('@/views/user-space/fans')
},
{
path: 'following',
name: 'following',
meta: {
login: true
},
component: () => import('@/views/user-space/fans')
},
{
path: 'collection',
name: 'collection',
meta: {
login: true
},
component: () => import('@/views/user-space/menu-list')
},
]
},
此时展示默认组件是我的作品组件。此时路由信息显示为
?因为需要在页面加载时初始化一些数据,因此需要使用到watch属性来监听路由的变化,第一个观察自己还是他人空间,第二个加载默认二级路由组件
watch:{
$route:{
async handler(){
let {userId} = this.$route.query
//这里用路由参数来判断是自己还是别人
this.isMyself = !userId || userId === this.$store.state.userInfo.userId
//根据主人采取不同的数据获取方式
if(this.isMyself){
this.userInfo = this.$store.state.userInfo
}else{
const data = await userInfo({userId})
this.userInfo = data.data
}
//将路由上面二级路由渲染到页面
this.activeName = this.$route.name
this.getInfo()
},
//将自动开启
immediate:true
}
},
?这里采取element-ui来实现具体的tab切换,利用v-model获取切换的值,再来根据路由切换二级组件,由此,名字和路由的路径相同的好处可见一斑
<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>
这里的点击事件是为了将名字和路由结合,用到了编程式导航,但是并不是简简单单的将名字给到路由就好,因为我们进入别人空间这样操作的时候,会将userId覆盖掉,根据之前的逻辑,这样会导致跳入自己的空间,因此在编程式导航中还需要将query参数一起放入
tabClickHandler(){
this.$router.push({
name:this.activeName,
query:{...this.$route.query}
})
}
接下来就是模块的展示,根据进入的路由的不同,切换到不同的组件之内,请求不同的数据,渲染模板,
这一块定义在实例之外,目的是简化逻辑处理,可以根据不同的需求来请求不同的数据
const getOtherInfo = {
async works(params){
return (await getMenus(params)).data
},
async following(params){
return (await following(params)).data
},
async fans(params){
return (await fans(params)).data
},
async collection(params){
return (await collection(params)).data
}
}
这里就是数据请求模块,根据tab的切换值来请求上面不同的数据,从而渲染不同模块,这里的调用实在watch中执行?
async getInfo(){
let data = await getOtherInfo[this.activeName]({userId:this.userInfo.userId})
this.data = data.list
console.log(data);
},
说明:作品和收藏结构相同,粉丝和关注结构相同,因此可以复用统一模板。
因为所有板块都是使用router-view来渲染,因此可以通过router-view将数据传递给不同模块,来达到渲染的目的。
<div class="user-info-show">
<!-- 作品 & 收藏 布局 -->
<!-- <menu-card :margin-left="13"></menu-card> -->
<!-- 粉丝 & 关注 布局 -->
<!-- <Fans></Fans> -->
<router-view :info='data' :activeName='activeName'></router-view>
</div>
在粉丝模块中接收参数,info是数据,activeName是名称
export default {
props:{
info:{
type:Array,
default:[]
},
activeName:{
type:String,
default:''
}
}
}
在粉丝模块中渲染数据
<ul class="fans clearfix">
<router-link :to="{name:'space',query:{userId:item.userId}}" tag="li" v-for="item in info" :key="item.userId">
<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 class="info-empty" v-if="!info.length">
<div>
<p v-if='activeName == "fans"'>还没有被关注哦!多发布菜谱,更容易被找到。</p>
<p v-if="activeName == 'following'">还没有关注别人哦!可以预览菜谱,找到别人</p>
</div>
</div>
同理,在作品模块中接收数据
props: {
info:{
type:Array,
default:[]
},
activeName:{
type:String,
default:''
}
}
根据数据来显示和隐藏提示信息
<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>
在作品列表模板中接受数据,并根据数据和样式渲染数据即可
<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'}">
<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>
今天的分享就到此结束了,具体功能不是很难,逻辑思维也不是很绕,需要注意的是有些需要取反的细节请多多留意。。。
祝生活安好
|