先简单看下效果图:(在原先基础上添加了删除和筛选操作)

代码:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>购物车</title>
<!--rel 属性指示被链接的文档是一个样式表,说白了就是指明你链进来的对象是个什么-->
<link href="bootstrap.min.css" type="text/css" rel="stylesheet">
<style type="text/css">
button{
outline: none;
}
</style>
</head>
<body>
<!--
container布局容器
Bootstrap 需要为页面内容和栅格系统包裹一个 .container 容器。提供了两个作此用处的类。注意,由于 padding 等属性的原因,这两种 容器类不能互相嵌套。
、container 类用于固定宽度并支持响应式布局的容器。、.container-fluid 类用于 % 宽度,占据全部视口(viewport)的容器。
-->
<div id="app" class="container">
<h1>购物车</h1>
<hr>
<btn-grp></btn-grp>
<br>
<br>
<table class="table table-bordered table-striped table-hover">
<tr>
<td><input type="checkbox" v-on:click="selectAll" name="selectAllBtn"/></td>
<th>ID</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>商品总价</th>
</tr>
<tr v-for="(product,index) in products">
<td>
<input type="checkbox" v-on:click="checkItem(product)" v-model="product.state" name="checkbox" />
</td>
<td>{{index+}}</td>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>
<!--可以将两个按钮的方法合成一个,通过传参-->
<!--<button @click="changeCount(prod, -1)">-</button>-->
<button @click="cutCount(product)" class="btn btn-default btn-sm">-</button>
<input type="number" v-model="product.count"/>
<!--<button @click="changeCount(prod, 1)">-</button>-->
<button @click="addCount(product)" class="btn btn-default btn-sm">+</button>
</td>
<td>{{product.price * product.count}}</td>
</tr>
<tr>
<!--text-right排版文本右对齐-->
<td colspan="" class="text-right">总价:</td>
<!--text-primary辅助类文本-->
<td class="text-primary">{{totalMoney}}</td>
<!--方法调用:<td class="text-primary">{{getTotalMoney()}}</td>-->
</tr>
</table>
</div>
<script type="application/javascript" src="vue-2.6.9.min.js"></script>
<script type="application/javascript">
Vue.component('btn-grp',{
props:['button'],
//btn-group:基本的按钮组。在 .btn-group 中放置一系列带有 class .btn 的按钮。
// role="group"按钮组合
template:`
<div style="overflow: hidden">
<div class="btn-group" role="group" style="float:left;">
<button type="button"
v-for="button in buttons"
v-bind:class="\'btn \'+button.class"
v-on:click="button.handler"
>{{button.title}}</button>
</div>
<div style="float:right;">
<input class="form-control"
v-model="searchProduct"
@keyup.enter="filterProduct"
type="text"
placeholder="请输入商品名称"/>
</div>
</div>
`,
data:function(){
return{
searchProduct:'',
buttons:[
{title:'添加',class:'btn-primary',handler:function(){alert('点击添加按钮')}},
{title:'修改',class:'btn-default',handler:function(){alert('点击修改按钮')}},
{title:'删除',class:'btn-default',handler:function(){
for(let i =;i<app.products.length;i++){
if(app.products[i].state){
app.products.splice(i,);
i--;
}
};
/* 全选按钮状态清空 */
document.querySelectorAll('input[name="selectAllBtn"]')[].checked = false;
}}
]
}
},
methods:{
/* 商品筛选 */
filterProduct:function(){
var searchArr = [];
for(let i=;i<app.products.length;i++){
searchArr.push(app.products[i].name)
}
var searchIndex = searchArr.indexOf(this.searchProduct);
if(searchIndex !== -){
app.products = app.products.filter(function(element, index, self){
/* element数组元素、index元素索引、self数组本身 */
return index == searchIndex;
})
}
}
}
})
var app = new Vue({
el:'#app',
data:{
products: [
{
name: '小米6S',
price: ,
count: ,
state:false
},
{
name: '锤子2',
price: ,
count: ,
state:false
},
{
name: '华为P20',
price: ,
count: ,
state:false
},
{
name: 'OPPO R15',
price: ,
count: ,
state:false
},
{
name: 'OPPO R11',
price: ,
count: ,
state:false
},
],
searchProduct:''
},
methods:{
// 用户点击加减数量时调用
cutCount:function(product){
if(product.count>){
product.count--
}else{
alert('商品数量不能小于0')
}
},
addCount:function(product){
product.count++
},
/*
用户点击加减数量时调用通过传参合并为一个函数
changeCount: function(prod, num) {
if(num < 0) {
if(prod.count > 0) {
prod.count += num;
}
}
else {
prod.count += num;
}
},
*/
/*获取总价除了计算属性也可以用方法
getTotalMoney: function() {
var totalMoney = 0.0;
for(var i = 0; i < this.products.length; ++i) {
totalMoney += parseFloat(this.products[i].price * this.products[i].count);
}
return totalMoney;
}
*/
checkItem:function(product){
product.state = !product.state;
},
selectAll:function() {
var checkObj = document.querySelectorAll('input[name="checkbox"]'); // 获取所有checkbox项
if (event.target.checked) {
// 点击全选事件
for (var i = ; i < checkObj.length; i++) {
checkObj[i].checked = true;//选中样式
app.products[i].state = true;//动态改变值,供删除用
}
} else {
for (var i = ; i < checkObj.length; i++) {
checkObj[i].checked = false;
app.products[i].state = false;
}
}
}
},
computed:{
totalMoney:function(){
var price = ;
for(var i = ; i < this.products.length; ++i) {
price += parseFloat(this.products[i].price * this.products[i].count);
}
return price;
}
}
})
</script>
</body>
</html>

修该:props传值

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>购物车</title>
<!--rel 属性指示被链接的文档是一个样式表,说白了就是指明你链进来的对象是个什么-->
<link href="bootstrap.min.css" type="text/css" rel="stylesheet">
<style type="text/css">
button{
outline: none;
}
</style>
</head>
<body>
<!--
container布局容器
Bootstrap 需要为页面内容和栅格系统包裹一个 .container 容器。提供了两个作此用处的类。注意,由于 padding 等属性的原因,这两种 容器类不能互相嵌套。
、container 类用于固定宽度并支持响应式布局的容器。、.container-fluid 类用于 % 宽度,占据全部视口(viewport)的容器。
-->
<div id="app" class="container">
<h1>购物车</h1>
<hr>
<btn-grp v-bind:buttons="buttons"></btn-grp>
<br>
<br>
<table class="table table-bordered table-striped table-hover">
<tr>
<td><input type="checkbox" v-on:click="selectAll" name="selectAllBtn"/></td>
<th>ID</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>商品总价</th>
</tr>
<tr v-for="(product,index) in products">
<td>
<input type="checkbox" v-on:click="checkItem(product)" v-model="product.state" name="checkbox" />
</td>
<td>{{index+}}</td>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>
<!--可以将两个按钮的方法合成一个,通过传参-->
<!--<button @click="changeCount(prod, -1)">-</button>-->
<button @click="cutCount(product)" class="btn btn-default btn-sm">-</button>
<input type="number" v-model="product.count"/>
<!--<button @click="changeCount(prod, 1)">-</button>-->
<button @click="addCount(product)" class="btn btn-default btn-sm">+</button>
</td>
<td>{{product.price * product.count}}</td>
</tr>
<tr>
<!--text-right排版文本右对齐-->
<td colspan="" class="text-right">总价:</td>
<!--text-primary辅助类文本-->
<td class="text-primary">{{totalMoney}}</td>
<!--方法调用:<td class="text-primary">{{getTotalMoney()}}</td>-->
</tr>
</table>
</div>
<script type="application/javascript" src="vue-2.6.9.min.js"></script>
<script type="application/javascript">
Vue.component('btn-grp',{
props:['buttons'],
//btn-group:基本的按钮组。在 .btn-group 中放置一系列带有 class .btn 的按钮。
// role="group"按钮组合
template:`
<div style="overflow: hidden">
<div class="btn-group" role="group" style="float:left;">
<button type="button"
v-for="button in buttons"
v-bind:class="\'btn \'+button.class"
v-on:click="button.handler"
>{{button.title}}</button>
</div>
<div style="float:right;">
<input class="form-control"
v-model="searchProduct"
@keyup.enter="filterProduct"
type="text"
placeholder="请输入商品名称"/>
</div>
</div>
`,
data:function(){
return{
searchProduct:''
}
},
methods:{
/* 商品筛选 */
filterProduct:function(){
var searchArr = [];
for(let i=;i<app.products.length;i++){
searchArr.push(app.products[i].name)
}
var searchIndex = searchArr.indexOf(this.searchProduct);
if(searchIndex !== -){
app.products = app.products.filter(function(element, index, self){
/* element数组元素、index元素索引、self数组本身 */
return index == searchIndex;
})
}else{
alert('暂无符合商品');
}
}
}
})
var app = new Vue({
el:'#app',
data:{
products: [
{
name: '小米6S',
price: ,
count: ,
state:false
},
{
name: '锤子2',
price: ,
count: ,
state:false
},
{
name: '华为P20',
price: ,
count: ,
state:false
},
{
name: 'OPPO R15',
price: ,
count: ,
state:false
},
{
name: 'OPPO R11',
price: ,
count: ,
state:false
},
],
searchProduct:'',
buttons:[
{title:'添加',class:'btn-primary',handler:function(){alert('点击添加按钮')}},
{title:'修改',class:'btn-default',handler:function(){alert('点击修改按钮')}},
{title:'删除',class:'btn-default',handler:function(){
for(let i =;i<app.products.length;i++){
if(app.products[i].state){
app.products.splice(i,);
i--;
}
};
/* 全选按钮状态清空 */
document.querySelectorAll('input[name="selectAllBtn"]')[].checked = false;
}}
]
},
methods:{
// 用户点击加减数量时调用
cutCount:function(product){
if(product.count>){
product.count--
}else{
alert('商品数量不能小于0')
}
},
addCount:function(product){
product.count++
},
/*
用户点击加减数量时调用通过传参合并为一个函数
changeCount: function(prod, num) {
if(num < 0) {
if(prod.count > 0) {
prod.count += num;
}
}
else {
prod.count += num;
}
},
*/
/*获取总价除了计算属性也可以用方法
getTotalMoney: function() {
var totalMoney = 0.0;
for(var i = 0; i < this.products.length; ++i) {
totalMoney += parseFloat(this.products[i].price * this.products[i].count);
}
return totalMoney;
}
*/
checkItem:function(product){
product.state = !product.state;
},
selectAll:function() {
var checkObj = document.querySelectorAll('input[name="checkbox"]'); // 获取所有checkbox项
if (event.target.checked) {
// 点击全选事件
for (var i = ; i < checkObj.length; i++) {
checkObj[i].checked = true;//选中样式
app.products[i].state = true;//动态改变值,供删除用
}
} else {
for (var i = ; i < checkObj.length; i++) {
checkObj[i].checked = false;
app.products[i].state = false;
}
}
}
},
computed:{
totalMoney:function(){
var price = ;
for(var i = ; i < this.products.length; ++i) {
price += parseFloat(this.products[i].price * this.products[i].count);
}
return price;
}
}
})
</script>
</body>
</html>

.

Vue+Bootstrap实现购物车程序(2)的更多相关文章

  1. Vue+Bootstrap实现购物车程序(3)

    效果展示:(说明:使用webpack重构购物车程序,使用vue-cli生成项目脚手架) 文件结构: 代码: (1)将原来编写的btn-grp组件单独编写到BtnGrp.vue文件中 可以看到现在代码清 ...

  2. Vue+Bootstrap实现购物车程序(1)

    先看下案例效果:(简单的数量控制及价格运算) 代码: <!DOCTYPE html> <html> <head lang="en"> <m ...

  3. vue.js实现购物车功能

    购物车是电商必备的功能,可以让用户一次性购买多个商品,常见的购物车实现方式有如下几种: 1. 用户更新购物车里的商品后,页面自动刷新. 2. 使用局部刷新功能,服务器端返回整个购物车的页面html 3 ...

  4. 基于 Vue BootStrap的迷你Chrome插件

    代码地址如下:http://www.demodashi.com/demo/14306.html 安装 安装 Visual Studio Code 和Chrome, 自行FQ 详细安装这里略过 安装包管 ...

  5. 用vue.js实现购物车功能

    购物车是电商必备的功能,可以让用户一次性购买多个商品,常见的购物车实现方式有如下几种: 1. 用户更新购物车里的商品后,页面自动刷新. 2. 使用局部刷新功能,服务器端返回整个购物车的页面html 3 ...

  6. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  7. 简单购物车程序(Python)

    #简单购物车程序:money_all=0tag=Trueshop_car=[]shop_info={'apple':10,'tesla':100000,'mac':3000,'lenovo':3000 ...

  8. vue项目向小程序迁移调研

    概述 今天调研了一下vue项目怎么向小程序迁移,有些心得,记录下来,供以后开发时参考,相信对其他人也有用. 基本上vue项目向小程序迁移不外乎2种方法,一种是用小程序的web-view组件,另一种是用 ...

  9. python学习:购物车程序

    购物车程序 product_list = [ ('mac',9000), ('kindle',800), ('tesla',900000), ('python book',105), ('bike', ...

随机推荐

  1. Java抽象类和接口的区别(好长时间没看这种文章了)

    Java抽象类和接口的区别(好长时间没看这种文章了) abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的 ...

  2. 并不对劲的字符串专题(二):kmp

    据说这些并不对劲的内容是<信息学奥赛一本通提高篇>的配套练习. 先感叹一句<信息学奥赛一本通提高篇>上对kmp的解释和matrix67的博客相似度99%(还抄错了),莫非mat ...

  3. 动态点分治入门 ZJOI2007 捉迷藏

    传送门 这道题好神奇啊……如果要是不带修改的话那就是普通的点分治了,每次维护子树中距离次大值和最大值去更新. 不过这题要修改,而且还改500000次,总不能每改一次都点分治一次吧. 所以我们来认识一个 ...

  4. bzoj2916

    容斥原理 计蒜客比赛day2t3的简化版 总数-异色三角形 对于每个点考虑,每个点红线数量为d[i],那么以这个点为顶点的异色三角形有d[i]*(n-1-d[i]),每条红线和蓝线成一个异色三角形,一 ...

  5. Bootstrap标签页

    用法 您可以通过以下两种方式启用标签页: 通过 data 属性:您需要添加 data-toggle="tab" 或 data-toggle="pill" 到锚文 ...

  6. 09_传智播客iOS视频教程_自动释放池与NSLog函数

    不要管什么是自动释放池,现在给你讲你也听不懂.就业班才讲,不要知道太多,知道太多对你不好.电影里面死的最惨的人就是知道最多的人.把代码写到自动释放池里面就可以了.NSLog是printf的增强版,它增 ...

  7. 【插件开发】—— 4 SWT编程须知

    根据前两篇博文,应该对插件开发有所了解. 前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 SWT知识介绍 之前学过Java的朋友,多少页会一些关于Swi ...

  8. Uix Kit 快速建站前端开发套件-工具箱

    这个产品维护已经有一年了(由于业务需求不同,目前没有做中文版,产品本身是针对国外网站),自己本身是做UI出生,开发只是业余爱好,仅仅作为平时工作的需要.杂七杂八会一些前后端开发.并非职业码农! 我是一 ...

  9. IP地址简单入门

    ------------------------针对网络地址相关的小白,最快速接触网络知识------------------------- 可以使用python自带的模块IPy,进行处理IP地址或I ...

  10. poj 2299 Ultra-QuickSort 归并排序求逆序数对

    题目链接: http://poj.org/problem?id=2299 题目描述: 给一个有n(n<=500000)个数的杂乱序列,问:如果用冒泡排序,把这n个数排成升序,需要交换几次? 解题 ...