美食杰-个人空间

一、介绍

个人空间包含上面的基础信息和下面的发布、关注等。

 二、过程

首先获取数据进行渲染,监听路由变化,来判断路由是否有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>

 总结:

到这里就介绍完了,祝大家生活愉快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值