看效果:
detail.vue:
<template>
<div class="menu-detail">
<detail-header :info='info'></detail-header>
<detail-content :cai='info'></detail-content>
<Comment :title='info.title'></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 {
info:{
userInfo:{},
raw_material:{
main_material:[], //
accessories_material:[]
},
steps:[]
}
}
},
watch:{
$route:{
handler(value) {
console.log(value.query.menuId);
if(value.query.menuId){
menuInfo({menuId:value.query.menuId}).then(data=>{
console.log(data.data.info);
this.info = data.data.info
})
}else{
this.$message({
type:'warning',
showClose:true,
message: '请重新进入'
})
}
},
immediate:true
}
}
}
</script>
组件DetailHeader:
<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='bbb()'
>
{{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>
<script>
import {toggleCollection} from '@/service/api'
export default {
data(){
return {
}
},
props:{
info: {
type: Object,
default: () => ({})
}
},
computed: {
isOnwer(){
return this.info.userInfo.userId == this.$store.state.userInfo.userId
}
},
methods:{
bbb(){
if(this.$store.getters.isLogin){
toggleCollection({menuId:this.$route.query.menuId}).then(data=>{
// console.log(data.data.isCollection);
this.info.isCollection = data.data.isCollection
if(this.info.isCollection){
this.$message({
type:'success',
showClose:true,
message: '收藏成功,快去试试看吧'
})
}else{
this.$message({
type:'error',
showClose:true,
message: '取消收藏,你吃屎吧'
})
}
})
}else{
this.$message({
type:'warning',
showClose:true,
message: '给老子先登录'
})
}
}
},
}
</script>
<style lang="stylus">
.detail-header
margin-top 40px
display flex
background-color #fff
.detail-img
width 328px
.detail-header-right
width 662px
.detail-title
box-sizing border-box
width 100%
padding-left: 25px;
border-bottom: 1px solid #eee;
.title
max-width: 288px;
height: 44px;
padding: 28px 0px;
line-height: 44px;
font-size: 36px;
color: #333;
float left
.collected
background: #999;
.collecte
background: #ff3232;
.detail-collection
float right
display block
height: 50px;
line-height: 44px;
color #fff
padding: 0px 14px;
text-align center
margin-top 25px
cursor pointer
a
display: inline-block;
padding: 3px 0;
width: 50px;
color: #fff;
text-align: center;
line-height 20px
.collection-at
background-color: #ff3232;
.no-collection-at
background-color: #999 !important;
.detail-property
margin-left 2px
overflow hidden
display:flex
flex-shrink :1
flex-wrap :wrap
justify-content :center
gap:20%;
li
width 199px
float left
height 48px
border-right 1px solid #eee
padding 18px 0px 18px 20px
border-bottom 1px solid #eee
strong
color #999
line-height 18px
display block
height 18px
span
display block
font-size 24px
color #ff3232
line-height 30px
width 100px
.user
height 70px
padding 20px 0px 20px 20px
overflow hidden
font-size 12px
a.img
display block
height 70px
width 70px
float left
position relative
border-radius 35px
overflow hidden
img
display block
height 70px
width 70px
.info
float left
padding-left 10px
height 70px
h4
height 22px
line-height 22px
font-size 14px
color #ff3232
position relative
a
color #ff3232
display inline-block
vertical-align top
padding-right 0px
height 22px
span
line-height 24px
display block
color #666
padding-top 4px
strong
line-height 22px
color #999
</style>
组件DetailContent:
<template>
<section class="detail-content">
<div class="detail-materials">
<p class=""><strong>“</strong>{{cai.product_story}}<strong>”</strong></p>
<h2>用料</h2>
<div class="detail-materials-box clearfix" v-if='cai.raw_material.main_material.length'>
<h3>主料</h3>
<ul>
<li class=""
v-for='item in cai.raw_material.main_material'
>
{{item.name}}
<span>{{item.specs}}</span>
</li>
</ul>
</div>
<div class="detail-materials-box clearfix" v-if='cai.raw_material.accessories_material.length'>
<h3>辅料</h3>
<ul>
<li class=""
v-for='item in cai.raw_material.accessories_material'
:key='item._id'
>
{{item.name}}
<span>适量</span>
</li>
</ul>
</div>
</div>
<div class="detail-explain">
<h2>{{cai.title}}的做法</h2>
<section class="detail-section clearfix"
v-for='item,keys in cai.steps'
:key='item._id'
>
<em class="detail-number">{{keys+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>{{cai.skill}}</p>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'DetailContent',
data(){
return{
}
},
props:{
cai:{
type:Object,
default:()=>({})
}
}
}
</script>
<style lang="stylus">
.detail-content
margin-top 20px
h2
font-size 24px
color #333
height 66px
line-height 66px
border-bottom 1px solid #eee
text-indent 24px
font-family Microsoft Yahei
display block
.detail-materials
background-color #fff
> p
line-height 24px
font-size 14px
padding 20px 24px 10px
color #666
.detail-materials-box
margin-bottom 20px
h3
width 48px
height 22px
color #999
background #f5f5f5
border 1px solid #ddd
text-align center
line-height 24px
margin 14px 5px 14px 25px
float left
ul
float left
width 910px
li
float left
box-sizing border-box
height 54px
line-height 54px
margin 0 5px 5px 5px
padding 0 10px
border 1px solid #eee
.detail-explain
background-color #fff
padding-bottom 20px
.detail-section
.detail-number
font-size 50px
color #ff3232
font-style italic
text-align center
font-family arial
height 50px
width 100px
display block
float left
line-height 50px
.detail-explain-desc
float left
width 650px
overflow hidden
p
line-height 24px
color #666
padding 10px 20px 10px 0px
position relative
font-size 14px
img
max-width 550px
.skill
p
font-size 12px
padding-left 100px
padding-top 10px
</style>
组件comment:
<template>
<div class="comment-box">
<h2>{{title}}的讨论</h2>
<div class="comment-text">
<router-link to='/space' class="useravatar" v-if='$store.state.userInfo.avatar'>
<img :src="$store.state.userInfo.avatar" alt="">
</router-link>
<div v-if="!isLogin">请先登录后,再评论<router-link to="/login" style='color:#ff3232'>登录</router-link></div>
<div class="comment-right"
v-if='this.$store.getters.isLogin'
>
<el-input
type="textarea"
:rows="5"
:cols="50"
placeholder="请输入内容"
v-model='commentRight'
>
</el-input>
<div class="comment-button" >
<el-button
class="send-comment"
type="primary"
size="medium"
@click='sub()'
>提交</el-button>
</div>
</div>
</div>
<div class="comment-list-box">
<ul class="comment-list">
<li v-for='item in comments'>
<!-- <a target="_blank" href="https://i.meishi.cc/cook.php?id=14026963" class="avatar">
</a> -->
<router-link :to="{name:'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.updateAt}}</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import {getComments,postComment} from '@/service/api';
export default {
name: 'Comment',
props:{
title:String
},
data(){
return {
isLogin:this.$store.getters.isLogin,
comments:[],
commentRight:''
}
},
computed: {
},
methods:{
sub(){
if(this.commentRight != '' && this.commentRight.trim() != ''){
console.log(this.commentRight);
postComment({menuId:this.$route.query.menuId,commentText:this.commentRight}).then(data=>{
console.log(data);
})
getComments({menuId:this.$route.query.menuId}).then(res=>{
// console.log(res.data.comments);
this.comments = res.data.comments
})
}else{
this.$message({
message: '发个空评论给谁看呢??',
type: 'error'
});
}
this.commentRight = '';
}
},
mounted(){
if(this.$route.query.menuId){
getComments({menuId:this.$route.query.menuId}).then(res=>{
console.log(res.data.comments);
this.comments = res.data.comments
})
}
}
}
</script>
<style lang="stylus">
.comment-box
background-color #ffffff
margin-top 20px
padding 0 20px
h2
font-size 24px
color #333
height 66px
line-height 66px
border-bottom 1px solid #eee
.comment-text
margin-top 20px
.useravatar
margin-right 20px
img
vertical-align top
width 36px
height 36px
.comment-right
display inline-block
width 80%
.comment-button
text-align right
margin-top 10px
.send-comment
background #ff3232
border none
.comment-list-box
border-top 1px solid #eee
margin-top 20px
padding-top 30px
ul li
border-bottom 1px solid #eee
margin-bottom 20px
.avatar
height 82px
width 50px
overflow hidden
display inline-block
h5
white-space nowrap
img
height 50px
width 50px
.comment-detail
display inline-block
vertical-align top
margin-left 20px
width 80%
p
margin 0
font-size 14px
.info
margin-top 10px
color #999
.thumbs
cursor pointer
font-size 18px
.thumbs-actve
color red
</style>