目录
- 前言
- 具体效果
- 实现的具体功能
- 代码思路
- 主要引入的element ui的具体样式
- 相关代码
- 总结:
前言
- 本节给大家讲的是美食杰项目的发布菜谱的主要功能和具体样式,希望我的代码能够帮助到你,也希望你能够看懂
具体效果
实现的具体功能
按照效果图实现静态页面布局
可以使用element-ui框架
实现上传图片功能
默认为3个可以增加,删除,最少为1个
点击提交,成功发布菜谱
代码思路
主页面完成具体的样式,可以看element ui的具体框架来实现具体样式
根据选项来实现具体口味和烹饪方法
将主料辅料功能实现组件化封装
将上传图片进行组件化封装
将选的具体数据传给接口实现发布菜谱
主要引入的element ui的具体样式
点击这里跳转到的element ui上传图片的具体样式和使用
点击这里跳转到的element ui中input的具体样式和使用
点击这里跳转到的element ui中select的具体样式和使用
相关代码
由于前面将编辑资料的时候说过上传图片的具体功能和样式,如果想要了解编辑资料可以
点击这里跳转到编辑个人资料页面看上传图片的样式
- 主页面为总组件发布菜谱的主要功能都在这里面所以代码有点多、主页面的相关代码:
<template>
<div class="box">
<p class="title">欢迎发布新菜谱,先介绍一下你的大作</p>
<div class="top">
<div class="headline">
<p>标题</p>
<input type="text" placeholder="请输入内容" v-model="backData.title" />
</div>
<div class="property">
<p>属性</p>
<el-select
v-for="item in property"
:key="item.parent_type"
:placeholder="item.parent_name"
v-model="backData.property[item.title]"
>
<el-option
v-for="option in item.list"
:key="option.type"
:label="option.name"
:value="option.type"
></el-option>
</el-select>
</div>
<div class="classify">
<p>菜谱分类</p>
<el-select v-model="backData.classify" placeholder="请选择">
<el-option-group
v-for="item in classify"
:key="item.parent_type"
:label="item.parent_name"
>
<el-option
v-for="option in item.list"
:key="option.type"
:label="option.name"
:value="option.type"
>
</el-option>
</el-option-group>
</el-select>
</div>
<div class="articles">
<p>成品图(328*440)</p>
<div>
<upload-img
action="/api/upload/?type=product"
class="image"
v-model="backData.product_pic_url"
@res-url="(data) => (backData.product_pic_url = data.resImgUrl)"
:imageUrl="backData.product_pic_url"
></upload-img>
<el-input
type="textarea"
:rows="5"
:cols="500"
placeholder="请输入内容"
class="textarea"
v-model="backData.product_story"
>
</el-input>
</div>
</div>
</div>
<p class="title">记录所有原材料</p>
<div class="center">
<div class="one">
<p>主料</p>
<Material
v-model="backData.raw_material.main_material"
@remove="(item) => (backData.raw_material.main_material = item)"
></Material>
</div>
<div class="two">
<p>辅料</p>
<Material
v-model="backData.raw_material.accessories_material"
@remove="
(item) => (backData.raw_material.accessories_material = item)
"
></Material>
</div>
</div>
<p class="title">开始写步骤了!能否简单易学就看你怎么写了,加油!</p>
<div class="bottom">
<div v-for="(item, index) in backData.steps" :key="index">
<b>{{ index }}.</b>
<upload-img
v-model="item.img_url"
:imageUrl="avatar"
:imgMaxWidth="184"
class="image"
action="/api/upload/?type=step"
@res-url="
(data) => (
(item.img_url = data.resImgUrl), (avatar = data.resImgUrl)
)
"
></upload-img>
<el-input
type="textarea"
:rows="2"
placeholder="请输入内容"
v-model="item.describe"
>
</el-input>
<i
class="delete-icon el-icon-close"
v-show="backData.steps.length !== 1"
@click="remove(index, id)"
></i>
</div>
<el-button
class="eaeaea"
type="primary"
size="medium"
icon="el-icon-plus"
@click="add"
>增加一项</el-button
>
<p>烹饪小技巧</p>
<el-input
type="textarea"
:rows="2"
placeholder="请输入内容"
:style="{ height: '150px' }"
v-model="backData.skill"
>
</el-input>
</div>
<div class="btn">
<button @click="submit">搞定,提交审核</button>
</div>
</div>
</template>
<script>
import { getProperty, getClassify, publish } from "@/connector/api";
import UploadImg from "@/views/uploadImg/upload_img.vue";
import Material from "@/views/PublishRecipes/material.vue";
// const backData = {
// //向后端发生的数据
// title: "",
// property: {
// craft: 0, // 工艺 enum: [1,2,3,4],
// flavor: 0, // 口味 enum: [1,2,3,4],
// hard: 0, // 难度 enum: [1,2,3,4],
// pepole: 0, // pepole 人数: [1,2,3,4],
// },
// //分类
// classify: "",
// //成品图
// product_pic_url:
// "https://s1.c.meishij.net/n/images/upload_big_img.png?_=1561906961", // 成品图URL
// product_story: "", // 成品图故事
// raw_material: {
// // 料
// main_material: [{ name: "", specs: "" }], // 主料
// accessories_material: [{ name: "", specs: "" }], // 辅料
// },
// // steps: [{img_url: '',describe: '',}], // 步骤
// steps: Array(3)
// .fill(1)
// .map(() => ({ ...steps_struct, customeId: this.uuid() })),
// skill: "", //心得
// };
const material = {
name: "",
specs: "",
};
const steps_struct = {
img_url: "",
describe: "",
};
export default {
components: {
UploadImg,
Material,
},
data() {
return {
// 向后端发送的数据
backData: {
// 标题
title: "",
property: {
// craft: 0, // 工艺 enum: [1,2,3,4],
// flavor: 0, // 口味 enum: [1,2,3,4],
// hard: 0, // 难度 enum: [1,2,3,4],
// pepole: 0, // pepole 人数: [1,2,3,4],
},
classify: "",
// 成品图
product_pic_url:
"https://s1.c.meishij.net/n/images/upload_big_img.png?_=1561906961",
product_story: "",
raw_material: {
// Array(3):数组长度为3,fill(1):数组的值为1,map:循环添加值
main_material: Array(3)
.fill(1)
.map(() => ({ ...material })), // 主料
accessories_material: Array(3)
.fill(1)
.map(() => ({ ...material })), // 辅料
},
steps: Array(3)
.fill(1)
.map(() => ({ ...steps_struct })),
skill: "",
},
property: [],
classify: [],
avatar: "https://s1.c.meishij.net/n/images/upload_step_img.png",
};
},
mounted() {
// 获取所有属性分类
getProperty().then(({ data }) => {
// console.log(data);
this.property = data;
});
// 获取所有菜谱分类
getClassify().then(({ data }) => {
// console.log(data);
this.classify = data;
});
},
methods: {
// 点击删除
remove(index) {
this.backData.steps.splice(index, 1);
},
// 点击添加
add() {
this.backData.steps.push({
img_url: "",
describe: "",
});
},
// 点击发布新的菜品
submit() {
// console.log(this.backData);
// 发布新菜品的请求头
publish(this.backData).then((data) => {
// console.log(data);
// 发布成功后跳转至首页
window.location.href = "/";
});
},
},
};
</script>
- input输入框为主料辅料的具体代码由于他是封装起来的所以单独实现、input输入框的具体代码
<template>
<div>
<div class="raw-item" v-for="(item, index) in value" :key="index">
<el-input
placeholder="请输入内容"
style="width: 200px"
v-model="item.name"
></el-input>
<el-input
placeholder="请输入内容"
style="width: 100px"
v-model="item.specs"
></el-input>
<!-- 只要input不等于1,删除功能就一直显示 -->
<i
class="delete-icon el-icon-close"
v-show="value.length !== 1"
@click="remove(index, id)"
></i>
</div>
<el-button
class="eaeaea"
type="primary"
size="medium"
icon="el-icon-plus"
@click="add"
>增加一项</el-button
>
</div>
</template>
<script>
export default {
props: {
// 接收数据v-model传递数据
value: {
type: Array,
default: () => [],
},
},
methods: {
// 点击删除
remove(index) {
const newValue = this.value.filter((item, i) => {
// console.log(index, item, i);
return i !== index;
});
// console.log(newValue);
this.$emit("remove", newValue);
},
add() {
// 子传父触发数据
this.$emit("input", [...this.value, { name: "", specs: "" }]);
},
},
};
</script>
总结:
以上就是 美食杰项目 中 发布菜谱页的具体实现方法,不懂得也可以在评论区里问我或私聊我询问,以后会持续发布一些新的功能,敬请关注。
我的其他文章