美食杰项目---菜品主页展示

美食杰项目—菜品主页展示

效果展示:
  1. 从内容精选点击进入菜品首页
  2. 把菜品页所需要要的数据进行渲染到页面上
  3. 当点击收藏时切换到已收藏,实现来回切换效果
  4. 输入评论点击提交时,让评论的数据显示在下方页面中
效果图展示:
  • 点击进入菜品首页
    在这里插入图片描述
  • 数据渲染,及收藏,已收藏切换
    在这里插入图片描述
  • 数据渲染
    在这里插入图片描述
  • 评论提交显示
    在这里插入图片描述
具体实现请看如下代码及理解:

1.detail.vue

  • 把头部,内容及评论分三个组件
  • 在此组件中请求数据以及保存数据
  • menuInfo接收数据 ,userInfo设置一个默认值
<template>
  <div class="menu-detail">
    <detail-header :info="menuInfo"></detail-header>
    <detail-content :info="menuInfo"></detail-content>
    <Comment :info="menuInfo"></Comment>
  </div>
</template>
<script>
import DetailHeader from './detail-header'
import DetailContent from './detail-content'
import Comment from './comment'
import {menuInfo} from '@/service/api';
export default {
  components: {DetailHeader, DetailContent, Comment},
  data(){
    return {
      menuInfo:{
      userInfo:{}, 
      raw_material:{
       main_material:[],
       accessories_material:[]
      },
      steps:[]
    } //接收菜谱的详细信息
    }
  },
  watch:{
  $route:{
   handler(){
      let {menuId} = this.$route.query;
      if(menuId){//发送请求
      menuInfo({menuId}).then(({data}) =>{
       console.log(data)
      //  返回值有两种 true:   未收藏转已收藏
                  // false:   
       this.menuInfo = data.info;
     })
      }else{
        this.$message({
          message:"重进",
          type:"warrning"
        })
      }
   },
   immediate:true
  }
  }
}
</script>

2. 头部的一个数据的渲染

  • 通过 props 把数据传递过来,进行页面渲染
  • 收藏和已收藏也在此完成
  • v-if="!isOnwer"判断在自己页面不显示收藏,只在他人主页显示
  • info.isCollection ? ‘已收藏’ : ‘收藏’ 通过isCollection 的true和false判断显示隐藏
    收藏显示红色,已收藏显示灰色
  • 通过async 和await同步的方法放它在登录完成之后才可以收藏
<template>
  <section class="detail-header">
    <img class="detail-img" :src="info.product_pic_url" />
    <div class="detail-header-right">

      <div class="detail-title clearfix">
          <h1 class="title">{{info.title}}</h1>
          <!--
            1. 不显示,这个菜谱是当前用户发布的
            2. 显示,后端返回一个是否收藏的字段
          -->
          <div class="detail-collection" v-if="!isOnwer">
            <!-- collection-at  no-collection-at-->
            
            <a 
              href="javascript:;" 
              class="collection-at"
              :class="{ 'no-collection-at' :info.isCollection}"
              @click="toggleCollection"
            > 
             {{
               info.isCollection ? '已收藏' : '收藏'
             }}
            </a>
          </div>
      </div>
      
      <ul class="detail-property clearfix">
        <li v-for="item in info.properties_show" :key="item.type">
          <strong>{{item.parent_name}}</strong>
          <span>{{item.name}}</span>
        </li>
      </ul>

      <div class="user">
        <router-link 
        id="tongji_author_img" 
        class="img" 
        :to="{name:'space',query:{userId:info.userInfo.userId}}"
        >
          <img :src="info.userInfo.avatar">
        </router-link>
        <div class="info">
          <h4>
            <router-link id="tongji_author"  :to="{name:'space',query:{userId:info.userInfo.userId}}">
           {{info.userInfo.name}}
            </router-link>
          </h4>
          <span>菜谱:{{info.userInfo.work_menus_len}}/ 关注:{{info.userInfo.following_len}} / 粉丝:{{info.userInfo.follows_len}}</span>
          <strong>{{info.userInfo.createdAt}}</strong>
        </div>
      </div>
    </div>
  </section>
</template>
<script>
import {toggleCollection} from '@/service/api'
export default {
  props:{
    info: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    isOnwer(){
      return this.info.userInfo.userId === this.$store.state.userInfo.userId
    }
  },
  methods:{
       async toggleCollection(){
         //先判断是否登录
         if(!this.$store.getters.isLogin){
            this.$message({
              showClose:true,
              message:'请先登录,再收藏',
              type:'warning'
            })
         }
         const data=await toggleCollection({menuId:this.info.menuId});
        //  console.log(data)
         this.info.isCollection=data.data.isCollection;
       }
  }
}
</script>

3. 渲染内容数据

  • 通过props把数据传递过来,查找每一个节点进行渲染
**<template>
  <section class="detail-content">
    <div class="detail-materials">
      <p class=""><strong></strong>{{info.product_story}}<strong></strong></p>
      <h2>用料</h2>
      <div class="detail-materials-box clearfix" v-if="info.raw_material.main_material.length">

        <h3>主料</h3>
        <ul>
          <li class="" v-for="item in info.raw_material.main_material" :key="item._id"> 
            {{item.name}}
            <span>{{item.space}}</span>
          </li>
        </ul>
      </div>
      <div class="detail-materials-box clearfix" v-if="info.raw_material.accessories_material.length">
        <h3>辅料</h3>
        <ul>
          <li class="" v-for="item in info.raw_material.accessories_material" :key="item._id">
            {{item.name}}
            <span>{{item.space}}</span>
          </li>
        </ul>
      </div>
    </div>
    <div class="detail-explain">
      <h2>{{info.title}}的做法</h2>
      <section class="detail-section clearfix" v-for="(item,index) in info.steps" :key="item._id">
        <em class="detail-number">{{index+1}}.</em>
        <div class="detail-explain-desc">
          <p>{{item.describe}}</p>
          <img class="conimg" :src="item.img_url"  v-if="item.img_url" alt="">
        </div>
      </section>
      <div class="skill">
        <h2>烹饪技巧</h2>
        <p>{{info.skill}}</p>
      </div>
    </div>
  </section>
</template>
<script>
export default {
  name: 'DetailContent',
  props:{
   info: {
      type: Object,
      default: () => ({})
    }
  }
}
</script>

4.评论

  • 通过props传递数据
  • comments接收数据,commentText设置内容为空
  • 把评论的图片以及数据渲染出来
  • v-model="commentText"通过v-model双向数据绑定内容
  • @click=“send” 点击事件send发送
  • 使用unshift向前添加
<template>
  <div class="comment-box">
    <h2>{{info.title}}的讨论</h2>
    <div class="comment-text">
      <a href="javascript:;" class="useravatar">
        <img :src="userInfo.avatar">
      </a>
      <div  v-if="!isLogin"><router-link to="">登录</router-link></div>
      
      <div class="comment-right">
        <el-input
          type="textarea"
          :rows="5"
          :cols="50"
          placeholder="请输入内容"
          v-model="commentText"
        >
        </el-input>
        <div class="comment-button" >
          <el-button 
            class="send-comment" 
            type="primary" 
            size="medium"
            @click="send"
          >提交</el-button>
        </div>
      </div>
    </div>
    <div class="comment-list-box">
      <ul class="comment-list">
        <li v-for="item in comments" :key="item.commentId">
          <a target="_blank" href="https://i.meishi.cc/cook.php?id=14026963" class="avatar">
           
          </a>
          <router-link :to="{name:'space',query:{userId: item.userInfo.userId}}" class="avatar">
            <img :src="item.userInfo.avatar">
            <h5>{{item.userInfo.name}}</h5>
          </router-link>
          <div class="comment-detail">
            <p class="p1">{{item.commentText}}</p>
            <div class="info clearfix">
              <span style="float: left;">{{item.createdAt}}</span>
            </div>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import {getComments,postComment} from '@/service/api';

export default {
  name: 'Comment',
  props:{
     info: {
      type: Object,
      default: () => ({})
    }
  },
  data(){
    return {
       comments:[],
       commentText:''

    }
  },
  computed: {
      userInfo(){
        return this.$store.state.userInfo
      },
      isLogin(){
        return this.$store.getters.isLogin
      }
  },
  async mounted(){
      let {menuId} = this.$route.query;
      if(menuId){
        let data = await getComments({menuId:menuId});
        // console.log(data)
        this.comments=data.data.comments
      }
  },
   methods:{
     async send(){
      let data=await postComment({menuId:this.info.menuId,commentText:this.commentText})
      console.log(data)
      this.comments.unshift(data.data.comments);
      this.commentText="";
   }
   },
  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值