vue项目开发卡片展示页面----菜品管理
对话框表单获取父组件数据
子组件dishform
对话框表单样式
methods
中的dataInit
方法 获取父组件传来的数据
<script>
export default {
name: 'DishForm',
data() {
return {
form: {
dis_name: '',
dis_size: '',
dis_description: '',
dis_img: '',
dis_delete_status: '',
dis_sales: '',
dis_price:'',
dis_sort:''
}
}
},
methods: {
dataInit(data) {
if (data) {
this.form = data;
console.info(data);
}
}
}
}
</script>
父组件 dish
dialogFormVisible
对话框表单是否显示的变量
<dishform v-if="dialogFormVisible" ref="popWindow"/>
引入dishform表单 ref调用子组件的数据
onSubmit
方法
<el-dialog
title="菜品信息"
:visible.sync="dialogFormVisible"
width="30%">
<dishform v-if="dialogFormVisible" ref="popWindow"/>
<span slot="footer" class="dialog-footer">
<a-button style="margin-right: 8px" @click="dialogVisible = false">取 消</a-button>
<a-button type="primary" @click="onSubmit">确 定</a-button>
</span>
</el-dialog>
onSubmit(){
this.dialogFormVisible=false;
}
父组件将数据传入表单
dish js
//修改菜品信息
changeItem(item){
this.dialogFormVisible = true;
this.addOperate = false;//用同一表单 标志 是修改还是增加
console.log(item)
//传数据给子组件
this.$nextTick(() => {
this.$refs.popWindow.dataInit(item)
})
}
菜品卡片样式
dish template
card-list
样式
:dataSource="dataSource"
将dataSource中的数据以Array的方式传给list
slot-scope="item"
item存取了每一个list的数据
@click="changeItem(item)"
点击修改 调用传参函数
<a-card>
<a-divider style="height: 3px; ">
<h3>主 菜</h3>
</a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="zc"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<span slot="actions" @click="changeItem(item)">修改</span>
<span slot="actions" @click="dishesDelete(item)">删除</span>
</a-card>
</a-list-item>
</a-list>
</div>
<el-dialog
title="菜品信息"
:visible.sync="dialogFormVisible"
width="30%">
<dishform v-if="dialogFormVisible" ref="popWindow"/>
<span slot="footer" class="dialog-footer">
<a-button style="margin-right: 8px" @click="dialogFormVisible = false">取 消</a-button>
<a-button type="primary" @click="onSubmit">确 定</a-button>
</span>
</el-dialog>
</a-list>
</div>
</a-card>
上传图片
<el-upload
class="avatar-uploader"
action="http://tgmmmmmmmm.online:8443/upload"
:on-change="handleChange"
:show-file-list="false"
:before-upload="httpRequest"><!--覆盖默认上传-->
<img v-if="form.disImg" :src="form.disImg" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
onchangemd(e){
console.log(e.target.files)//这个就是选中文件信息
},
//将上传图片的原路径赋值给临时路径
handleChange(file) {
this.form.disImg = URL.createObjectURL(file.raw);
},
// 实现图片上传功能 将图片赋值给file 确定所有数据统一上传
httpRequest(item) {
this.form.file = item
console.log(item)
}
添加数据 页面数据增加
localadd(form,imgurl,disid){
var obj = {
"disId": disid,
"disName": form.disName,
"disSize": form.disSize,
"disDescription": form.disDescription,
"disImg": imgurl,
"disSales": form.disSales,
"disPrice": form.disPrice,
"disSort": form.disSort,
"deleted": 0
}
switch (getSortCode(form.disSort)) {
case "xj":
this.xj.push(obj)
break
case "zc":
this.zc.push(obj)
break
case "qt":
this.qt.push(obj)
break
case "xc":
this.xc.push(obj)
break
case "js":
this.js.push(obj)
break
}
},
完整代码
dish.vue
<template>
<div>
<a-card>
<a-divider style="height: 3px; ">
<h3>主 菜</h3>
</a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="zc"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<span slot="actions" @click="changeItem(item)">修改</span>
<span slot="actions" @click="dishesDelete(item)">删除</span>
</a-card>
</a-list-item>
</a-list>
</div>
<el-dialog
title="菜品信息"
:visible.sync="dialogFormVisible"
width="30%">
<dishform v-if="dialogFormVisible" ref="popWindow"/>
<span slot="footer" class="dialog-footer">
<a-button style="margin-right: 8px" @click="dialogFormVisible = false">取 消</a-button>
<a-button type="primary" @click="onSubmit">确 定</a-button>
</span>
</el-dialog>
<a-divider style="height: 3px;"><h3>小 吃 下 酒 菜</h3></a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="xj"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<a slot="actions" @click="changeItem(item)">修改</a>
<a slot="actions" @click="dishesDelete(item)">删除</a>
</a-card>
</a-list-item>
</a-list>
</div>
<a-divider style="height: 3px;"><h3>小 菜</h3></a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="xc"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<span slot="actions" @click="changeItem(item)">修改</span>
<span slot="actions" @click="dishesDelete(item)">删除</span>
</a-card>
</a-list-item>
</a-list>
</div>
<a-divider style="height: 3px;"><h3>酒 水 饮 料</h3></a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="js"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<span slot="actions" @click="changeItem(item)">修改</span>
<span slot="actions" @click="dishesDelete(item)">删除</span>
</a-card>
</a-list-item>
</a-list>
</div>
<a-divider style="height: 3px;"><h3>其 它</h3></a-divider>
<div class="card-list">
<a-list
:grid="{gutter: 24, lg: 4, md: 2, sm: 1, xs: 1}"
:dataSource="qt"
>
<a-list-item slot="renderItem" slot-scope="item">
<a-card :hoverable="true">
<a-card-meta>
<div style="margin-bottom: 3px" slot="title">{{ item.disName }}</div>
<a-avatar shape="square" slot="avatar" :src="item.disImg" :size="100"/>
<div class="meta-content" slot="description">
<div>
{{item.disDescription}}
</div>
<div>
{{"价格:"+item.disPrice+"元/"+item.disSize}}
</div>
<div v-if="item.disSales===null">
{{"销量:"+0+"次"}}
</div>
<div v-else>
{{"销量:"+item.disSales+"次"}}
</div>
</div>
</a-card-meta>
<!-- changeItem(item) 修改菜品信息-->
<span slot="actions" @click="changeItem(item)">修改</span>
<span slot="actions" @click="dishesDelete(item)">删除</span>
</a-card>
</a-list-item>
</a-list>
</div>
</a-card>
<footer-tool-bar>
<a-button type="primary" @click="handleCreate">增加菜品</a-button>
</footer-tool-bar>
</div>
</template>
<script>
import FooterToolBar from "@/components/tool/FooterToolBar";
import dishform from "@/pages/Dish_mg/DishForm"
import { dishesSortList} from "@/services/dishesdata";
import axios from "_axios@0.27.2@axios";
import qs from 'qs';
import {getSortCode} from "@/utils/mngzsutil";
export default {
name: 'CardDish',
components: {FooterToolBar, dishform},
data() {
return {
xj:[],
zc:[],
qt:[],
xc:[],
js:[],
// dataSource,
dialogFormVisible: false,
addOperate: undefined//标志 是修改还是增加
}
},
methods: {
handleCreate() {
this.dialogFormVisible = true
this.addOperate = true
},
localdeletedish(disId){
var index = -1
// 本地删除,通过公用函数获取分类文字代码
index = this.xj.findIndex(i => i.disId == disId)
if(index != -1) {
this.xj.splice(index, 1);
}
index = this.zc.findIndex(i => i.disId == disId)
if(index != -1){
this.zc.splice(index, 1);
}
index = this.qt.findIndex(i => i.disId == disId)
if(index != -1){
this.qt.splice(index, 1);
}
index = this.xc.findIndex(i => i.disId == disId)
if(index != -1){
this.xc.splice(index, 1);
}
index = this.js.findIndex(i => i.disId == disId)
if(index != -1){
this.js.splice(index, 1);
}
},
dishesDelete(item){
// 本地删除调用
this.localdeletedish(item.disId)
const data = { 'id': item.disId.toString() }
const options = {
method: 'DElETE',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify(data),
url: "http://tgmmmmmmmm.online:8443/dishes"
}
axios(options).then((res)=>{
console.log("删除菜品",res)
this.$message({message:"删除菜品 "+item.disName+" 成功",type:"warning"});
}).catch((err)=>{
console.log(err)
})
},
// dishesDelete1(item){
// 此方法也可行
// // 本地删除调用
// this.localdeletedish(item.disSort,item.disId)
// const params = new FormData()
// params.append("id",item.disId)
// const options = {
// method: 'DElETE',
// headers: { 'content-type': 'application/x-www-form-urlencoded' },
// data: params,
// url: "http://tgmmmmmmmm.online:8443/dishes"
// }
// axios(options).then((res)=>{
// console.log("删除菜品",res)
// this.$message({message:"删除菜品 "+item.disName+" 成功",type:"warning"});
// }).catch((err)=>{
// console.log(err)
// })
// },
//获取数据
getDishesSort(){
dishesSortList().then((res)=>{
// console.log(res.data.data.dishesList.xj)
for(let i=0;i<res.data.data.dishesList.xj.length;i++)
{
this.xj.push(res.data.data.dishesList.xj[i])
}
for(let i=0;i<res.data.data.dishesList.zc.length;i++)
{
this.zc.push(res.data.data.dishesList.zc[i])
}
for(let i=0;i<res.data.data.dishesList.qt.length;i++)
{
this.qt.push(res.data.data.dishesList.qt[i])
}
for(let i=0;i<res.data.data.dishesList.xc.length;i++)
{
this.xc.push(res.data.data.dishesList.xc[i])
}
for(let i=0;i<res.data.data.dishesList.js.length;i++)
{
this.js.push(res.data.data.dishesList.js[i])
}
})
},
// 本地添加,图片链接解决
localadd(form,imgurl,disid){
var obj = {
"disId": disid,
"disName": form.disName,
"disSize": form.disSize,
"disDescription": form.disDescription,
"disImg": imgurl,
"disSales": form.disSales,
"disPrice": form.disPrice,
"disSort": form.disSort,
"deleted": 0
}
switch (getSortCode(form.disSort)) {
case "xj":
this.xj.push(obj)
break
case "zc":
this.zc.push(obj)
break
case "qt":
this.qt.push(obj)
break
case "xc":
this.xc.push(obj)
break
case "js":
this.js.push(obj)
break
}
},
localmodify(form,imgurl){
this.localdeletedish(form.disId)
var obj = {
"disId": form.disId,
"disName": form.disName,
"disSize": form.disSize,
"disDescription": form.disDescription,
"disImg": imgurl,
"disSales": form.disSales,
"disPrice": form.disPrice,
"disSort": form.disSort,
"deleted": 0
}
switch (getSortCode(form.disSort)) {
case "xj":
this.xj.push(obj)
break
case "zc":
this.zc.push(obj)
break
case "qt":
this.qt.push(obj)
break
case "xc":
this.xc.push(obj)
break
case "js":
this.js.push(obj)
break
}
},
//添加提交菜品信息
onSubmit(){
// 需要提交的form表单
var form = this.$refs.popWindow.form
if (this.addOperate) {
// console.log("增加")
var f = new FormData()
f.append("disDescription",form.disDescription)
f.append("file",form.file)
f.append("disName",form.disName)
f.append("disPrice",form.disPrice)
f.append("disSort",form.disSort)
f.append("disSize",form.disSize)
f.append("disSales",0)
const options = {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: f,
url: "http://tgmmmmmmmm.online:8443/dishes"
}
axios(options).then((res)=>{
console.log("增加菜品",res)
this.$message({message:"增加菜品"+ form.disName + "成功!",type:"success"})
this.localadd(form,res.data.data.disImg,res.data.data.disId)
}).catch((err)=>{
console.log(err)
})
this.dialogFormVisible = false
} else {
var ff = new FormData()
ff.append("disDescription",form.disDescription)
ff.append("file",form.file)
ff.append("disName",form.disName)
ff.append("disPrice",form.disPrice)
ff.append("disSort",form.disSort)
ff.append("disSize",form.disSize)
ff.append("disSales",form.disSales)
ff.append("disId",form.disId)
ff.append("disImg",form.disImg)
const options = {
method: 'PUT',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: ff,
url: "http://tgmmmmmmmm.online:8443/dishes"
}
axios(options).then((res)=>{
this.$message({message:"修改菜品"+ form.disName + "成功!",type:"success"})
this.localmodify(form,res.data.data.disImg)
console.log("修改菜品",res)
}).catch((err)=>{
console.log(err)
})
this.dialogFormVisible = false
}
},
//修改菜品信息
changeItem(item){
this.dialogFormVisible = true;
this.addOperate = false;
// console.log(item)
this.$nextTick(() => {
this.$refs.popWindow.dataInit(item)
})
}
},
mounted() {
this.getDishesSort();
}
}
</script>
<style lang="less" scoped>
.card-avatar {
width: 48px;
height: 48px;
border-radius: 48px;
}
.new-btn {
border-radius: 2px;
width: 100%;
height: 187px;
}
.meta-content {
position: relative;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
height: 64px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
</style>
dishForm.vue
<template>
<div class="mycontainer">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="菜品名称">
<el-input v-model="form.disName" style="width: 150px;float: left"></el-input>
</el-form-item>
<el-form-item label="菜品分类">
<el-select v-model="form.disSort" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="菜品价格">
<el-input v-model="form.disPrice" style="width: 150px;float: left"></el-input>
</el-form-item>
<el-form-item label="菜品规格">
<el-input v-model="form.disSize" style="width: 150px;float: left"></el-input>
</el-form-item>
<el-form-item label="菜品描述">
<el-input v-model="form.disDescription" style="width: 200px;float: left"></el-input>
</el-form-item>
<el-form-item label="菜品图片">
<el-upload
class="avatar-uploader"
action="http://tgmmmmmmmm.online:8443/upload"
:on-change="handleChange"
:show-file-list="false"
:before-upload="httpRequest"><!--覆盖默认上传-->
<img v-if="form.disImg" :src="form.disImg" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'DishForm',
components: {},
data() {
return {
form: {
deleted: '',
disDescription: "",
disId: '',
disImg: "",
disName: "",
disPrice: '',
disSales: '',
disSize: "",
disSort: "",
file:undefined
},
// formdata:new FormData(),
imageUrl: '',
tempUrl: '',
options: [{
value: '选项1',
label: '主菜'
}, {
value: '选项2',
label: '小吃下酒菜'
}, {
value: '选项3',
label: '小菜'
}, {
value: '选项4',
label: '酒水饮料'
}, {
value: '选项5',
label: '其他'
}],
}
},
methods: {
dataInit(data) {
if (data) {
this.form = data;
console.info(data);
}
},
onchangemd(e){
console.log(e.target.files)//这个就是选中文件信息
},
//将上传图片的原路径赋值给临时路径
handleChange(file) {
this.form.disImg = URL.createObjectURL(file.raw);
},
// 实现图片上传功能
httpRequest(item) {
this.form.file = item
console.log(item)
}
}
}
</script>
<style scoped>
.mycontainer {
display: flex;
flex-direction: column;
justify-content: space-around
}
.avatar-uploader {
margin-top: 20px;
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 78px;
height: 78px;
}
.avatar-uploader:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 78px;
height: 78px;
line-height: 78px;
text-align: center;
}
.avatar {
width: 78px;
height: 78px;
display: flex;
}
</style>