Vue.js 2 快餐店收银系统

技术栈

Vue.js 2 + Webpack + Element + Axios + vueRouter.

效果图

图标 Iconfont

在项目开发过程中经常会遇到小图标的使用问题,小图标的使用可以让程序更美观。在这里推荐使用 IconFont,这是阿里巴巴的矢量图标库。

在 Iconfont 中有很多图标,我们可以像逛超市一样,挑选自己喜欢的商品,然后放入购物车。

使用步骤如下:
第一步:拷贝项目下面生成的 fontclass 代码

//at.alicdn.com/t/font_6fwsxglzew154s4i.css

第二步:挑选相应图标并获取类名,应用于页面

<i class="iconfont icon-hanbao"></i>

侧边栏导航组件

LeftNav.vue

<template>
    <div class="left-nav">
        <ul>
            <li>
                <i class="iconfont icon-wodezichan"></i>
                <div>收银</div>
            </li>
    
            <li>
                <i class="iconfont icon-dianpu"></i>
                <div>店铺</div>
            </li>
    
            <li>
                <i class="iconfont icon-hanbao"></i>
                <div>商品</div>
            </li>
    
            <li>
                <i class="iconfont icon-31huiyuan"></i>
                <div>会员</div>
            </li>
        </ul>
    </div>
</template>
<script>
export default {
    name: 'LeftNav'
}
</script>
<style>
.left-nav {
    color: #fff;
    font-size: 10px;
    background-color: #1D8ce0;
    float: left;
    height: 100%;
    width: 5%;
}

.iconfont {
    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 布局

  • npm 安装
npm install element-ui --save
  • 引入项目
    main.js 中加入以下内容:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
Vue.use(ElementUI)

右侧内容组件

Main.vue

<template>
    <div class="content">
        <el-row class="row">
            <el-col :span="9" class="col1">
                <el-tabs>
                    <el-tab-pane label="点餐">
                        <el-table :data="goods" style="width: 100%" stripe>
                            <el-table-column prop="goodsName" label="商品名称">
                            </el-table-column>
                            <el-table-column prop="count" label="数量" width="70">
                            </el-table-column>
                            <el-table-column prop="price" label="金额" width="70">
                            </el-table-column>
                            <el-table-column label="操作" width="100" fixed="right">
                                <template scope="scope">
                                    <el-button type="text" size="small" @click="del(scope.row)">删除</el-button>
                                    <el-button type="text" size="small" @click="add(scope.row)">增加</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
    
                        <div class="summarize">
                            <small>数量:</small>{{totalCount}}
                            <small>金额:</small>{{totalMoney}}元
                        </div>
    
                        <div class="block">
                            <span class="wrapper">
                                <el-button type="warning">挂单</el-button>
                                <el-button type="danger" @click="goods=[]">删除</el-button>
                                <el-button type="info" @click="checkout">结账</el-button>
                            </span>
                        </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="15" class="col2">
                <div class="common-goods">
                    <div class="title">常用商品</div>
                    <div class="goods-list">
                        <ul>
                            <li v-for="good in commonGoods" @click="add(good)">
                                <span v-text="good.goodsName"></span>
                                <span class="good-price">¥{{good.price}}元</span>
                            </li>
                        </ul>
                    </div>
                </div>
                <div class="category">
                    <el-tabs>
                        <el-tab-pane label="汉堡">
                            <ul class='type-list'>
                                <li v-for="hanbao in hanbaoGoods" @click="add(hanbao)">
                                    <span class="img">
                                        ![](hanbao.goodsImg)
                                    </span>
                                    <span class="name">{{hanbao.goodsName}}</span>
                                    <span class="price">¥{{hanbao.price}}元</span>
                                </li>
                            </ul>
                        </el-tab-pane>
                        <el-tab-pane label="小食">
                            <ul class='type-list'>
                                <li v-for="xiaoshi in xiaoshiGoods" @click="add(xiaoshi)">
                                    <span class="img">
                                        ![](xiaoshi.goodsImg)
                                    </span>
                                    <span class="name">{{xiaoshi.goodsName}}</span>
                                    <span class="price">¥{{xiaoshi.price}}元</span>
                                </li>
                            </ul>
                        </el-tab-pane>
                        <el-tab-pane label="饮料">
                            <ul class='type-list'>
                                <li v-for="yinliao in yinliaoGoods" @click="add(yinliao)">
                                    <span class="img">
                                        ![](yinliao.goodsImg)
                                    </span>
                                    <span class="name">{{yinliao.goodsName}}</span>
                                    <span class="price">¥{{yinliao.price}}元</span>
                                </li>
                            </ul>
                        </el-tab-pane>
                        <el-tab-pane label="套餐">
                            <ul class='type-list'>
                                <li v-for="taocan in taocanGoods" @click="add(taocan)">
                                    <span class="img">
                                        ![](taocan.goodsImg)
                                    </span>
                                    <span class="name">{{taocan.goodsName}}</span>
                                    <span class="price">¥{{taocan.price}}元</span>
                                </li>
                            </ul>
                        </el-tab-pane>
                    </el-tabs>
                </div>
            </el-col>
        </el-row>
    </div>
</template>
<script>
import axios from 'axios'
export default {
    name: 'main',
    data() {
        return {
            goods: [],
            commonGoods: [],
            hanbaoGoods: [],
            xiaoshiGoods: [],
            yinliaoGoods: [],
            taocanGoods: []
        }
    },
    methods: {
        add(good) {
            let data = this.goods.filter(g => g.goodsId == good.goodsId)
            if (data.length > 0) {
                data[0].count++
            } else {
                // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
                let newGood = Object.assign({}, good)
                newGood.count = 1
                this.goods.push(newGood)
            }
        },
        del(good) {
            this.goods = this.goods.filter(g => g.goodsId != good.goodsId)
        },
        checkout() {
            if (this.goods.length != 0) {
                this.goods = []
                this.totalCount = 0
                this.totalMoney = 0
                this.$message({
                    message: '结账成功^_^',
                    type: 'success'
                });
            } else {
                this.$message.error('不能空结⊙o⊙');
            }
        }
    },
    computed: {
        totalCount() {
            let count = 0
            this.goods.forEach(function (element) {
                count += element.count
            }, this);
            return count
        },
        totalMoney() {
            let money = 0
            this.goods.forEach(function (element) {
                money += element.count * element.price
            }, this);
            return money
        }
    },
    created() {
        // 读取常用商品列表
        axios.get('http://jspang.com/DemoApi/oftenGoods.php').then(response => {
            this.commonGoods = response.data
        }).catch(error => {
            console.log(error)
        });

        // 读取分类商品列表
        axios.get('http://jspang.com/DemoApi/typeGoods.php').then(response => {
            this.hanbaoGoods = response.data[0]
            this.xiaoshiGoods = response.data[1]
            this.yinliaoGoods = response.data[2]
            this.taocanGoods = response.data[3]
        }).catch(error => {
            console.log(error)
        })
    }
}

</script>
<style>
.content,
.row,
.col1,
.col2,
.card {
    height: 100%;
}

.col1 {
    border-right: 1px solid;
}

.block {
    margin-top: 20px;
    text-align: center;
}

.title {
    height: 42px;
    line-height: 42px;
    border-bottom: 1px solid #D3DCE6;
    background-color: #F9FAFC;
    color: #20a0ff;
    padding-left: 15px;
}

.goods-list ul li {
    list-style: none;
    float: left;
    border: 1px solid #E5E9F2;
    padding: 10px;
    margin: 5px;
    background-color: #fff;
    cursor: pointer;
}

.good-price {
    color: #58B7FF;
}

.category {
    clear: both;
}

.type-list li {
    list-style: none;
    width: 30%;
    border: 1px solid #E5E9F2;
    height: auot;
    overflow: hidden;
    background-color: #fff;
    padding: 2px;
    float: left;
    margin: 2px;
    cursor: pointer;
}

.type-list li span {
    display: block;
    float: left;
}

.img {
    width: 40%;
}

.name {
    font-size: 18px;
    padding-left: 10px;
    color: brown;
}

.price {
    font-size: 16px;
    padding-left: 10px;
    padding-top: 10px;
}

.summarize {
    text-align: center;
    padding: 10px;
    border-bottom: 1px solid #E5E9F2;
}

.summarize small {
    margin-left: 40px;
}
</style>

其余代码

index.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>awesomepos</title>
  <link rel="stylesheet" href="http://at.alicdn.com/t/font_6fwsxglzew154s4i.css">
  <style>
    html,
    body {
      margin: 0px;
      padding: 0px;
      height: 100%;
    }

  </style>
</head>

<body>
  <div id="app"></div>
  <!-- built files will be auto injected -->
</body>

</html>

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import router from './router'

Vue.config.productionTip = false

Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: {
    App
  }
})

App.vue

<template>
  <div id="app">
    <!--左侧导航-->
    <LeftNav></LeftNav>
  
    <div class="main">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
import LeftNav from '@/components/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;
  color: #2c3e50;
  height: 100%;
}

.main {
  float: left;
  width: 95%;
  height: 100%;
  overflow: auto;
}
</style>

index.js

import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/components/Main'

Vue.use(Router)

export default new Router({
  routes: [{
    path: '/',
    name: 'main',
    component: Main
  }]
})

项目打包

注意事项:
打开 config/index.js 会看到一个 build 属性,这里就是我们打包的基本配置。你在这里可以修改打包的目录,文件名。最重要的是一定要把绝对路径改为相对路径。

assetsPublicPath: '/'

改为

assetsPublicPath: './'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 前几天,在德国通过同性恋婚姻合法化的法案的同时,我们国家通过了一篇《通则》。 通则中有一条:不得展示非正常的性关系...
    向你扔了个柿子的强强阅读 947评论 2 7
  • 又到了必须对着电脑发呆的学期末。 在自习室的门口听到了两个女生在打招呼,“最近过得好吗?”“我想我很焦虑,哈哈哈。...
    柚君子阅读 452评论 0 0
  • 成长? 一点点的改变,一点点的思考,一点点的挣扎。 心,存在既也不存在。 用心,尽所能而为。 有天有地,直起脊背。...
    了尽阅读 162评论 0 0
  • 各位看官们,请先下手...... 或者这个....... 看到以上两张图片我想你一定很熟悉,但它们只是众多中的两个...
    橘子侠阅读 761评论 1 4
  • 现在各种反鸡汤语录层出不穷,让我突然觉得,我以前到底都喝了些什么,是不是毒药啊?细思极恐啊。 什么是心灵鸡汤?就是...
    余美鱼阅读 625评论 0 0