实现效果:
在detail组件中:
1.根据menuld请求数据(查看数据结构),渲染页面(如果没有menuld,提示框请登录)
注意:数据结构过多,在保存到组件中时,提前写好默认值。避免在异步请求返回数据之前找下到属性。
头部:
1.根据数据,逐个渲染头部页面。用户信息中,query传入用户id,跳转个人空间
2.收藏按钮:判断是否本人登录再显示
3..收藏功能:I判断是否登录,再请求,否则提示框,请先登录
菜谱做法的顺序
1.逐个渲染数据中,菜品的步骤:编号使用数组下标+1即可(index)
评论:
1.获取菜品本来的评论
2.输入评论点击提交可以发送
3.未登录账号时显示不能评论需要登录
效果显现方式
使用vue脚手架搭建项目完成效果
使用element组件库
使用vue-router路由
vuex库
等...
效果图
登陆时评论区的状态
未登录时状态
当前菜品有评论时会显示 但是不能提交评论
说明各个组件负责的块 以及实现代码说明
detail.vue 获取所有数据
detail-header.vue 获取头部数据 块(第一张图)
detail-content.vue 菜品制作过程
comment.vue 评论区块
detail中代码
<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'; // 从menuInfo中获取数据 数据从后端拿
export default {
components: {DetailHeader, DetailContent, Comment},
data(){
return {
menuInfo:{//获取数据给menuInfo 下面是我们需要数据的解构进行一下声明
userInfo:{},
raw_material:{
accessories_material:[],
main_material:[]
},
steps:[]
},
}
},
//获取数据
watch:{
$route:{
handler(){
let {menuId} = this.$route.query;
//判断进入的query的路径,路径不对需要重新进入
if(menuId){//发请求
menuInfo({menuId}).then(({data})=>{
this.menuInfo=data.info
console.log(data)
})
}else{
this.$message({
showClose:true,
message:'请重新进入',
type:'warning'
})
}
},
immediate:true
},
}
}
</script>
detail-header.vue 头部中代码
<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.userId}}"
>
<img :src="info.userInfo.avatar">
</router-link>
<div class="info">
<h4>
<router-link id="tongji_author"
:to="{name:'space', query:{userId:info.userId}}" tag="em"
>
{{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'
});
return
}
const data = await toggleCollection({menuId:this.info.menuId})
console.log(data)
this.info.isCollection = data.data.isCollection;
}
}
}
</script>
detail-content.vue 菜品制作过程 代码块 这一块没什么拿数据渲染
<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.specs}}</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.specs}}</span>
</li>
</ul>
</div>
</div>
<div class="detail-explain">
<h2>{{info.title}}的做法</h2>
<section class="detail-section clearfix"
v-for="(proc,index) in info.steps"
:key="index"
>
<!--key值标记当前数量 index+1所以下一步就是index+1-->
<em class="detail-number">{{index+1}}.</em>、
<div class="detail-explain-desc">
<p>{{proc.describe}}</p>
<img class="conimg" :src="proc.img_url" v-if="proc.img_url.length" 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>
comment.vue 评论区块代码
<template>
<div class="comment-box">
<h2>{{info.title}}的讨论</h2>
<div class="comment-text">
<!--img 用户头像显示-->
<a href="javascript:;" class="useravatar">
<img :src="userInfo.avatar">
</a>
<div v-if="!isLogin">请先登录后,再评论<router-link :to="{name:'space'}">登录</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>
<!--send点击提交的事件-->
</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 {
commentText:'',
comments:[]
}
},
computed: {
//判断用户是否登陆账号
isLogin(){
return this.$store.getters.isLogin
},
//获取头像
userInfo(){
return this.$store.state.userInfo
}
},
//提交评论
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 = ""//添加后清空
}
},
//获取当前菜谱的历史评论
async mounted(){
let {menuId} = this.$route.query;
if(menuId){
let {data} = await getComments({menuId:menuId})
this.comments=data.comments;
// console.log(data)
// console.log(this.comments)
}
},
}
</script>
以上效果的代码展示完毕
下次见