项目采用Webpack+Vue-router的架构方式,在命令行中,进入项目目录,使用npm install 安装package.json里项目的依赖包。若是你网速较慢的话,可使用淘宝镜像的cnpm来进行安装。 查看是否安装正确。在命令行中输入 npm run dev ,若是能在浏览器中正常打开页面,说明安装正确。javascript
mkdir myPos
cd myPos
vue init webpack
cnpm install
npm run dev
复制代码
本博客代码所在github:https://github.com/dumingcode/myPos.gitphp
这节课咱们要快速撸一个侧边栏组件出来。组件的做用就是在能够复用,想在那个页面使用均可以,而且像写html标签同样简单。css
咱们在src/components目录下,先新建一个common和page文件夹。html
<template>
<div class="left-nav">
</div>
</template>
<script>
export default {
name: 'leftNav',
data () {
return {
}
}
}
</script>
<style>
</style>
复制代码
开始写html结构,咱们用列表li来表明导航。菜单栏有收银、店铺、商品、会员、统计。咱们编写的html结构以下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-tongji"></i>
<div>统计</div>
</li>
</ul>
</div>
</template>
复制代码
注意:这里你也许和我使用的图标不同,请自行改为你图标用的代码,不要无脑拷贝,图标会显示不出来。java
components(组件)基本结构写好后,开始动手写CSS样式,让咱们的组件变的好看。webpack
<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样式,这个组件算是大致写好了,之后根据需求咱们会在组件里添加标签。可是如今尚未这个需求,因此暂时不添加。ios
把leftNav组件放到模板中,先用import在App.vue中引入leftNav组件。git
import leftNav from '@/components/common/leftNav'
复制代码
引入后在vue的构造器里添加components属性,并放入咱们的leftNav组件github
export default {
name: 'App',
components:{
leftNav
}
}
复制代码
这样组件就算在也页面引入成功了,接下来咱们就能够在<template>
区域里愉快的使用它(<leftNav></leftNav>
)。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>
复制代码
Element是一套为开发者、设计师和产品经理准备的基于Vue2.0的组件库,提供了配套设计资源,帮助你的网站快速成型。其实还有另一套相似的ui组件iview。
cnpm install element-ui --save
// 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.productionTi
Vue.use(ElementUI)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
render: h => h(App),
template: '<App/>'
})
复制代码
以上代码便完成了Element的引入。须要注意的是,样式文件须要单独引入。
3. 用Element的el-row的布局 在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>
复制代码
mounted:function(){
var orderHeight=document.body.clientHeight;
document.getElementById("order-list").style.height=orderHeight+'px';
}
复制代码
1.安装 vetur
2.在User Setting中增长设置:
"vetur.format.defaultFormatter.html": "js-beautify-html"
3.搞定
格式化快捷键:Alt+Shift+F
复制代码
用Element里提供的el-tabs组件能够快速制做咱们的tabs标签页效果,具体使用方法能够到Element的官网查看API。 基本用法很简单,能够直接在模板中引入标签,标签里边用来表明每一个每一个标签页。
<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>
复制代码
须要在点餐的tab标签页里放入表格,把点选的食品放入到待结帐列表里,可使用Element的内置组件el-table。若是你对el-table不了解, 能够去Element官网去查看一下。我这里不做太多的解释,先把代码贴过来,而后根据代码在讲解。
<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
中的值为方便取数,暂时写成固定的,代码以下:
data() {
return {
tableData: [
{
goodsName: "可口可乐",
price: 8,
count: 1
},
{
goodsName: "香辣鸡腿堡",
price: 15,
count: 1
},
{
goodsName: "爱心薯条",
price: 8,
count: 1
},
{
goodsName: "甜筒",
price: 8,
count: 1
}
]
};
}
复制代码
此时能够运行npm run dev
看下运行效果。
须要在点餐表格的下方放入三个功能性按钮,分别是挂单按钮、删除按钮、结帐按钮。一样使用Element里的组件,进行快速写入。el-button 的type属性是设置按钮样式的,为了学些和区分咱们这里用三个属性来设置按钮。
<el-button type="warning" >挂单</el-button>
<el-button type="danger" >删除</el-button>
<el-button type="success" >结帐</el-button>
复制代码
到这里咱们左边最重要的订单操做区域就布局完成了,接下来咱们布局右侧的商品布局。
先给出完成布局以后的页面效果,引用技术胖老师博客的图片。
在<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。for
循环代码以下:
<el-col :span="17">
<div class="often-goods">
<div class="title">经常使用商品</div>
<div v-for="item in oftenGoods" class=" often-goods-list ">
<ul>
<li>
<span>{{ item.goodsName }}</span>
<span class="o-price ">¥{{ item.price }}元</span>
</li>
</ul>
</div>
</div>
</el-col>
复制代码
often-goods
数组代码以下:
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
}
]
复制代码
商品的上半部分就布局完成了,如今须要布局下半部分,咱们在下半部分先添加一个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>
复制代码
<el-tab-pane label="汉堡">
<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>
</el-tab-pane>
复制代码
针对商品无序列表添加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
}
]
复制代码
经过添加循环将静态数据展示到页面上。
<el-tab-pane label="汉堡">
<ul class=" cookList ">
<li v-for="item in type0Goods">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
</ul>
</el-tab-pane>
复制代码
开始学习Axios的知识,并把商品数据从远端读取到页面上。
npm install axios --save
引入Axios,在Pos.vue页面引入Axios,因为使用了npm来进行安装,因此这里不须要填写路径。 import axios from 'axios'
感谢技术胖老师提供的server程序。远端服务器地址:http://jspang.com/DemoApi/oftenGoods.php。使用Axios的get 方式来得到数据,把axios的方法写到了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('网络错误,不能访问');
})
},
复制代码
远端服务器地址:http://jspang.com/DemoApi/typeGoods.php。
//读取分类商品列表
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('网络错误,不能访问');
})
复制代码
页面上里有循环展现商品详情代码以下:
<el-tab-pane label="汉堡">
<ul class=" cookList ">
<li v-for="item in type0Goods">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
</ul>
<ul class=" cookList ">
<li v-for="item in type1Goods">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
</ul>
<ul class=" cookList ">
<li v-for="item in type2Goods">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
</ul>
<ul class=" cookList ">
<li v-for="item in type3Goods">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
</ul>
</el-tab-pane>
复制代码
后面继续学习订单操做里须要的功能,好比点击商品,添加到左边的订单栏里,增长,删除商品,模拟订单提交到后台。
本节要完成的任务是实现页面左侧的订单列表页面的添加操做。
在vue的构造器里加入methods方法,在methods方法里再加入addOrderList方法。这个方法的做用是点击右侧的商品,而后把商品添加到左边的列表里。
addOrderList(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.tableData.forEach(element => {
this.totalCount += element.count;
this.totalMoney = this.totalMoney + element.price * element.count;
});
}
复制代码
在咱们的商品上绑定方法,来进行调用添加方法,增长代码以下:@click="addOrderList(goods)"
。
<li v-for="item in type0Goods" @click="addOrderList(item)">
<span class="foodImg"><img :src="item.goodsImg" width="100%"></span>
<span class="foodName">{{ item.goodsName}}</span>
<span class="foodPrice">¥{{ item.price}}元</span>
</li>
<div v-for="item in oftenGoods" class=" often-goods-list " @click="addOrderList(item)">
<ul>
<li>
<span>{{ item.goodsName }}</span>
<span class="o-price ">¥{{ item.price }}元</span>
</li>
</ul>
</div>
复制代码
商品中绑定addOrderList方法是很是容易的,若是在订单列表中绑定是须要特殊处理一下的,须要用到template的scope值,让后进行绑定。
<el-button type="text" size="small" @click="addOrderList(scope.row)">增长</el-button>
复制代码
在veu构造器methods属性里增长一个delSingleGoods方法,并接收goods对象为参数,用数组的filter能够轻松删除数组中单个的商品。
//删除单个商品
delSingleGoods(goods){
console.log(goods);
this.tableData=this.tableData.filter(o => o.goodsId !=goods.goodsId);
},
复制代码
将统计代码写成一个函数,增长商品或删除商品的时候都会调用。
//汇总数量和金额
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;
});
}
}
复制代码
删除代码html调用实例
<el-button type="text" size="small" @click="delSingleGoods(scope.row)">删除</el-button>
复制代码
此部分代码直接将商品表清空。
//删除全部商品
delAllGoods() {
this.tableData = [];
this.totalCount = 0;
this.totalMoney = 0;
},
复制代码
由于模拟结帐须要Post数据到后台,个人服务器又不能提供这样的借口给你们,因此我只说制做思路,你们能够在本身的服务器上去实现。
一、设置咱们Aixos的Pos方法。
二、接受返回值进行处理。
三、若是成功,清空现有构造器里的tableData,totalMoney,totalCount数据。
四、进行用户的友好提示。
第三步和第四步的方法以下所示:
checkout() {
if (this.totalCount!=0) {
this.tableData = [];
this.totalCount = 0;
this.totalMoney = 0;
this.$message({
message: '结帐成功,感谢你又为店里出了一份力!',
type: 'success'
});
}else{
this.$message.error('不能空结。老板了解你急切的心情!');
}
}
复制代码
文章最后感谢技术胖老师的分享,本文其实是按着老师的blog敲出来的,经过老师的课程初步对vue.js有了了解,后面经过实践慢慢积累经验。