main.js(引入element框架)
import Vue from 'vue'
import App from './App.vue'
import store from './store/'
import router from './router/index.js'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import "./assets/css/index.styl";
import "./assets/css/over-write.styl";
Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
在项目中使用npm install element安装后引入
页面代码:
<template>
<div class="create">
<h2>欢迎发布新菜谱,先介绍一下你的大作!</h2>
<section class="create-introduce">
<h5>标题</h5>
{{backData.title}}
<el-input v-model='backData.title' class="create-input" placeholder="请输入内容"></el-input>
<h5>属性</h5>
<div>
<el-select
v-for='item in propertyies'
: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>
<h5>菜谱分类</h5>
<div>
<el-select placeholder="请选择菜谱分类"
v-model='backData.classify'
>
<el-option-group
v-for='group,keys in classifies'
:key='group.parent_type'
:label='group.parent_name'
>
<el-option
v-for='item in group.list'
:key='item.type'
:label='item.name'
:value='item.type'
>
</el-option>
</el-option-group>
</el-select>
</div>
<h5>成品图 (328*440)</h5>
<div class="upload-img-box clearfix">
<div class="upload-img">
<upload-img
action='api/upload?type=produce'
:image-url='backData.produce_pic_url'
@res-url='(data)=>{backData.porduct_pic_url = data.resImgUrl}'
></upload-img>
</div>
<el-input
class="introduce-text"
type="textarea"
:rows="10"
placeholder="请输入内容"
>
</el-input>
</div>
</section>
<h2>记录所有原材料</h2>
<section class="create-introduce">
<h5>主料</h5>
<!--[ { "name": "", "specs": "" }, { "name": "", "specs": "" }, { "name": "", "specs": "" } ]-->
<Stuff
v-model='backData.raw_material.main_material'
></Stuff>
<h5>辅料</h5>
<Stuff
v-model='backData.raw_material.accessories_material'
></Stuff>
</section>
<h2>开始写步骤了!能否简单易学就看你怎么写了,加油!</h2>
<section class="create-introduce">
<Upload
v-for='item,keys in backData.steps'
:arr='backData.steps'
:num='keys'
@ccc='jjj($event)'
></Upload>
<el-button
class="eaeaea add-step-button"
type="primary"
size="medium"
icon="el-icon-plus"
@click='bbb'
>增加一步</el-button>
<h5>烹饪小技巧</h5>
<el-input
class="introduce-text"
type="textarea"
:rows="8"
placeholder="分享下你做这道菜的过程中的心得和小技巧吧!"
>
</el-input>
</section>
<el-button
class="send"
type="primary"
size="medium"
:icon="icon"
>搞定,提交审核</el-button>
</div>
</template>
<script>
import Stuff from './stuff'
import Upload from './step-upload'
import UploadImg from '@/components/upload-img'
import {getProperty, getClassify, publish} from '@/service/api'
export default {
name: 'create',
components: {Stuff,Upload,UploadImg},
data(){
return {
backData:{
title:'',
property: {},
classify:'',
porduct_pic_url:'',
product_story:'',
raw_material: { // 料
main_material: [
{name: '',specs: ''},
{name: '',specs: ''}
], // 主料
accessories_material: [{name: '',specs: ''}], // 辅料
},
steps: [{img_url: '',describe: '',id:1}]
},
propertyies:[],
classifies:[]
}
},
mounted(){
getProperty().then(({data})=>{
// console.log(data);
this.propertyies = data;
this.backData.property = data.reduce((o,item)=>{
o[item.title] = '';
return o;
},{})
})
getClassify().then(({data})=>{
console.log(data);
this.classifies = data;
})
},
methods:{
bbb(){
this.backData.steps.push({img_url: '',describe: '',id:Date.now()})
// this.backData.steps = [...this.backData.steps,{img_url: '',describe: '',}]
},
jjj(data){
this.backData.steps = data
}
}
}
</script>
<style lang="stylus">
.create-introduce
background-color #fff
padding 20px
.add-step-button
margin-left 100px
.create
width 100%
h2
text-align center
margin 20px 0
.send
// ff3232()
height: 70px;
width: 220px;
background #ff3232
color #fff
border none
margin 20px auto
display block
h5
margin 20px 0
.create-input input
width 446px
line-height 22px
.upload-img-box
.upload-img
float left
.introduce-text
// float left
.el-textarea
width 60%
margin-left 10px
</style>
Stuff组件:
<template>
<div class="stuff">
<div class="clearfix">
<div class="raw-item"
v-for='item,keys in value'
:key='keys'
>
<el-input v-model='item.name' placeholder="请输入内容" style="width: 200px" ></el-input>
<el-input v-model='item.specs' placeholder="请输入内容" style="width: 100px" ></el-input>
<i class="delete-icon el-icon-close" v-show='value.length !== 1' @click='remove(keys)'></i>
</div>
</div>
<el-button class="eaeaea" type="primary" size="medium" icon="el-icon-plus" @click='add'>增加一项</el-button>
</div>
</template>
<script>
// v-model 在组件上面双向绑定 value 发布事件input
export default {
props: {
value:{
type:Array,
default:()=>[]
}
},
methods:{
add(){
this.$emit('input',[
...this.value,
{"name":'',"space":''}
])
},
remove(index){
// this.value.splice(index,1)
const newValue = this.value.filter((item,i)=>{
return i !== index
})
this.$emit('input',newValue);
}
}
}
</script>
<style lang="stylus">
.delete-icon
background-color #ccc
border-radius 50%
color #fff
:hover
background: #ff3232;
color: #fff;
.raw-item
float left
margin-right 65px
margin-bottom 20px
.el-input
margin-right 5px
</style>
Upload组件:
<template>
<div class="step clearfix">
<div class="step-number">{{num+1}}</div>
<div class="upload-box">
<upload-img
:img-max-width="184"
></upload-img>
</div>
<el-input
class="introduce-text"
type="textarea"
:rows="8"
placeholder="请输入内容"
>
</el-input>
<i class="delete-icon el-icon-close" v-show='arr.length > 1' @click='remove(num)'></i>
</div>
</template>
<script>
import UploadImg from '@/components/upload-img'
export default {
components: {UploadImg},
imageUrl: 'https://s1.c.meishij.net/n/images/upload_step_img.png',
props: {
num:Number,
arr:{
type:Array,
default:()=>[]
}
},
methods: {
remove(a){
const newArr = this.arr.filter((item,i)=>{
return i !== a
})
console.log(newArr);
this.$emit('ccc',newArr)
}
},
mounted(){
console.log(this.num);
console.log(this.arr);
}
}
</script>
<style lang="stylus">
.step
margin-bottom 20px
> div
float left
.step-number
height 180px
width 100px
font-size 60px
color #aaa
font-family Arial, Helvetica, sans-serif
font-weight bold
vertical-align top
line-height 180px
.introduce-text
width 60%
margin-left 40px
.upload-box
img
vertical-align top
</style>
UploadImg组件:
<template>
<el-upload
class="avatar-uploader"
:action="action"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</template>
<script>
export default {
props:{
action:String,
maxSize:{
type:Number,
default:2
},
imageUrl:{
type:String,
default:''
},
imgMaxWidth:{
type:[Number,String],
default:'auto'
}
},
data(){
return {
imageUrl:'',
}
},
methods: {
//图片上传成功之后
handleAvatarSuccess(res, file) {
if(res.code === 1){
this.$message({
message:res.mes,
type:'warning'
})
return;
}
// console.log(res);
// console.log(file);
console.log(this.action);
this.imageUrl = URL.createObjectURL(file.raw);
this.$emit('res-url',{
resImgUrl:res.data.url
})
},
//图片上传成功之前
beforeAvatarUpload(file) {
//限制图片的类型
const isJPG = file.type === 'image/jpeg';
//限制图片的内存大小
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
}
}
}
</script>