Vue实战——快餐店收银系统

作者: 9979eb0cd854 | 来源:发表于2018-08-11 17:45 被阅读0次

    用到的技术栈:Vue+Webpack+Element+Axios+vueRouter

    Mockplus前端画草图软件:
    下载地址:https://www.mockplus.cn/
    把快餐店收银系统的架构用Mockplus画出来,如下:

    image.png
    image.png

    项目正式开始

    一:Vue-cli搭建开发环境

    具体做法步骤“
    1、项目采用Webpack+Vue-router的架构方式,开始安装
    按Win+R,然后在文本框中输入cmd,回车打开命令行,输入vue-cli安装命令

    mpm install vue-cli -g
    

    这里的-g代表全局安装
    2、在命令行中初始化项目,我们采用的是webpack模板,输入初始化命令:

    vue init webpack AwesomePos
    

    3、这里的AwesmonePos是我的项目文件夹名称,你可以起一个自己喜欢的名称。安装时根据项目需要配置所需要的模块。这里有一个小技巧,就是在你已经提前建立好了文件夹的时候,我们也进入了文件夹,这时候我们可以省略这个文件夹名称。如下情况:

    mikdir AwesomePos
    cd AwesomePos
    vue init webpack
    

    3、在命令行中,进入项目目录,使用npm install 安装package.json里项目的依赖包。如果你网速较慢的话,可以使用淘宝镜像的cnpm来进行安装。
    4、查看是否安装正确。在命令行中输入 npm run dev ,如果能在浏览器中正常打开页面,说明安装正确。
    到这里为止,我们的项目架构就建立好了,我们需要对Vue-cli给我们生成的文件进行一些必要的修改。

    二: 修改项目文件内容:

    1、修改根目录下的index.html文件,我们想写一些CSS样式,这样作是为了更好的布局,然后修改一下标题栏。让标题符合项目这里起名叫“AwesomePOS-快餐店管理系统”。index.html修改后内容如下。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>AwesomePOS-快餐管理系统</title>
        <style>
          html,
          body,
          #app {
            height:100%;
            padding: 0;
            margin:0;
            }
        </style>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
    

    2、新建Pos组件,这个相当于程序员的入口文件。在src/components目录下新建Pos.vue文件。文件内容写出vue模板的架构就可以。

    <template>
        <div class="pos">
             Hello Pos Demo!
        </div>
    </template>
    
    <script>
        export default {
            name: 'Pos'
        }
    </script>
    
    <style>
    </style>
    

    3、修改路由文件,项目根目录/src/router/index.js,让入口文件变成Pos组件。
    先用import引入了Pos模板组件,然后修改routes里边的内容。

    import Vue from 'vue'
    import Router from 'vue-router'
    import Pos from '@/components/Pos'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Pos',
          component: Pos
        }
      ]
    })
    
    

    5、这时候看一下浏览器中的网页,如果显示出了Hello Pos Demo.我们就算成功搭建项目架构了


    image.png

    三:搞定项目图标Iconfont

    挑选图标的过程(共6步)
    1、进入网站:Iconfont网址:http://www.iconfont.cn

    image.png
    2、点击网站上方的“官方图标库”,选择自己喜欢的图标。在这里我选择天猫的图标库。
    image.png
    3、选择好自己喜欢的图标,你可以有两个选择,下载代码添加至项目
    4、我们这两选择添加至项目,然后新建项目,并输入名称。
    image.png
    image.png
    image.png

    5、项目添加好后,会自动给我们转入到我们项目库中。点击查看在线链接。
    6、生产css引入的代码,生成后就可以在项目首页index.html引入了。

    <link rel="stylesheet" href="http://at.alicdn.com/t/font_717905_r0c14h3jzqm.css"/>
    
    image.png
    使用图标
    image.png
    图标生成
    image.png

    添加更多图标:

    如果在项目中觉的图标不够用了,需要添加更多图标。可以利用下面四步进行添加。

    1、去Iconfont网站继续挑选,把相中的图标加入购物车中。
    2、把购物车中的图标加入到项目中。
    3、重新生成在线链接。(这部很重要
    4、在项目主页中(index.html),更换css引入链接。

    四:编写独立的侧边栏导航组件

    建立leftNav.vue文件:
    我们在src/components目录下,先新建一个common和page文件夹。

    common文件夹用来放共用组件,下面写的leftNav.vue组件就放到这里。
    page文件夹用来放我们的页面模板组件,页面的模板文件放到这里。
    在common文件夹下,新建leftNav.vue文件。

    开始动手写代码:
    建立好文件后,先给components来个基本组件结构。

    <template>
      <div class="left-nav">
        
      </div>
    </template>
     
    <script>
    export default {
      name: 'leftNav',
      data () {
        return {
        }
      }
    }
    </script>
    <style>
     
    </style>
    

    开始写html结构,我们用列表li来代表导航。菜单栏有收银、店铺、商品、会员、统计。我们编写的html结构如下:

    <ul>
            <li>
                <i class="icon iconfont icon-wodezichan"></i>
                <div>收银</div>
            </li>
     
            <li>
                <i class="icon iconfont icon-dianpu"></i>
                <div>店铺</div>
            </li>
     
            <li>
                <i class="icon iconfont icon-hanbao"></i>
                <div>商品</div>
            </li>
     
             <li>
                <i class="icon iconfont icon-huiyuanqia"></i>
                <div>会员</div>
            </li>
     
     
            <li>
                <i class="icon iconfont icon-tongji"></i>
                <div>统计</div>
            </li>
    </ul>
    

    components(组件)基本结构写好后,开始动手写CSS样式,让我们的组件变的好看。

    <style>
        .left-nav{
           color:#fff;
           font-size:10px;
           height:100%;
           background-color: #1D8ce0;
           float:left;
           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>
    

    编写完CSS样式,这个组件算是大体写好了,以后根据需求我们会在组件里添加<route-link>标签。但是现在还没有这个需求,所以暂时不添加。
    把leftNav组件放到模板中
    先用import在App.vue中引入leftNav组件。

    import leftNav from '@/components/common/leftNav'
    

    引入后在vue的构造器里添加components属性,并放入我们的leftNav组件。

    export default {
      name: 'app',
      components:{
        leftNav
      }
    }
    

    这样组件就算在也页面引入成功了,接下来我们就可以在<template>区域里愉快的使用它(<leftNav></leftNav>)。

    <template>
      <div id="app">
        <!--左侧导航-->
        
            <leftNav></leftNav>
        
        <!--操作区域-->
        <div class="main">
          <router-view></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: left;
      color: #2c3e50;
       height:100%;
    }
     
    .main{
      float:left;
      width:95%; 
      background-color: #EFF2F7;
      height:100%;
      overflow: auto;
     
    }
    </style>
    

    预览效果

    image.png

    五:项目中用到Element组件库

    Element官网地址:http://element-cn.eleme.io/#/zh-CN

    image.png
    1、安装Element-ui,打开终端输入以下命令,如下:
    npm安装
    这里使用npm的方式安装,它能更好地和webpack打包工具配合使用。
    npm install element-ui --save
    
    image.png
    image.png
    完整引入项目
    在main.js中写入以下内容:
    image.png
    用Element的el-row的布个局
    安装好,先做个简单的布局小试牛刀,这里作两栏布局,Element支持用24栏的形式进行布局。

    在Pos.vue里添加模版布局:

    <template>
      <div class="pos">
        <div>
            <el-row >
                <el-col :span='7'>
                我是订单栏
                </el-col>
                <!--商品展示-->
                <el-col :span="17">
                 我是产品栏
                </el-col>
            </el-row>
        </div>
      </div>
    </template>
     
    <script>
    export default {
      name: 'Pos',
      data () {
        return { 
        }
      }
    }
    </script>
    <style scoped>
    </style>
    

    解决100%高的问题
    在页面中使用了Element组件,这样他会自动给我们生产虚拟DOM,我们无法设置高度100%;

    这时候可以利用javascript,来设置100%高度问题。先要给我们的<el-col>标签上添加一个id,我们这里把ID设置为

    order-list。然后在vue构造器里使用mounted钩子函数来设置高度。

    <script>
    export default {
       name: 'Pos',
       mounted:function(){
          var orderHeight=document.body.clientHeight;
          document.getElementById("order-list").style.height=orderHeight+'px';
      },
    }
    

    效果

    image.png
    利用Element快速布局(1)
    el-tabs标签页组件

    用Element里提供的el-tabs组件可以快速制作我们的tabs标签页效果,具体使用方法可以到Element的官网查看API。

    基本用法很简单,可以直接在模板中引入<el-tabs>标签,标签里边用<el-tab-pane>来代表每个每个标签页。

    先看一个最简单的代码:

    <el-tabs>
          <el-tab-pane label="点餐">
           点餐   
          </el-tab-pane>
          <el-tab-pane label="挂单">
          挂单
          </el-tab-pane>
          <el-tab-pane label="外卖">
          外卖
         </el-tab-pane>
    </el-tabs>
    

    看到每个<el-tab-pane>里会有一个label属性,这个属性就是你标签页的标题。内容可以直接写在<el-tab-pane>里。
    el-table组件制作表格
    需要在订单的tab标签页里放入表格,把点选的食品放入到待结账列表里,可以使用Element的内置组件el-table。

    <el-table :data="tableData" border show-summary 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 scope="scope">
                <el-button type="text" size="small">删除</el-button>
                <el-button type="text" size="small">增加</el-button>
     
            </template>
        </el-table-column>
    </el-table>
    

    这里我们采用了五列布表格, 在第1行中的:data是用来绑定数据源的, border代表表格有边框效果。
    tableData中的数据源的值,为了布局方便,所以我进行了写死,以后会改成动态添加的数据

    tableData: [{
              
              goodsName: '可口可乐',
              price: 8,
              count:1
            }, {
              
              goodsName: '香辣鸡腿堡',
              price: 15,
              count:1
            }, {
             
              goodsName: '爱心薯条',
              price: 8,
              count:1
            }, {
             
              goodsName: '甜筒',
              price: 8,
              count:1
            }]
    

    el-button 按钮组件
    需要在点餐表格的下方放入三个功能性按钮,分别是挂单按钮、删除按钮、结账按钮。同样使用Element里的组件,进行快速写入。el-button 的type属性是设置按钮样式的,为了学些和区分我这里用三个属性来设置按钮。

    <el-button type="warning" >挂单</el-button>
    <el-button type="danger" >删除</el-button>
    <el-button type="success" >结账</el-button>
    

    可以预览一下

    image.png
    左边最重要的订单操作区域就布局完成了。
    利用Element快速布局(2)完成布局右侧的商品布局
    常用商品区域布局:
    在<el-col :span=17>标签里增加一个层,然后在层内进行布局。因为里边的商品实际意义上是列表,所以用无序列表<li>来布局商品。贴出布局的html代码。
    <div class="often-goods">
        <div class="title">常用商品</div>
        <div class="often-goods-list">
     
            <ul>
                <li>
                    <span>香辣鸡腿堡</span>
                    <span class="o-price">¥15元</span>
                </li>
     
            </ul>
        </div>
    </div>
    

    有了基本html结构后,需要增加一些css样式来美化页面:

    .title{
           height: 20px;
           border-bottom:1px solid #D3DCE6;
           background-color: #F9FAFC;
           padding:10px;
       }
       .often-goods-list ul li{
          list-style: none;
          float:left;
          border:1px solid #E5E9F2;
          padding:10px;
          margin:5px;
          background-color:#fff;
       }
      .o-price{
          color:#58B7FF; 
       }
    

    在Vue的构造器里临时加一个数组,用作常用商品使用。声明的变量叫oftenGoods(真实项目不能这样起名字,这里只是练习使用)。

    oftenGoods:[
              {
                  goodsId:1,
                  goodsName:'香辣鸡腿堡',
                  price:18
              }, {
                  goodsId:2,
                  goodsName:'田园鸡腿堡',
                  price:15
              }, {
                  goodsId:3,
                  goodsName:'和风汉堡',
                  price:15
              }, {
                  goodsId:4,
                  goodsName:'快乐全家桶',
                  price:80
              }, {
                  goodsId:5,
                  goodsName:'脆皮炸鸡腿',
                  price:10
              }, {
                  goodsId:6,
                  goodsName:'魔法鸡块',
                  price:20
              }, {
                  goodsId:7,
                  goodsName:'可乐大杯',
                  price:10
              }, {
                  goodsId:8,
                  goodsName:'雪顶咖啡',
                  price:18
              }, {
                  goodsId:9,
                  goodsName:'大块鸡米花',
                  price:15
              }, {
                  goodsId:20,
                  goodsName:'香脆鸡柳',
                  price:17
              }
              
          ]
    

    预览效果

    image.png
    有了数据,可以使用v-for循环来输出到html模板中。
    商品分类布局:
    在下半部分先添加一个tabs的标签样式。
    <div class="goods-type">
     
        <el-tabs>
            <el-tab-pane label="汉堡">
                汉堡
            </el-tab-pane>
                <el-tab-pane label="小食">
                小食
            </el-tab-pane>
            <el-tab-pane label="饮料">
                饮料
            </el-tab-pane>
            <el-tab-pane label="套餐">
                套餐
            </el-tab-pane>
     
        </el-tabs>
    </div>
    

    制作商品的无序列表:

    <ul class='cookList'>
        <li>
            <span class="foodImg"><img src="http://7xjyw1.com1.z0.glb.clouddn.com/pos001.jpg" width="100%"></span>
            <span class="foodName">香辣鸡腿堡</span>
            <span class="foodPrice">¥20.00元</span>
        </li>
    </ul>
    

    对无序列表进行CSS样式编写:

    .cookList li{
           list-style: none;
           width:23%;
           border:1px solid #E5E9F2;
           height: auot;
           overflow: hidden;
           background-color:#fff;
           padding: 2px;
           float:left;
           margin: 2px;
     
       }
       .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;
       }
    

    有了基本的样式,就可以在Vue的构造器里添加汉堡类的数据。声明一个type0Goods的数据,数据格式如下。

     type0Goods:[
              {
                  goodsId:1,
                  goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos001.jpg",
                  goodsName:'香辣鸡腿堡',
                  price:18
              }, {
                  goodsId:2,
                  goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos002.jpg",
                  goodsName:'田园鸡腿堡',
                  price:15
              }, {
                  goodsId:3,
                  goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos004.jpg",
                  goodsName:'和风汉堡',
                  price:15
              }, {
                  goodsId:4,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos003.jpg",
                  goodsName:'快乐全家桶',
                  price:80
              }, {
                  goodsId:5,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos003.jpg",
                  goodsName:'脆皮炸鸡腿',
                  price:10
              }, {
                  goodsId:6,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos004.jpg",
                  goodsName:'魔法鸡块',
                  price:20
              }, {
                  goodsId:7,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos001.jpg",
                  goodsName:'可乐大杯',
                  price:10
              }, {
                  goodsId:8,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos003.jpg",
                  goodsName:'雪顶咖啡',
                  price:18
              }, {
                  goodsId:9,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos002.jpg",
                  goodsName:'大块鸡米花',
                  price:15
              }, {
                  goodsId:20,
                   goodsImg:"http://7xjyw1.com1.z0.glb.clouddn.com/pos002.jpg",
                  goodsName:'香脆鸡柳',
                  price:17
              }
              
          ],
    

    用v-for改造我们的无序列表:

    <li v-for="goods in type0Goods">
        <span class="foodImg"><img :src="goods.goodsImg" width="100%"></span>
        <span class="foodName">{{goods.goodsName}}</span>
        <span class="foodPrice">¥{{goods.price}}元</span>
    </li>
    

    预览的效果

    image.png

    六:Axios从远程读取数据(从后端拉取数据)

    安装Axios
    使用npm install来进行安装。

    npm install axios --save
    

    由于axios是需要打包到生产环境中的,所以使用–save来进行安装。
    引入Axios
    我们在Pos.vue页面引入Axios,由于使用了npm来进行安装,所以这里不需要填写路径。

    import axios from 'axios'
    

    服务端拉取常用商品数据

    远端服务器地址:http://jspang.com/DemoApi/oftenGoods.php
    (在实际项目中这个后台接口地址是后端程序员提供给你的,你可以随便调用这个接口,我已经放到服务器上了。)
    可以先把地址放到地址栏访问一下,是可以正常访问的,并且输出了json格式的字符串,这就是需要的远端数据了。这里使用Axios的get 方式来获得数据。

    image.png

    第一步:创建created构造函数

    created(){
          axios.get('http://jspang.com/DemoApi/oftenGoods.php')
          .then(response=>{
             console.log(response);
             this.oftenGoods=response.data;
          })
          .catch(error=>{
              console.log(error);
              alert('网络错误,不能访问');
          })
      },
    

    把axios的方法写到了created钩子函数中,我们使用了get 方法进行拉取数据,如果拉取成功用远端数据对oftenGoods进行赋值。

    拉取报错,一般有两种情况:

    1、网络不通:网络状况不是很好,这可以在失败后隔5秒再次请求。
    2、报决绝访问:这种多是后端程序员设置了不允许跨域访问,需要你和后端程序员一起调试解决。
    拉取分类商品数据:
    远端服务器地址:http://jspang.com/DemoApi/typeGoods.php

    依然用Get进行拉取,拉取后先用consoe.log(response)查看一下数据结构,让后进行赋值。由于知识跟上边的很像,文字版我就不多描述了,详细可以查看视频教程。

    在这里贴出拉取和分配不同分类代码:

      //读取分类商品列表
          axios.get('http://jspang.com/DemoApi/typeGoods.php')
          .then(response=>{
             console.log(response);
             //this.oftenGoods=response.data;
             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('网络错误,不能访问');
          })
    

    html模板输出代码:

    <ul class='cookList'>
         <li v-for="goods in type3Goods">
             <span class="foodImg"><img :src="goods.goodsImg" width="100%"></span>
             <span class="foodName">{{goods.goodsName}}</span>
             <span class="foodPrice">¥{{goods.price}}元</span>
          </li>
    </ul>
    

    项目代码一览

    html

    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>AwesomePOS-快餐管理系统</title>
        <link rel="stylesheet" href="http://at.alicdn.com/t/font_wyhhdpv5lhvbzkt9.css">
        <style>
          html,body,#app{height:100%;padding: 0;margin:0;}
        </style>
      </head>
      <body >
         
                      
                    
        <div id="app" ></div>
        <!-- built files will be auto injected -->
        
      </body>
    
    </html>
    
    

    components>>common>>leftNav.vue

    <template>
      <div class="left-nav">
        <ul>
            <li>
                <i class="icon iconfont icon-wodezichan"></i>
                <div>收银</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-dianpu"></i>
                <div>店铺</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-hanbao"></i>
                <div>商品</div>
            </li>
    
             <li>
                <i class="icon iconfont icon-huiyuanqia"></i>
                <div>会员</div>
            </li>
    
             <li>
                <i class="icon iconfont icon-shijian"></i>
                <div>抢购</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-tongji"></i>
                <div>统计</div>
            </li>
    
    ·
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Main',
      data () {
        return {
          
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
        .left-nav{
           color:#fff;
           font-size:10px;
           height:100%;
           background-color: #1D8ce0;
           float:left;
           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>
    
    

    components>>page>>Pos.vue

    <template>
        <div class="pos">
            <div>
                <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 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">
                                    <small>数量:</small>
                                    <strong>{{totalCount}}</strong> &nbsp;&nbsp;&nbsp;&nbsp;
                                    <small>总计:</small>
                                    <strong>{{totalMoney}}</strong> 元
                                </div>
        
                                <div class="order-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="often-goods">
                            <div class="title">常用商品</div>
                            <div class="often-goods-list">
        
                                <ul>
                                    <li v-for="goods in oftenGoods" @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="汉堡">
                                    <ul class='cookList'>
        
                                        <li v-for="goods in type0Goods" @click="addOrderList(goods)">
                                            <span class="foodImg">
                                                <img :src="goods.goodsImg" 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 type1Goods" @click="addOrderList(goods)">
                                            <span class="foodImg">
                                                <img :src="goods.goodsImg" 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" @click="addOrderList(goods)">
                                            <span class="foodImg">
                                                <img :src="goods.goodsImg" 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" @click="addOrderList(goods)">
                                            <span class="foodImg">
                                                <img :src="goods.goodsImg" 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>
        </div>
    </template>
    
    <script>
    import axios from 'axios';
    export default {
        name: 'Pos',
        mounted: function () {
            var orderHeight = document.body.clientHeight;
            document.getElementById("order-list").style.height = orderHeight + 'px';
        },
        created() {
            //读取常用商品列表
            axios.get('http://jspang.com/DemoApi/oftenGoods.php')
                .then(response => {
                    //console.log(response);
                    this.oftenGoods = response.data;
                })
                .catch(error => {
                    console.log(error);
                    alert('网络错误,不能访问');
                })
            //读取分类商品列表
            axios.get('http://jspang.com/DemoApi/typeGoods.php')
                .then(response => {
                    //console.log(response);
                    //this.oftenGoods=response.data;
                    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('网络错误,不能访问');
                })
        },
        data() {
            return {
                tableData: [], //订单列表的值
                oftenGoods: [],
                type0Goods: [],
                type1Goods: [],
                type2Goods: [],
                type3Goods: [],
                totalMoney: 0, //订单总价格
                totalCount: 0  //订单商品总数量
    
            }
        },
        methods: {
            //添加订单列表的方法
            addOrderList(goods) {
                //console.log(goods);
                this.totalCount = 0; //汇总数量清0
                this.totalMoney = 0;
                let isHave = false;
                //判断是否这个商品已经存在于订单列表
                for (let i = 0; i < this.tableData.length; i++) {
                    console.log(this.tableData[i].goodsId);
                    if (this.tableData[i].goodsId == goods.goodsId) {
    
                        isHave = true; //存在
    
                    }
                }
                //根据isHave的值判断订单列表中是否已经有此商品
                if (isHave) {
                    //存在就进行数量添加
                    let arr = this.tableData.filter(o => o.goodsId == goods.goodsId);
                    arr[0].count++;
                    //console.log(arr);
                } else {
                    //不存在就推入数组
                    let newGoods = { goodsId: goods.goodsId, goodsName: goods.goodsName, price: goods.price, count: 1 };
                    this.tableData.push(newGoods);
    
                }
    
                this.getAllMoney();
            },
            //删除单个商品
            delSingleGoods(goods) {
                console.log(goods);
                this.tableData = this.tableData.filter(o => o.goodsId != goods.goodsId);
                this.getAllMoney();
    
            },
            //删除所有商品
            delAllGoods() {
                this.tableData = [];
                this.totalCount = 0;
                this.totalMoney = 0;
            },
            //汇总数量和金额
            getAllMoney() {
                this.totalCount = 0;
                this.totalMoney = 0;
                if (this.tableData) {
                    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 scoped>
    .pos {
        font-size: 12px;
    }
    
    .pos-order {
    
        background-color: #F9FAFC;
        border-right: 1px solid #C0CCDA;
    }
    
    .order-btn {
        margin-top: 10px;
        text-align: center;
    }
    
    .title {
        height: 20px;
        border-bottom: 1px solid #D3DCE6;
        background-color: #F9FAFC;
        padding: 10px;
    }
    
    .often-goods-list ul li {
        list-style: none;
        float: left;
        border: 1px solid #E5E9F2;
        padding: 10px;
        margin: 5px;
        background-color: #fff;
        cursor: pointer;
    }
    
    .goods-type {
        clear: both;
    }
    
    .o-price {
        color: #58B7FF;
    }
    
    .often-goods-list {
        border-bottom: 1px solid #C0CCDA;
        height: auto;
        overflow: hidden;
        padding-bottom: 10px;
        background-color: #F9FAFC;
    }
    
    .cookList li {
        list-style: none;
        width: 23%;
        border: 1px solid #E5E9F2;
        height: auot;
        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 {
        height: auot;
        overflow: hidden;
        text-align: right;
        font-size: 16px;
        background-color: #fff;
        border-bottom: 1px solid #E5E9F2;
        padding: 10px;
    }
    </style>
    
    

    components>>page>>Main.vue

    <template>
      <div class="main">
        
      </div>
    </template>
    
    <script>
    export default {
      name: 'Main',
      data () {
        return {
          
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    
    </style>
    
    

    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
        }
      ]
    })
    
    

    router>>App.vue

    <template>
      <div id="app">
        <!--左侧导航-->
        
            <leftNav></leftNav>
        
        <!--操作区域-->
        <div class="main">
          <router-view></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: left;
      color: #2c3e50;
       height:100%;
    }
    
    .main{
      float:left;
      width:95%; 
      background-color: #EFF2F7;
      height:100%;
      overflow: auto;
    
    }
    </style>
    
    

    router>>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 router from './router'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-default/index.css'
    
    Vue.config.productionTip = false;
    Vue.use(ElementUI);
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    })
    
    

    整个项目的结构:

    image.png

    六:项目打包上线

    打包注意事项:
    1、把绝对路径改为相对路径

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


    image.png

    这样才能保证我们打包出去的项目可以正常预览。

    2、在命令行中用npm run build 进行打包。

    npm run build
    

    相关文章

      网友评论

        本文标题:Vue实战——快餐店收银系统

        本文链接:https://www.haomeiwen.com/subject/qeqdbftx.html