前言:
- 本节给大家讲的是美食杰项目的美食详情页的主要功能和具体样式,希望我的代码能够帮助到你,也希望你能够看懂有所收获
具体样式
-
头部样式
-
内容样式
-
评论样式
实现效果
完成具体样式的渲染
完成评论的渲染并且可以实现发布评论的功能
代码思路
通过点击美食图片实现跳转,跳转到食品详情页,并将用户的id传进路由
利用id请求到美食的详细信息
并将这些数据传给相应的组件实现低耦合高边距
各个组件拿到数据之后挨个进行渲染
评论思路:
利用v-model将评论的内容拿到
利用接口的将评论的内容保存到接口数据里
相应的组件
相关代码
- detail组件为总组件,里面包含了页面的头部组件,内容组件,评论组件,路由跳转到此组件,相关代码:
<template>
<div class="detail">
<!-- 通过父传子将值传到响应的组件 -->
<!-- 头部 -->
<detailHeader :menuInfo="menuInfo"></detailHeader>
<!-- 内容 -->
<detailContent :menuInfo="menuInfo"></detailContent>
<!-- 评论 -->
<comment :menuInfo="menuInfo"></comment>
</div>
</template>
<script>
import { menuInfo } from "@/connector/api";
import detailHeader from "./detail-header";
import detailContent from "./detail-content";
import comment from "./comment";
export default {
data() {
return {
menuInfo: [],
};
},
components: {
// 组件
detailHeader,
detailContent,
comment,
},
mounted() {
// 将id结构出来
let { menuId } = this.$route.query;
console.log(menuId);
// 通过id将数据拿出来,赋值给menuInfo
menuInfo({ menuId }).then(({ data }) => {
console.log(data);
this.menuInfo = data.info;
});
},
};
</script>
- detail-header组件里面的具体功能就是将菜品的详细介绍出来,并将作者的基本信息列举出来,detail-header头部组件代码:
<template>
<div class="detail-header">
<div class="header-left">
<img :src="menuInfo.product_pic_url" alt="" />
</div>
<div class="header-right">
<div class="header-right-title">
<h1>{{ menuInfo.title }}</h1>
<div class="collection" @click="collection">
{{ menuInfo.isCollection ? "已收藏" : "收藏" }}
</div>
</div>
<ul class="detail-property">
<li v-for="item in menuInfo.properties_show" :key="item.type">
<strong>{{ item.parent_name }}</strong>
<span>{{ item.name }}</span>
</li>
</ul>
<div class="user">
<router-link class="img">
<img :src="menuInfo.userInfo.avatar" />
</router-link>
<div class="info">
<h4>
<router-link to="">
{{ menuInfo.userInfo.name }}
</router-link>
</h4>
<span
>菜谱:{{ menuInfo.userInfo.work_menus_len }}/ 关注:{{
menuInfo.userInfo.following_len
}} / 粉丝:{{ menuInfo.userInfo.follows_len }}</span
>
<strong>{{ menuInfo.userInfo.createdAt }}</strong>
</div>
</div>
</div>
</div>
</template>
<script>
import { toggleCollection } from "@/connector/api";
export default {
props: {
menuInfo: {
type: Object,
default: () => {},
},
},
methods: {
// 收藏
async collection() {
// 将用户id结构出来
const { userId } = this.$route.query;
// 将data数据拿出来
const { data } = await toggleCollection({ menuId: userId });
// 将值赋值给menuInfo里面的isCollection
// console.log(res);
this.menuInfo.isCollection = data.isCollection;
},
},
};
</script>
- detail-conten组件的主要功能是对菜品的主要介绍,将菜品的主料,辅料,具体步骤进行渲染。detail-content内容组件相关代码:
<template>
<div class="detail-content">
<div class="content-header">
<p class="">
<strong>“</strong>{{ menuInfo.product_story }}<strong>”</strong>
</p>
<h2>用料</h2>
<div class="materials">
<h3>主料</h3>
<ul>
<li
class=""
v-for="item in menuInfo.raw_material.main_material"
:key="item._id"
>
{{ item.name }}
<span>{{ item.space }}</span>
</li>
</ul>
</div>
<div class="materials">
<h3>辅料</h3>
<ul>
<li
class=""
v-for="item in menuInfo.raw_material.accessories_material"
:key="item._id"
>
{{ item.name }}
<span>{{ item.space }}</span>
</li>
</ul>
</div>
</div>
<div class="content">
<h2>{{ menuInfo.title }}</h2>
<div
class="detail-steps"
v-for="(item, index) in menuInfo.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>
</div>
<h2>烹饪技巧</h2>
<div class="skill">
{{ menuInfo.skill }}
</div>
</div>
</div>
</template>
<script>
export default {
// 用props来接收父元素传过来的值
props: {
menuInfo: {
type: Object,
default: () => {},
},
},
};
</script>
- comment组件为评论组件,主要功能就是渲染对菜品的评论,并且可以添加评论内容。comment评论组件相关代码
<template>
<div class="discuss">
<h2>“{{ menuInfo.title }}”的讨论</h2>
<div class="comment">
<router-link to=""
><img :src="menuInfo.userInfo.avatar" alt=""
/></router-link>
<!-- 判断是否登录 -->
<div v-if="!isLogin">
请先登录后,再评论<router-link to="">登录</router-link>
</div>
<div class="comment-right">
<el-input
type="textarea"
:rows="5"
:cols="300"
placeholder="请输入内容"
v-model="commentText"
>
</el-input>
<!-- 给提交写一个点击事件 -->
<div class="comment-button">
<el-button
class="send-comment"
type="primary"
size="medium"
style="float: left"
@click="sendComment"
>提交</el-button
>
</div>
</div>
</div>
<div class="comment-list">
<div class="comment-item" v-for="item in comments" :key="item.commentId">
<div class="avatar">
<img :src="item.userInfo.avatar" alt="" />
<span>{{ item.userInfo.name }}</span>
</div>
<div class="discuss-content">
<p>{{ item.commentText }}</p>
<p>{{ item.createdAt }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import { getComments, postComment } from "@/connector/api";
export default {
// props接受父组件传过来的数据
props: {
menuInfo: {
type: Object,
default: () => {},
},
},
data() {
return {
// 变量接收输入进去的值
commentText: "",
comments: [],
};
},
computed: {
// 看是否登录
isLogin() {
return this.$store.getters.isLogin;
},
},
async mounted() {
//向后端请求数据(评论的内容)
//有两种情况
console.log(this.$route.query);
let { userId } = this.$route.query;
// 判断是否有用户id
if (userId) {
// 将评论数据赋值给data
let data = await getComments({ menuId: userId });
console.log(data);
// 将data的评论数据赋值给comments里面
this.comments = data.data.comments;
}
},
methods: {
// 发送评论
async sendComment() {
// 将值传进接口
let data = await postComment({
menuId: this.menuInfo.menuId,
commentText: this.commentText,
});
// 将输入进的评论添加到comments里面
this.comments.unshift(data.data.comments);
// console.log(data.data.comments);
},
},
};
</script>
总结:
以上就是 美食杰项目中美食详情页的具体样式和实现方法,不懂得也可以在评论区里问我,以后会持续发布一些新的功能,敬请关注。我的其他作品