vue使用组件化思想实现一个简单的购物车页面

文章目录

  • vue使用组件化思想实现一个简单的购物车页面
    • 页面预览
    • 项目结构
    • 组件介绍
    • 主页面ShopCar
    • Header组件
    • Goods组件
    • Count组件
    • Bottom组件
    • eventBus.js

页面预览

项目结构

组件介绍

主页面ShopCar

  • 主要负责获取商品数据、渲染数据到相应组件
  • 将所有商品的选中状态传递给子组件Bottom
  • 计算出已经勾选商品的总价格,将其传递给子组件Bottom
  • 计算出已经勾选商品的总数量,将其传递给子组件Bottom

<template><div class="wrap"><!-- 头部 --><Header></Header><!-- 商品栏 --><Goods v-for="item in list" :key="item.id" :index="item.id" :title="item.shopDesc" :pic="item.imgSrc" :price="item.price" :status="item.status" :count="item.num"@status-change="getNewStatus"></Goods><div class="bottom"><Bottom :checked="allState" :allPrice="amount" :total="total" @all-change="getFullStatus" ></Bottom></div></div>
</template>
<script>
import Header from '../components/Header.vue';
import Goods from '../components/Goods.vue'
import Bottom from '../components/Bottom.vue';
import bus from '../components/eventBus'
export default {components:{Header,Bottom,Goods},data(){return{status:false,list:[{id:"01", status:true  ,imgSrc:'https://img.alicdn.com/imgextra/i4/14219353/O1CN0145jVEE2Ixj4WfGyOx_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',shopDesc:'焕伊美宽松休闲F晒服外套女2022年新款夏季洋气百',price:'388.6',num:1},{id:"02", status:true,imgSrc:'https://img.alicdn.com/imgextra/i1/30603673/O1CN01AjV6XY1d0HKGpaEJt_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',shopDesc:'七小铺潮牌设计感拼接条纹韩版卫衣女2022年春秋',price:'379.8',num:1},{id:"03", status:true,imgSrc:'https://img.alicdn.com/imgextra/i3/14219353/O1CN01ZKUntQ2Ixj4fJ4U1r_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',shopDesc:'姿派女孩夏季镂空钩花遮晒衣女2022年新款夏装薄',price:'458.65',num:1},{id:"04", status:true,imgSrc:'https://img.alicdn.com/imgextra/i4/30301515/O1CN01qME9In1N3ultkxD54_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',shopDesc:'汐颜洋气衬衣女时尚短袖雪纺衬衫2022春季新款女',price:'418.69',num:2},{id:"05", status:true,imgSrc:'https://img.alicdn.com/imgextra/i3/25431444/O1CN01NMvc931MXOZtzfxjN_!!0-saturn_solar.jpg_468x468q75.jpg_.webp',shopDesc:'NENW复古港味上衣韩版宽松白色衬衫女2022新款',price:'398.12',num:1}]}},computed:{// 已勾选商品的总数量total(){return this.list.filter(item=> item.status).reduce((total,item)=>(total += item.num),0)},// 计算全选的状态allState(){return this.list.every(item =>item.status);},// 计算所有商品的价格amount(){return this.list.filter(item =>item.status).reduce((total,item)=>{return total += parseFloat(item.price) * parseInt(item.num);},0)}},methods:{// 接收子组件传递过来的全选状态getFullStatus(e){// console.log(e);this.list.forEach(item=>{item.status = e;})},// 接收子组件传递过来的数据getNewStatus(e){this.list.some(item =>{if(item.id == e.id){item.status = e.value;}})}},created(){bus.$on('share',(val)=>{this.list.some(item =>{if(item.id === val.id){item.num = val.value;return true}})})}
}
</script>
<style lang="scss" scoped>
.wrap{text-align: left;
}
</style>

Header组件

<template><div class="wrap"><div class="text"><span>购物车</span></div></div>
</template>
<script>
export default {}
</script>
<style lang="scss" scoped>
.wrap{.text{width: 750px;height: 48px;background-color: rgb(12, 144, 239);text-align: center;margin: 0 auto;span{color: #fff;font-size: 18px;line-height: 48px;font-weight: bold;}}
}
</style>

Goods组件

  • 主要负责获取父组件ShopCar的数据,并动态渲染出来
  • 勾选状态发生变化时通过自定义事件向父组件传值
<template><div class="wrap"><div class="goods-wrap"><!-- 左侧多选框 --><div class="check"><input  type="checkbox" :id="index" :checked="status" @change="stastusChange"><label for="id"></label></div><!-- 右侧商品信息 --><div class="goods-contain"><!-- 图片容器 --><div class="img-wrap"><a href=""><img :src="pic" alt=""></a></div><!-- 商品描述 --><div class="shop-desc-wrap"><!-- 商品描述 --><p class="desc">{{title}}</p><!-- 价格 --><p class="price">¥{{price}}</p><div class="button"><Count :shopnum="count" :id="index"></Count></div></div></div>  </div></div>
</template>
<script>
import Count from './Count.vue';
export default {components:{Count,},props:{// 商品购买数量count:{type:Number,default:1,},// keyindex:{require:true,type:String},// 商品描述title:{default:'',type:String,},// 图片pic:{default:'',type:String,},// 商品价格price:{default:'0',type:String,},// 状态status:{default:true,type:Boolean}},data(){return{}},methods:{stastusChange(e){// console.log(e.target.id);// console.log(e.target.checked);this.$emit('status-change',{id:e.target.id,value:e.target.checked})}}
}
</script><style lang="scss" scoped>
.wrap{.goods-wrap{border-radius: 8px;display: flex;margin: 0 auto;width: 750px;height: 200px;margin: 8px auto;background-color: rgb(236, 230, 230);.check{width: calc(750px - 95%);line-height: 200px;text-align: center;}.goods-contain{width: 95%;height: 100%;display: flex;.img-wrap{width: 200px;height: 100%;display: flex;align-items: center;a{  width: 200px;height: 200px; overflow: hidden;}img{width: 200px;height: 200px; }}.shop-desc-wrap{margin: 18px 0 0 12px;flex-grow: 1;position: relative;.desc{font-size: 16px;color: #333;}.price{margin-top: 12px;color: #f00;font-size: 36px;font-weight: bold;}.button{position: absolute;right: 22px;bottom: 22px;}} }}
}
</style>

Count组件

  • 负责对商品数量的控制
<template><div class="button"><button @click="sub">-</button><span v-text="shopnum"></span><button @click="add">+</button></div>
</template>
<script>
import bus from './eventBus';
export default {props:{//商品数量shopnum:{type:Number,default:1,},id:{require:true,type:String}},data(){return{}},methods:{add(){const obj = {id:this.id,value:this.shopnum +1}bus.$emit('share',obj);},sub(){if(this.shopnum -1 == 0){return}const obj = {id:this.id,value:this.shopnum -1}bus.$emit('share',obj);}}}
</script><style lang="scss" scoped>
.button{display: flex;button{cursor: pointer;width: 34px;height: 30px;margin: 0 6px;font-size: 16px;background-color: transparent;border: none;}span{display: inline-block;height: 30px;width: 32px;line-height: 30px;text-align: center;background-color: #fff;}button:hover{background-color: rgb(227, 105, 105);}button:active{border: 1px solid #333;background-color: rgb(227, 105, 105);}
}
</style>

Bottom组件

  • 将选中商品的价格与数量动态计算后展示出来
  • 将全选的checked值传递给父元素
<template><div class="wrap"><!-- 全选 --><div class="checkAll"><input type="checkbox" id="cheakAll" :checked="checked" @change="allchange"><label for="cheakAll">全选</label></div><!-- 价格 --><div class="price"><span>合计:</span><span>¥{{allPrice.toFixed(2)}}</span></div><!-- 结算按钮 --><div class="submit"><span>结算({{total}})</span></div></div>
</template><script>
export default {props:{// 已勾选的商品数量total:{type:Number,default:0,},// 所有价格allPrice:{type:Number,default:0},// 全选状态checked:{type:Boolean,default:true}},data(){return{}},methods:{// 监听全选状态变化allchange(e){this.$emit('all-change',e.target.checked)}}
}
</script>
<style lang="scss" scoped>
.wrap{width: 750px;height: 58px;margin: 0 auto;background-color: rgb(206, 208, 210);display: flex;justify-content: space-around;align-items: center;font-size: 18px;font-weight: bold;.checkAll{input{width: 16px;height: 16px;border-radius: 50%;}label{text-align: middle;}}.price{span:last-child{color: red;font-size: 26px;}}.submit{width:120px;height: 48px;border-radius: 12px;text-align: center;line-height: 48px;background-color: rgb(28, 142, 187);cursor: pointer;}.submit:hover{background-color: rgb(11, 186, 255);}.submit:active{border: 1px solid rgb(0, 0, 0);}
}
</style>

eventBus.js

  • 里面就是一个vue示例,用于兄弟组件或者祖孙组件之间的通信
  • 数据发送方通过调用$emit()方法想接收方发送数据
  • 数据接收方通过调用$on()方法接收数据

vue使用组件化思想实现一个简单的购物车页面相关推荐

  1. 组件化思想+Vue路由_day09

    1.组件化思想 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件就可以了 1.1组件化步骤 组件化步骤: 1 ...

  2. Vue.js组件化开发实践

    Vue.js组件化开发实践 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了一下的内容.首先会对使用Vue进行开发的一 ...

  3. Vue.js 组件化开发

    三.组件化开发 1.1 组件化的实现和使用步骤 组件注册步骤解析 1.2 全局组件和局部组件 1.3 父组件和子组件 1.4 注册组件语法糖 1.5 组件模板抽离的写法 1.6 组件数据存放 1.7 ...

  4. 第三天:Vue的组件化

    1.认识组件化 我们将一个完整的页面分成很多个组件,每个组件都用于实现页面的一个功能块,而每一个组件又可以进行细分. 组件化是Vuejs中的重要思想,它提供了一种抽象,让我们可以开发出一个个独立可复用 ...

  5. 利用webpack和vue实现组件化

    原文链接:http://mrzhang123.github.io/2016/06/02/webpack-vue-3/ 本文基于vue1.x 基于vue2.x&webpack2.x请移步至 Vu ...

  6. 基于layui的框架模版,采用模块化设计,接口分离,组件化思想

    代码地址如下: http://www.demodashi.com/demo/13362.html 1. 准备工作 编辑器vscode,需要安装liveServer插件在前端开启静态服务器 或者使用hb ...

  7. 前端组件化思想与实践

    前端组件化思想与实践 组件化思想 什么是组件化? 简单的说组件就是:将一段UI样式和其对应的功能作为独立的整体去看待,无论这个整体放在哪里去使用,它都具有一样的功能和样式,从而实现复用,这种整体化的思 ...

  8. 使用Unity3D的设计思想实现一个简单的C#赛车游戏场景

    最近看了看一个C#游戏开发的公开课,在该公开课中使用面向对象思想与Unity3D游戏开发思想结合的方式,对一个简单的赛车游戏场景进行了实现.原本在C#中很方便地就可以完成的一个小场景,使用Unity3 ...

  9. 【数据挖掘】数据挖掘算法 组件化思想 示例分析 ( 组件化思想 | Apriori 算法 | K-means 算法 | ID3 算法 )

    文章目录 一. 数据挖掘算法组件化思想 二. Apriori 算法 ( 关联分析算法 ) 三. K-means 算法 ( 聚类分析算法 ) 四. ID3 算法 ( 决策树算法 ) 一. 数据挖掘算法组 ...

最新文章

  1. 《人件集》阅读笔记第一篇
  2. 全栈工程师15年经验分享:40个改变编程技能的小技巧
  3. 【深度】北大王奕森:对抗机器学习的鲁棒、隐私和架构
  4. 香槟分校计算机科学排名,伊利诺伊大学厄巴纳-香槟分校计算机科学与工程世界排名2020年最新排名第42(ARWU世界排名)...
  5. mysql导入sas文件夹_MYSQL导出HTML格式数据如何导入到SAS中
  6. 区块链100讲:EOS环境搭建入门(私链节点-钱包-密钥-账号)
  7. 光模块功能失效的原因有哪些?
  8. ORA-12514: TNS:监听程序当前无法识别连接描述符中请(转)
  9. 美团外卖客户端高可用建设体系
  10. Hive Shell
  11. c 语言自行实现字符串常用库函数_学习c语言的7本书——你知道吗?
  12. linux设备驱动模型及其他,Linux设备驱动模型
  13. 如何选型商业智能和分析平台,Gartner给了这些建议!
  14. 使用反射复制一个JavaBean的对象
  15. Android HAL(硬件抽象层)介绍以及调用
  16. j2me解决模拟器乱码
  17. php日历天气预报下载安装手机桌面_日历天气预报下载安装app_手机桌面时钟日历天气软件下载 安卓版 V7.5.1 - 罐头安卓网...
  18. Rabbitmq取消预取机制配置,配置手动确认后仍然java.lang.IllegalStateException: Channel closed; cannot ack/nack的问题
  19. Nginx反向代理:多域名跳转多台服务器(研发需求)
  20. 0x0F1AFD76 (libcocos2d.dll) (Plane.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000018 时发生访问冲突。

热门文章

  1. 赵铁安烧饼机器人_六旬老汉耗资发明烧饼机 企业20万欲购被拒
  2. 鸿蒙系统的软件怎么下载,怎么下载鸿蒙系统?
  3. ps作图缩小有锯齿的解决方法
  4. Python中的字符串
  5. 抛物线的几何性质(传统几何法推导)
  6. uiautomator测试中scrollForward方法使用失灵
  7. Hive 统计连续天数
  8. 帧间预测--AMVP模式理论部分
  9. 计算机c盘program,电脑c盘program files(x86)文件夹可以删除吗
  10. “科林明伦杯”哈尔滨理工大学第十届部分题解