我们先看一下页面的效果为
接下来我们进行下面的开发
第一步是安装Mockplus,我们使用mockplus画一个快餐店点餐页面的线图。
我们在里面创建项目
宽1000,高600
这个是使用mockPlus拖拽生成的原型项目图
第二步:搭建项目
mpm install vue-cli -g
vue init webpack newdemo
cd newdemo
npm run dev
第二步:上阿里图标库选一些我们需要的图标
这次不是一个一个使用的单个图标,而是直接在index.html中引入图标css样式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>快餐店收银系统</title>
<link rel="stylesheet" href="//at.alicdn.com/t/font_1307406_b3oprhr1ycw.css">
<style>
html,body,#app{
height: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
第三步:添加组件,leftNav作为左侧的公共组件,Pos组件为功能组件
修改router文件
//src\router\index.js
import Vue from 'vue'
import Router from 'vue-router'
import Pos from '@/components//page/Pos'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Pos',
component: Pos
}
]
})
//src\App.vue
<template>
<div id="app">
<leftNav/>
<div class="main">
<router-view/>
</div>
</div>
</template>
<script>
import leftNav from '@/components/common/leftNav'
export default {
name: 'App',
components: {
leftNav
}
}
</script>
<style>
#app {
font-family: 'Microsoft Yahei''Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
/* margin-top: 60px; */
}
.main{
float: left;
width: 95%;
background-color: #EFF2F7;
height: 100%;
overflow: hidden;
}
</style>
//src\components\common\leftNav.vue
<template>
<div class="left-nav">
<ul>
<li>
<i class="i iconfont icongoumai"></i>
<div>收银</div>
</li>
<li>
<i class="i iconfont icondianpu"></i>
<div>店铺</div>
</li>
<li>
<i class="i iconfont icondianpu"></i>
<div>商品</div>
</li>
<li>
<i class="i iconfont iconhuiyuanqia"></i>
<div>会员</div>
</li>
<li>
<i class="i iconfont iconzuanshi"></i>
<div>统计</div>
</li>
<li>
<i class="i iconfont icongongnengjianyi"></i>
<div>设置</div>
</li>
</ul>
</div>
</template>
<script>
export default {
}
</script>
<style>
.left-nav{
color: #fff;
font-size: 10px;
height: 100%;
background-color: #1D8CE0;
float: left;
width: 5%;
}
.confont{
font-size: 24px;
}
.left-nav ul{
padding: 0px;
margin: 0px;
}
.left-nav li{
list-style: none;
text-align: center;
border-bottom: 1px solid #20a0ff;
padding: 10px;
}
</style>
关于右侧的点餐页面
我们使用的是element-ui,以及使用了axios和mock数据,模拟从后端获取数据
(一开始的时候,也是前端写死数据的)
关于核心的逻辑部分,点击常用商品,还有下面的有图标的各类商品,会在左侧的点餐页面中出现,并且还会计算金额和数量
当我们对点餐页面进行操作,进行删除和增加可以改变点餐页面中的数量以及金额,当我们点击删除的时候,点餐页面一切清空。
当我们点击结账页面,我们通过模拟结账,会弹出一个成功的提示或者失败的提示。
安装element-ui和axios
npm n install element-ui --save
npm n install axios --save
模拟的mock数据
created: function () {
let baseUrl =
'https://www.easy-mock.com/mock/5c07a781d292dd2dc4f9caa8/mockapi'
axios
.get(baseUrl + '/oftenGoods')
.then(response => {
console.log('response', response)
this.oftenGoods = response.data
})
.catch(error => {
console.log(error)
alert('网络错误,不能访问')
})
axios
.get(baseUrl + '/typeGoods')
.then(response => {
console.log('......response', response)
this.type0Goods = response.data[0]
this.type1Goods = response.data[1]
this.type2Goods = response.data[2]
this.type3Goods = response.data[3]
})
.catch(error => {
console.log(error)
alert('网络错误,不能访问')
})
},
我们模拟添加商品删除商品以及计算金额
addOrderList (goods) {
// 添加商品,商品是否已经在订单列表中
this.totalMoney = 0
this.totalCount = 0
let isHave = false
// 根据判断的值编写业务逻辑
// 判断是否存在商品
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].goodsId === goods.goodsId) {
isHave = true // 存在
}
}
// 根据判断的值编写业务逻辑
if (isHave) {
// 改变列表中商品的数量 这个过滤的是什么?
let arr = this.tableData.filter(o => o.goodsId === goods.goodsId)
arr[0].count++
console.log('arr....是什么', arr)
} else {
let newGoods = {
goodsId: goods.goodsId,
goodsName: goods.goodsName,
price: goods.price,
count: 1
}
this.tableData.push(newGoods)
}
// 计算汇总金额和数量
this.tableData.forEach(element => {
this.totalCount += element.count
this.totalMoney = this.totalMoney + element.price * element.count
})
this.getAllMoney()
},
// 删除单个商品
delSingleGoods (goods) {
this.tableData = this.tableData.filter(o => o.goodsId !== goods.goodsId)
this.getAllMoney()
},
delAllGoods () {
this.tableData = []
this.totalMoney = 0
this.totalCount = 0
},
// 汇总数量和金额
getAllMoney () {
this.totalCount = 0
this.totalMoney = 0
this.tableData.forEach(element => {
this.totalCount += element.count
this.totalMoney = this.totalMoney + element.price * element.count
})
},
模拟结账
//
// 结账 模拟结账
checkout () {
if (this.totalCount !== 0) {
this.tableData = []
this.totalCount = 0
this.totalMoney = 0
this.$message({
message: '结账成功,感谢你的光顾啊',
type: 'success'
})
} else {
this.$message.error('不能为空')
}
}
整个页面的代码为
//src\components\page\Pos.vue
<template>
<div class="pos">
<el-row>
<el-col :span="7" class="pos-order" id="order-list">
<el-tabs>
<el-tab-pane label="点餐">
<el-table :data="tableData" border style="width:100%;">
<el-table-column prop="goodsName" label="商品名称"></el-table-column>
<el-table-column prop="count" label="数量" width="50"></el-table-column>
<el-table-column prop="price" label="金额" width="70"></el-table-column>
<el-table-column label="操作" width="100" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="small" @click="delSingleGoods(scope.row)">删除</el-button>
<el-button type="text" size="small" @click="addOrderList(scope.row)">增加</el-button>
</template>
</el-table-column>
</el-table>
<div class="totalDiv">
<span>
<small>金额:</small>
{{totalMoney}}
</span>
<span>
<small>数量:</small>
{{totalCount}}
</span>
</div>
<div class="div-btn">
<el-button type="warning">挂单</el-button>
<el-button type="danger" @click="delAllGoods">删除</el-button>
<el-button type="success" @click="checkout">结账</el-button>
</div>
</el-tab-pane>
<el-tab-pane label="挂单">挂单</el-tab-pane>
<el-tab-pane label="外卖">外卖</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="17">
<div class="ofen-goods">
<div class="title">常用商品</div>
<div class="often-goods-list">
<ul>
<li v-for="goods in oftenGoods" :key="goods.goodsId" @click="addOrderList(goods)">
<span>{{goods.goodsName}}</span>
<span class="o-price">{{goods.price}}</span>
</li>
</ul>
</div>
</div>
<div class="goods-type">
<el-tabs>
<el-tab-pane label="汉堡">
<div>
<ul class="cookList">
<li v-for="goods in type0Goods" :key="goods.goodsId" @click="addOrderList(goods)">
<span class="foodImg">
<img
src="https://img.4008823823.com.cn/kfcios/Version/635_667540.jpg"
width="100%"
/>
</span>
<span class="foodName">{{goods.goodsName}}</span>
<span class="foodPrice">{{goods.price}}$</span>
</li>
</ul>
</div>
</el-tab-pane>
<el-tab-pane label="小食">
<ul class="cookList">
<li v-for="goods in type1Goods" :key="goods.goodsId" @click="addOrderList(goods)">
<span class="foodImg">
<img
src="https://img.4008823823.com.cn/kfcios/Version/635_667540.jpg"
width="100%"
/>
</span>
<span class="foodName">{{goods.goodsName}}</span>
<span class="foodPrice">{{goods.price}}$</span>
</li>
</ul>
</el-tab-pane>
<el-tab-pane label="饮料">
<ul class="cookList">
<li v-for="goods in type2Goods" :key="goods.goodsId" @click="addOrderList(goods)">
<span class="foodImg">
<img
src="https://img.4008823823.com.cn/kfcios/Version/635_667540.jpg"
width="100%"
/>
</span>
<span class="foodName">{{goods.goodsName}}</span>
<span class="foodPrice">{{goods.price}}$</span>
</li>
</ul>
</el-tab-pane>
<el-tab-pane label="套餐">
<ul class="cookList">
<li v-for="goods in type3Goods" :key="goods.goodsId" @click="addOrderList(goods)">
<span class="foodImg">
<img
src="https://img.4008823823.com.cn/kfcios/Version/635_667540.jpg"
width="100%"
/>
</span>
<span class="foodName">{{goods.goodsName}}</span>
<span class="foodPrice">{{goods.price}}$</span>
</li>
</ul>
</el-tab-pane>
</el-tabs>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import axios from 'axios'
// import { Message } from 'element-ui'
export default {
name: 'Pos',
data () {
return {
tableData: [
// {
// goodName: '香辣鸡腿堡',
// price: 15,
// count: 1
// },
// {
// goodName: '爱心薯条',
// price: 8,
// count: 1
// },
// {
// goodName: '甜筒',
// price: 8,
// count: 1
// }
],
oftenGoods: [
// {
// goodsId: 1,
// goodsName: '香辣鸡腿堡',
// price: 18
// },
// {
// goodsId: 2,
// goodsName: '薯条',
// price: 10
// },
// {
// goodsId: 3,
// goodsName: '可乐',
// price: 8
// },
// {
// goodsId: 4,
// goodsName: '鸡块',
// price: 21
// },
// {
// goodsId: 5,
// goodsName: '大份鸡腿',
// price: 18
// }
],
// type0Goods: [
// {
// goodsId: 1,
// goodsImg: 'https://img.4008823823.com.cn/kfcios/Version/621_626971.jpg',
// goodsName: '芝士厚菇素堡',
// price: 18
// },
// {
// goodsId: 2,
// goodsImg: 'https://img.4008823823.com.cn/kfcios/Version/640_684737.jpg',
// goodsName: '芝士澳牛堡',
// price: 10
// },
// {
// goodsId: 3,
// goodsImg: 'https://img.4008823823.com.cn/kfcios/Version/635_667540.jpg',
// goodsName: '脏脏大虾鸡堡',
// price: 12
// }
// ],
type0Goods: [],
type1Goods: [],
type2Goods: [],
type3Goods: [],
totalMoney: 0,
totalCount: 0
}
},
created: function () {
let baseUrl =
'https://www.easy-mock.com/mock/5c07a781d292dd2dc4f9caa8/mockapi'
axios
.get(baseUrl + '/oftenGoods')
.then(response => {
console.log('response', response)
this.oftenGoods = response.data
})
.catch(error => {
console.log(error)
alert('网络错误,不能访问')
})
axios
.get(baseUrl + '/typeGoods')
.then(response => {
console.log('......response', response)
this.type0Goods = response.data[0]
this.type1Goods = response.data[1]
this.type2Goods = response.data[2]
this.type3Goods = response.data[3]
})
.catch(error => {
console.log(error)
alert('网络错误,不能访问')
})
},
mounted: function () {
var orderHeight = document.body.clientHeight
console.log('orderHeight....', orderHeight)
document.getElementById('order-list').style.height = orderHeight + 'px'
},
methods: {
addOrderList (goods) {
// 添加商品,商品是否已经在订单列表中
this.totalMoney = 0
this.totalCount = 0
let isHave = false
// 根据判断的值编写业务逻辑
// 判断是否存在商品
for (let i = 0; i < this.tableData.length; i++) {
if (this.tableData[i].goodsId === goods.goodsId) {
isHave = true // 存在
}
}
// 根据判断的值编写业务逻辑
if (isHave) {
// 改变列表中商品的数量 这个过滤的是什么?
let arr = this.tableData.filter(o => o.goodsId === goods.goodsId)
arr[0].count++
console.log('arr....是什么', arr)
} else {
let newGoods = {
goodsId: goods.goodsId,
goodsName: goods.goodsName,
price: goods.price,
count: 1
}
this.tableData.push(newGoods)
}
// 计算汇总金额和数量
this.tableData.forEach(element => {
this.totalCount += element.count
this.totalMoney = this.totalMoney + element.price * element.count
})
this.getAllMoney()
},
// 删除单个商品
delSingleGoods (goods) {
this.tableData = this.tableData.filter(o => o.goodsId !== goods.goodsId)
this.getAllMoney()
},
delAllGoods () {
this.tableData = []
this.totalMoney = 0
this.totalCount = 0
},
// 汇总数量和金额
getAllMoney () {
this.totalCount = 0
this.totalMoney = 0
this.tableData.forEach(element => {
this.totalCount += element.count
this.totalMoney = this.totalMoney + element.price * element.count
})
},
// 结账 模拟结账
checkout () {
if (this.totalCount !== 0) {
this.tableData = []
this.totalCount = 0
this.totalMoney = 0
this.$message({
message: '结账成功,感谢你的光顾啊',
type: 'success'
})
} else {
this.$message.error('不能为空')
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.pos-order {
background-color: #f9fafc;
}
.div-btn {
margin-top: 10px;
}
.title {
height: 20px;
border-bottom: 1px solid #d3dce6;
background-color: #f9fafc;
padding: 10px;
text-align: left;
}
.often-goods-list ul li {
list-style: none;
float: left;
border: 1px solid #e5e9f2;
padding: 10px;
margin: 10px;
background-color: #fff;
cursor: pointer;
}
.o-price {
color: #58b7ff;
}
.goods-type {
clear: both;
margin-left: 20px;
border-top: 1px solid #d3dce6;
}
.cookList li {
list-style: none;
width: 23%;
border: 1px solid #e5e9f2;
height: auto;
overflow: hidden;
background-color: #fff;
padding: 2px;
float: left;
margin: 2px;
cursor: pointer;
}
.cookList li span {
display: block;
float: left;
}
.foodImg {
width: 40%;
}
.foodName {
font-size: 18px;
padding-left: 10px;
color: brown;
}
.foodPrice {
font-size: 16px;
padding-left: 10px;
padding-top: 10px;
}
.totalDiv {
background-color: #fff;
padding: 10px;
border-bottom: 1px solid#D3dce6;
color: red;
}
</style>