美食杰项目 -- 菜品信息(五)

简介: 美食杰项目 -- 菜品信息(五)

前言:

本文给大家讲解,美食杰项目中 实现菜品信息页的效果,和具体代码。


具体实现思路:

  1. 跳转时传递菜品 id
  2. 根据菜品 id 进行(获取菜品详细信息,获取评论信息,发布评论,收藏/取消收藏)
  3. 点击收藏,判断是否收藏如果收藏则取消收藏,未收藏则收藏
  4. 给 input 框输入信息,点击提交发布评论信息
  5. 提交后的评论信息添加到开头
  6. 根据效果图进行渲染

步骤:

1. 展示美食杰菜谱大全效果

ff66102b1a4a44ddb4ca2db1b96a1bca.png

image.png

美食杰菜品信息页


2. 引入element-ui


点击跳转至 element-ui 中 input 输入框使用方法:https://element.eleme.cn/#/zh-CN/component/input

点击跳转至 element-ui 中 button 按钮使用方法:https://element.eleme.cn/#/zh-CN/component/button


3. 代码

菜品信息页中可以引入 element-ui 框架使用,本文引入了 input 输入框方法,button 则使用了原生 js。

当然静态页面其他地方你也可以使用 element-ui 框架或其他框架进行布局。

<template>
  <div class="box">
    <!-- 个人信息 -->
    <div class="header">
      <img :src="menuInfo.product_pic_url" class="head" />
      <div class="right">
        <div class="title">
          {{ menuInfo.title }}
          <a
            href="#"
            @click="collect"
            :class="{ action: menuInfo.isCollection }"
          >
            <!-- 判断是否收藏,样式不同 -->
            {{ menuInfo.isCollection ? "已收藏" : "未收藏" }}
          </a>
        </div>
        <div class="introduce">
          <span
            v-for="item in menuInfo.properties_show"
            :key="item.parent_type"
          >
            {{ item.parent_name }}
            <br />
            <b>{{ item.name }}</b>
          </span>
        </div>
        <div class="message">
          <img :src="menuInfo.userInfo.avatar" />
          <div class="bottom">
            <p class="name">{{ menuInfo.userInfo.name }}</p>
            <p>
              菜谱:{{ menuInfo.userInfo.work_menus_len }} / 关注:{{
                menuInfo.userInfo.following_len
              }}
              / 粉丝:{{ menuInfo.userInfo.follows_len }}
            </p>
            <p class="time">{{ menuInfo.createdAt }}</p>
          </div>
        </div>
      </div>
    </div>
    <!-- 用料 -->
    <div class="seasoning">
      <p class="product_story">{{ menuInfo.product_story }}</p>
      <p class="title">用料</p>
      <div class="flavour">
        <p>主料</p>
        <span
          v-for="item in menuInfo.raw_material.main_material"
          :key="item._id"
        >
          {{ item.name }} {{ item.specs }}
        </span>
      </div>
      <div class="flavour">
        <p>辅料</p>
        <span
          v-for="item in menuInfo.raw_material.accessories_material"
          :key="item._id"
        >
          {{ item.name }} {{ item.specs }}
        </span>
      </div>
    </div>
    <!-- 步骤 -->
    <div class="practice">
      <p class="title">{{ menuInfo.title }}的做法</p>
      <li v-for="(item, index) in menuInfo.steps" :key="index">
        <i>{{ index + 1 }}.</i>
        <img :src="item.img_url" alt="" />
        <span>{{ item.describe }}</span>
      </li>
      <p class="skill">烹饪技巧</p>
      <p class="skills">{{ menuInfo.skill }}</p>
    </div>
    <!-- 评论 -->
    <div class="comments">
      <p class="title">{{ menuInfo.title }}的讨论</p>
      <div class="message">
        <img
          :src="$store.state.userInfo.avatar"
          alt=""
          v-if="$store.getters.islogin"
        />
        <!-- 判断是否登录,登录显示发布评论,未登录不显示 -->
        <p v-if="!$store.getters.islogin">请先登录后,在进行评论</p>
        <br />
        <el-input
          type="textarea"
          :rows="5"
          :cols="500"
          placeholder="请输入内容"
          v-model="commentText"
          class="textarea"
          v-if="$store.getters.islogin"
        >
        </el-input>
        <br />
        <button class="btn" v-if="$store.getters.islogin" @click="release">
          提交
        </button>
      </div>
      <p class="xian"></p>
      <!-- 已发布评论 -->
      <ul class="information">
        <li v-for="item in comments" :key="item.commentId">
          <span class="name">{{ item.userInfo.name }}</span>
          <img :src="item.userInfo.avatar" alt="" />
          <span class="mes">
            <p class="text">{{ item.commentText }}</p>
            <p class="time">{{ item.updateAt }}</p>
          </span>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
// 收藏,菜谱信息,获取评论信息,提交评论信息
import {
  toggleCollection,
  menuInfo,
  getComments,
  postComment,
} from "@/connector/api";
export default {
  data() {
    return {
      // 菜谱信息
      menuInfo: [],
      // 评论信息
      comments: [],
      // 发布的内容
      commentText: "",
    };
  },
  mounted() {
    // 获取进入菜品的 id
    const { menuId } = this.$route.query;
    // 根据菜品 id 获取菜品信息
    menuInfo({ menuId: menuId }).then(({ data }) => {
      // console.log(data);
      this.menuInfo = data.info;
    });
    // 根据菜品 id 获取评论信息
    getComments({ menuId: menuId }).then(({ data }) => {
      // console.log(data.comments);
      this.comments = data.comments;
    });
  },
  methods: {
    // 收藏
    async collect() {
      // 获取进入菜品的 id
      const { menuId } = this.$route.query;
      // 已收藏则取消收藏,未收藏则收藏
      const { data } = await toggleCollection({ menuId: menuId });
      // 给菜品信息进行更新
      this.menuInfo.isCollection = data.isCollection;
    },
    // 发布
    async release() {
      // 获取进入菜品的 id
      const { menuId } = this.$route.query;
      // 根据菜品 id 发布评论
      const data = await postComment({
        menuId: menuId,
        // 发布的内容
        commentText: this.commentText,
      });
      // 添加到开头
      this.comments.unshift(data.data.comments);
      // 发布成功后发布信息框为空
      this.commentText = "";
    },
  },
};
</script>
<style lang="scss" scoped>
.box {
  width: 990px;
  margin: 20px auto 0;
  .header {
    background-color: #fff;
    display: flex;
    .head {
      width: 25%;
      height: 350px;
    }
    .right {
      width: 75%;
      .title {
        display: flex;
        justify-content: space-between;
        padding: 20px 30px;
        border-bottom: 1px solid gainsboro;
        font-size: 25px;
        a {
          font-size: 16px;
          padding: 10px 15px;
          background-color: red;
          border-radius: 10px;
          text-decoration: none;
          color: #fff;
        }
        .action {
          background-color: gainsboro;
        }
      }
      .introduce {
        width: 65%;
        display: flex;
        flex-wrap: wrap;
        span {
          width: 50%;
          padding: 15px 10px;
          display: inline-block;
          border-bottom: 1px solid gainsboro;
          border-right: 1px solid gainsboro;
          font-size: 15px;
          b {
            color: red;
            font-weight: 400;
            font-size: 25px;
          }
        }
      }
      .message {
        display: flex;
        img {
          width: 50px;
          height: 50px;
          margin: 25px 0 0 25px;
          border-radius: 50%;
        }
        .bottom {
          margin: 25px 0 0 20px;
          font-size: 12px;
          color: gainsboro;
          p {
            margin: 0;
            padding: 1px 0;
          }
          .name {
            color: red;
          }
        }
      }
    }
  }
  .seasoning {
    background-color: #fff;
    .product_story {
      padding: 10px 20px;
    }
    .title {
      font-size: 20px;
      padding: 0 20px 10px;
      border-bottom: 1px solid gainsboro;
    }
    .flavour {
      p {
        width: 40px;
        text-align: center;
        padding: 2px 0;
        margin-left: 20px;
        font-size: 12px;
        background-color: rgb(241, 241, 241);
        border: 1px solid gray;
      }
      span {
        display: inline-block;
        padding: 5px;
        font-size: 14px;
        margin: 0 0 20px 5px;
        border: 1px solid gray;
      }
    }
  }
  .practice {
    background-color: #fff;
    .title {
      font-size: 20px;
      padding: 20px;
      border-bottom: 1px solid gainsboro;
    }
    li {
      list-style: none;
      padding: 10px 20px;
      i {
        color: red;
        font-size: 40px;
      }
      img {
        padding: 0 10px;
      }
    }
    .skill {
      padding: 10px 20px 20px;
      border-bottom: 1px solid gainsboro;
      font-size: 20px;
    }
    .skills {
      padding: 10px 0 20px 50px;
    }
  }
  .comments {
    background-color: #fff;
    padding: 0 20px;
    .title {
      padding: 20px 0;
      font-size: 20px;
      border-bottom: 1px solid gainsboro;
    }
    .message {
      width: 70%;
      img {
        width: 50px;
        height: 50px;
      }
      p {
        text-align: center;
        margin: 0;
      }
      .btn {
        padding: 10px 20px;
        border: none;
        background-color: red;
        color: #fff;
        margin-left: 89.9%;
      }
    }
    .xian {
      height: 1px;
      background-color: gainsboro;
    }
    .information {
      padding: 0;
      li {
        margin: 10px 0;
        display: flex;
        list-style: none;
        align-items: center;
        color: #333;
        img {
          width: 70px;
          height: 70px;
          margin: 0 20px;
        }
        .mes {
          .text {
            font-size: 18px;
          }
          .time {
            color: gainsboro;
          }
        }
      }
    }
  }
}
</style>

总结:

总结:

以上就是 美食杰项目 中 菜品信息的具体实现方法,不懂得也可以在评论区里问我,以后会持续发布一些新的功能,敬请关注。



相关文章
|
12月前
|
数据采集 XML JSON
获取携程网站上指定景点的用户评论数据
获取携程网站上指定景点的用户评论数据
504 0
|
2月前
|
存储 数据可视化 安全
大学餐厅菜品推荐和点评系统设计与实现
大学餐厅菜品推荐和点评系统设计与实现
美食杰项目 -- 登录注册(三)
美食杰项目 -- 登录注册(三)
美食杰项目 -- 登录注册(三)
|
数据采集 Python
Python爬虫系列18-采集电视剧详情 比如:导演、年份、类型、短评等数据
身材不好就去锻炼,没钱就努力去赚,别把窘迫困境迁怒于别人,你唯一可以抱怨的就是不够努力的自己。 向往别人看过的风景,但是到了周末,却抱着手机在家宅过一个又一个周末。所以当自己想到的一些东西就赶紧行动起来,羡慕别人不如行动自己。 如果只是一味的去羡慕别人,从来都不去让自己行动起来,那么你永远都会在见证别人的成功,在见证别人的成长。
Python爬虫系列18-采集电视剧详情 比如:导演、年份、类型、短评等数据
好客租房175-获取当前小区被点击房源数据
好客租房175-获取当前小区被点击房源数据
96 0
好客租房175-获取当前小区被点击房源数据