定义一个局部组件 分成三个部分

Vue.component('my-cart',{
template: `
<div class='cart'>
<cart-title></cart-title>
<cart-list :list='list' @cart-del='delCart($event)'></cart-list>
<cart-total></cart-total>
</div>
`,
components: {
'cart-title': CartTitle,
'cart-list': CartList,
'cart-total': CartTotal
}
});

补全三个子组件

var CartTotal = {
template: `
<div class="total">
<span>总价:123</span>
<button>结算</button>
</div>
`
}

cart 组件需要提供一个数据对象 用于展示数据 包含标题组件和商品的信息

data: function() {
return {
uname: '张三',
list: [{
id: 1,
name: 'TCL彩电',
price: 1000,
num: 1,
img: 'img/a.jpg'
},{
id: 2,
name: '机顶盒',
price: 1000,
num: 1,
img: 'img/b.jpg'
},{
id: 3,
name: '海尔冰箱',
price: 1000,
num: 1,
img: 'img/c.jpg'
},{
id: 4,
name: '小米手机',
price: 1000,
num: 1,
img: 'img/d.jpg'
},{
id: 5,
name: 'PPTV电视',
price: 1000,
num: 2,
img: 'img/e.jpg'
}]
}
},

提供计算总价的组件


var CartTotal = {
props: ['list'],
template: `
<div class="total">
<span>总价:{{total}}</span>
<button>结算</button>
</div>
`,
computed: {
total: function() {
// 计算商品的总价
var t = 0;
this.list.forEach(item => {
t += item.price * item.num;
});
return t;
}
}
}

增加遍历商品的方法

var CartList = {
props: ['list'],
template: `
<div>
<div :key='item.id' v-for='item in list' class="item">
<img :src="item.img"/>
<div class="name">{{item.name}}</div>
<div class="change">
<a href="">-</a>
<input type="text" class="num" />
<a href="">+</a>
</div>
<div class="del" @click='del(item.id)'>×</div>
</div>
</div>
`,
methods: {
del: function(id){
// 把id传递给父组件
this.$emit('cart-del', id);
}
}
}

完成删除部分的逻辑

methods: {
delCart: function(id) {
// 根据id删除list中对应的数据
// 1、找到id所对应数据的索引
var index = this.list.findIndex(item=>{
return item.id == id;
});
// 2、根据索引删除对应数据
this.list.splice(index, 1);
}
}

完成商品数量的变更逻辑 支持加减 和直接输入商品的数量

methods: {
changeNum: function(val) {
// 分为三种情况:输入域变更、加号变更、减号变更
if(val.type=='change') {
// 根据子组件传递过来的数据,跟新list中对应的数据
this.list.some(item=>{
if(item.id == val.id) {
item.num = val.num;
// 终止遍历
return true;
}
});
}else if(val.type=='sub'){
// 减一操作
this.list.some(item=>{
if(item.id == val.id) {
item.num -= 1;
// 终止遍历
return true;
}
});
}else if(val.type=='add'){
// 加一操作
this.list.some(item=>{
if(item.id == val.id) {
item.num += 1;
// 终止遍历
return true;
}
});
}
},
delCart: function(id) {
// 根据id删除list中对应的数据
// 1、找到id所对应数据的索引
var index = this.list.findIndex(item=>{
return item.id == id;
});
// 2、根据索引删除对应数据
this.list.splice(index, 1);
}
}
});

1 标题

2 商品列表

  • 2.1 列表展示

    • 2.1.1 数据以数组的形式展示 包含
  • 2.2 商品数量变更

    • 2.2.1 增加
    • 2.2.2 删除
    • 2.2.3 直接输入商品的数量
  • 2.3 商品删除

    • 2.3.1 删除一行商品的信息

3 结算部分 计算商品的总额

  • 3.1 总价采用计算属性的方式 以便随着商品数量的变更而变化

    • 3.1.1 增加computed 方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.container {
}
.container .cart {
width: 300px;
margin: auto;
}
.container .title {
background-color: lightblue;
height: 40px;
line-height: 40px;
text-align: center;
/*color: #fff;*/
}
.container .total {
background-color: #FFCE46;
height: 50px;
line-height: 50px;
text-align: right;
}
.container .total button {
margin: 0 10px;
background-color: #DC4C40;
height: 35px;
width: 80px;
border: 0;
}
.container .total span {
color: red;
font-weight: bold;
}
.container .item {
height: 55px;
line-height: 55px;
position: relative;
border-top: 1px solid #ADD8E6;
}
.container .item img {
width: 45px;
height: 45px;
margin: 5px;
}
.container .item .name {
position: absolute;
width: 90px;
top: 0;left: 55px;
font-size: 16px;
} .container .item .change {
width: 100px;
position: absolute;
top: 0;
right: 50px;
}
.container .item .change a {
font-size: 20px;
width: 30px;
text-decoration:none;
background-color: lightgray;
vertical-align: middle;
}
.container .item .change .num {
width: 40px;
height: 25px;
}
.container .item .del {
position: absolute;
top: 0;
right: 0px;
width: 40px;
text-align: center;
font-size: 40px;
cursor: pointer;
color: red;
}
.container .item .del:hover {
background-color: orange;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<my-cart></my-cart>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript"> var CartTitle = {
props: ['uname'],
template: `
<div class="title">{{uname}}的商品</div>
`
}
var CartList = {
props: ['list'],
template: `
<div>
<div :key='item.id' v-for='item in list' class="item">
<img :src="item.img"/>
<div class="name">{{item.name}}</div>
<div class="change">
<a href="" @click.prevent='sub(item.id)'>-</a>
<input type="text" class="num" :value='item.num' @blur='changeNum(item.id, $event)'/>
<a href="" @click.prevent='add(item.id)'>+</a>
</div>
<div class="del" @click='del(item.id)'>×</div>
</div>
</div>
`,
methods: {
changeNum: function(id, event){
this.$emit('change-num', {
id: id,
type: 'change',
num: event.target.value
});
},
sub: function(id){
this.$emit('change-num', {
id: id,
type: 'sub'
});
},
add: function(id){
this.$emit('change-num', {
id: id,
type: 'add'
});
},
del: function(id){
// 把id传递给父组件
this.$emit('cart-del', id);
}
}
}
var CartTotal = {
props: ['list'],
template: `
<div class="total">
<span>总价:{{total}}</span>
<button>结算</button>
</div>
`,
computed: {
total: function() {
// 计算商品的总价
var t = 0;
this.list.forEach(item => {
t += item.price * item.num;
});
return t;
}
}
}
Vue.component('my-cart',{
data: function() {
return {
uname: '张三',
list: [{
id: 1,
name: 'TCL彩电',
price: 1000,
num: 1,
img: 'img/a.jpg'
},{
id: 2,
name: '机顶盒',
price: 1000,
num: 1,
img: 'img/b.jpg'
},{
id: 3,
name: '海尔冰箱',
price: 1000,
num: 1,
img: 'img/c.jpg'
},{
id: 4,
name: '小米手机',
price: 1000,
num: 1,
img: 'img/d.jpg'
},{
id: 5,
name: 'PPTV电视',
price: 1000,
num: 2,
img: 'img/e.jpg'
}]
}
},
template: `
<div class='cart'>
<cart-title :uname='uname'></cart-title>
<cart-list :list='list' @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list>
<cart-total :list='list'></cart-total>
</div>
`,
components: {
'cart-title': CartTitle,
'cart-list': CartList,
'cart-total': CartTotal
},
methods: {
changeNum: function(val) {
// 分为三种情况:输入域变更、加号变更、减号变更
if(val.type=='change') {
// 根据子组件传递过来的数据,跟新list中对应的数据
this.list.some(item=>{
if(item.id == val.id) {
item.num = val.num;
// 终止遍历
return true;
}
});
}else if(val.type=='sub'){
// 减一操作
this.list.some(item=>{
if(item.id == val.id) {
item.num -= 1;
// 终止遍历
return true;
}
});
}else if(val.type=='add'){
// 加一操作
this.list.some(item=>{
if(item.id == val.id) {
item.num += 1;
// 终止遍历
return true;
}
});
}
},
delCart: function(id) {
// 根据id删除list中对应的数据
// 1、找到id所对应数据的索引
var index = this.list.findIndex(item=>{
return item.id == id;
});
// 2、根据索引删除对应数据
this.list.splice(index, 1);
}
}
});
var vm = new Vue({
el: '#app',
data: { }
}); </script>
</body>
</html>

vue-购物车的部分的更多相关文章

  1. Vue购物车实例

    <div class="buyCarBox" id="buyCarBox" v-cloak> <div class="haveClo ...

  2. vue 购物车练习

    本人看了vue官网上的教程后,感觉对vue的依稀有点了解,决定动手练习个小功能项目,就找了购物车本项目.原文链接:http://blog.csdn.net/take_dream_as_horse/ar ...

  3. vue购物车和地址选配(三)

    参考资料:vue.js官网 项目演示: 项目源代码: 核心代码及踩坑 删除: new Vue({ el:'#app', data:{ productlist:[], totalMoney:0, che ...

  4. vue购物车功能源码

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  5. Vue购物车

    index.html <!DOCTYPE html><html>    <head>        <meta charset="utf-8&quo ...

  6. VUE购物车示例

    代码下载地址:https://github.com/MengFangui/VueShoppingCart 1.index.html <!DOCTYPE html> <html lan ...

  7. vue购物车的实现

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. vue购物车动画效果

    使用动画的三个函数 v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter=&q ...

  9. 第八十三篇:Vue购物车(四) 总价计算

    好家伙, 1.总价计算 来了,又先是一波分析: 我们用一个计算属性amt 我们把item中被勾选的项用一个过滤器过滤器来 然后用一个循环相加,把商品的价格乘以商品的数量, 把这个总值返回出去, 然后组 ...

  10. 第八十二篇:Vue购物车(三) 实现全选功能

    好家伙, 继续完善购物车相应功能 1.如何实现全选和反全选 1.1.全选框的状态显示(父传子) 来一波合理分析: 在页面中,有三个商品中 三个商品中的第二个未选择, 我么使用一个计算属性(fullSt ...

随机推荐

  1. 运维排查篇 | Linux 连接跟踪表满了怎么处理

    nf_conntrack (在老版本的 Linux 内核中叫 ip_conntrack )是一个内核模块,用于跟踪一个网络连接的状态 一旦内核 netfilter 模块 conntrack 相关参数配 ...

  2. 【C/C++】main函数中的argc和argv

    1.简述argc和argv 当你用命令行执行文件时,可在后面接指令,以控制程序的运行 argc(argument counter)表示指令的数量 argv(argument vector)表示指令向量 ...

  3. CF单机版终极猎手30人版安装教程

    本游戏是CF的单机版本,内含终极猎手30人版,可变身四种终极猎手.这个版本只有这一种模式,没有其他的幽灵模式.生化模式.爆破模式.团队模式等等,如果想玩上述的模式,你可以在其他地方找.值得注意的是这个 ...

  4. 使用PHP自带的过滤验证函数:Filter

    在PHP开发中,大家经常会对提交的表单数据做合法性验证,比如验证Email/IP/URL,大家首先想到的应该是使用正则验证.其实在PHP中已经内置了一个过滤验证函数Filter,大家可以参考一下. P ...

  5. huawei--配置链路聚合

    huawei--配置链路聚合 项目要求: LSW1和LSW2之间配置链路聚合,链路聚合分为手工和lacp两种模式.配置完后查看链路聚合状态. 项目实施: (vlan10 20 30的创建命令vlan ...

  6. 安全测试-WEB安全渗透测试基础知识(五)

    1.5. 代码审计 1.5.1. 简介 代码审计是找到应用缺陷的过程.其通常有白盒.黑盒.灰盒等方式.白盒指通过对源代码的分析找到应用缺陷,黑盒通常不涉及到源代码,多使用模糊测试的方式,而灰盒则是黑白 ...

  7. vue项目,本地启动时,请求地址会自动加上http://localhost:

    wepack设置时,使用代理 devServer: { hot: true, host: '0.0.0.0', port: "2023", // 项目启动端口, 默认8080 // ...

  8. 32位机转化11位手机号以及BLE与USB的切换

    目录 用现有的资源,去实现本应该用更多资源来实现的需求,是一件很有意思的事情.不是说提倡这样使用,而是换一种思路解决问题比较新奇,或是在很多限制既定的情况下可以应急. 比如说,582m芯片,默认用32 ...

  9. Appium+RobotFrameWork测试环境搭建

    前提:搭建好robotframework环境 RF基于python2.7的版本实现的一套开源自动化测试框架 推荐使用Appium Desktop, 搭建Appium环境: 1. 搭建JDK 2. 搭建 ...

  10. Linux Conda 使用activate无法进入环境,但list中有环境的路径

    安装OpenFace时装了个miniconda,之后就进不去anaconda的其它环境了: (pfld) .....$ conda env list # conda environments: # / ...