美食杰-菜谱详情页

一、 菜谱介绍

        美食杰详情页页面,通过使用elementUI组件配合进行渲染页面,这里我们分为3个组件分别进行渲染,组件分为 头部组件(detail-header)、主体组件(detail-content)、评论组件(detail-comment) 配合 主组件(detail) 进行渲染;

这里我们看一下整体效果图

二、Detail组件传递数据

        这里我们就开始进行渲染组件,我们先从detail组件开始进行编写,先在detail组件进行网络请求,这里我们在 watch 监听属性进行路由的跳转请求数据,menuInfo这个API 接受一个参数( 点击进入detail组件路由跳转时传递的query参数里面的id ) 

 

我们可以清楚看见detail已经请求到数据了,组件数据请求到之后,我们分别给分开的3个组件进行props传值操作

 

三、渲染组件

这里我们3个组件传入的名字都叫 info

 detail-header组件

         直接进行渲染即可; info. xxx

<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"
              @click='collectionClick'
              :class="{'no-collection-at': info.isCollection}"
            > 
                {{info.isCollection ? '已收藏' : '收藏'}}
            </a>
          </div>
      </div>
      
      <ul class="detail-property clearfix">
        <li v-for='item in info.properties_show' :key='item.parent_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>

收藏的操作, 先这样,在那样  (请求到组件,然后赋值)

         这里 isClooection 值为 true 或 false, 我们点击一下按钮 它的值就会在 true/false 之间进行切换,我们可以进行 三目运算符 判断 是否 显示为 已收藏, 样式也是一样的操作。

detail-contnet组件

        同样的操作直接渲染 info.xxx

<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">
        <h3>主料</h3>
        <ul>
          <li 
            class=""
            v-for='item in info.raw_material.main_material'
            :key='item._id'
          >  
            {{item.name}}
            <span>{{item.specs}}</span>
          </li>
        </ul>
      </div>
      <div class="detail-materials-box clearfix">
        <h3>辅料</h3>
        <ul>
          <li 
            class=""
            v-for='item in info.raw_material.accessories_material'
            :key='item._id'  
          >
            {{item.name}}
            <span>{{item.specs}}</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" alt="">
        </div>
      </section>
      <div class="skill">
        <h2>烹饪技巧</h2>
        <p>{{info.skill}}</p>
      </div>
    </div>
  </section>
</template>
<script>

detail-comment组件

        首先我们在created生命周期进行 网络请求 拿到数据先把 评论 这块进行渲染渲染;

         之后,在点击提交按钮时 进行 发送数据的请求 请求 getCommentsApi,嗯,之后在点击发布的时候,postComment 这个api会获取到我们在评论里面输入的内容,然后我们把 获取到的数据插入到 userComments 这个数组, 然后我们把 commentText 设置为 空字符串  。

<template>
  <div class="comment-box">
    <h2>{{info.title}}的讨论</h2>
    <div class="comment-text">
      <a href="javascript:;" class="useravatar">
        <img :src="userAvatar">
      </a>

      <div  v-if="!isLogin">请先登录后,再评论<router-link to="/login">登录</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='submitClick'
          >提交</el-button>
        </div>
      </div>
    </div>
    <div class="comment-list-box">
      <ul class="comment-list">
        <li v-for='(item, index) in userComments' :key='item.commentId'>
          <a target="_blank" href="https://i.meishi.cc/cook.php?id=14026963" class="avatar">
            {{index + 1}}.
          </a>
          <router-link :to="{
            path: '/space',
            query: {
              userId: item.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>
            <p @click='removeClick(index)'>删除</p>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import {getComments, postComment} from '@/service/api';
export default {
  name: 'Comment',
  props:{
    info: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data(){
    return {
      id: this.$route.query.id,
      commentText: '',
      userComments: []
    }
  },
  computed: {
    isLogin() {
      //const isLogin = localStorage.getItem('token')
      //if(isLogin) return isLogin
      return this.$store.getters.isLogin
    },
    userAvatar() {
      return this.$store.state.userInfo.avatar
    }
  },
  methods:{
    async submitClick() {
      if(this.commentText) {
        let state = await postComment({
          menuId: this.id, 
          commentText: this.commentText
        })
        this.commentText = ''
        this.userComments.unshift(state.data.comments)
        //this._getComments()
        console.log(state)
      } else {
        return false
      }
    },
    async _getComments() {
      if(this.id) {
        let { data } = await getComments({menuId: this.id});
        this.userComments = data.comments
        //console.log(this.userComments)
      } 
    },
    removeClick(index) {
      this.userComments =  this.userComments.filter((item, indey) => {
        return index != indey
      })
    }
  },
   created() {
    this._getComments()
  }
}
</script>

好了,差不多就完事了,今天就到这里吧,各位再见 。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值