Vue项目—Supermall移动端购物商城
Posted weixin_45392774
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue项目—Supermall移动端购物商城相关的知识,希望对你有一定的参考价值。
目录
4.2 css文件的引入:base.css normalize.css
4.5 创建vue.config.js文件,给项目目录起别名,便于开发
一、项目描述
基于Vue全家桶构建的移动端购物商城,页面共分为:首页,详情页,分类页,购物车页面和个人信息页
gitee地址:https://gitee.com/mgslsdt/supermall
1.1 如何运行
# 克隆
git clone https://gitee.com/mgslsdt/supermall.git
# 打开项目目录
cd supermall
# 安装依赖
npm install
# 开启本地服务运行项目
npm run serve
1.2 项目演示
二、项目页面及功能
Home商城首页:
NavBar
利用具名插槽实现三栏布局- 利用
axios
进行服务端通讯获取接口数据Swiper
轮播图组件TabControl
控制商品列表展示TabControl
标签吸顶- backTop利用scrollTo返回顶部
- 封装第三方库
better-scroll
,处理商品列表滚动- 利用
mixin
混入添加防抖函数debounce
商品详情页:
- 根据id获取商品数据保存并展示
- 封装工具函数
utils.js
进行时间格式化- 实现标题和内容的联动效果,既点击标题滚动到对应的主题内容(反之亦可)
- 封装
Toast
弹窗插件
购物车页面:
CheckButton
商品全选按钮
Vuex
对购物车进行状态管理(总计金额与商品相关联,购物车总数与去计算数据更新 )Vue.js
组件复用
三、项目技术栈
Vue.js
+ Vue Router
+ Vuex
+ axios
Vue CLI3快速搭建Vue开发环境以及对应的webpack配置;
Vue-router完成页面的跳转及部分数据的传递;
Vuex完成多个页面之间的状态管理
axios请求页面所需要的数据
四、准备工作
4.1 利用脚手架3创建项目开发环境,并划分目录结构;
4.2 css文件的引入:base.css normalize.css
4.3 项目的模块划分:tabbar -> 路由映射关系
<template>
<div id="app">
<keep-alive exclude="Detail">
<router-view></router-view>
</keep-alive>
<main-tab-bar></main-tab-bar>
</div>
</template>
4.4 小图标的修改
4.5 创建vue.config.js文件,给项目目录起别名,便于开发
五、功能点代码梳理
5.0 总体框架
tabbar+路由组件映射
main-tab-bar=>tab-bar=>tab-bar-item依次调用组件
- 路由组件对应
效果
5.1 首页开发
开发原则:保证首页逻辑简单清晰,有必要封装组件
5.1.1 首页导航栏的封装与使用
封装公共navbar组件,利用具名插槽实现组件复用(home,deatil,cart)
<template>
<div class="nav-bar">
<div class="left"><slot name="left"></slot></div>
<div class="center"><slot name="center"></slot></div>
<div class="right"><slot name="right"></slot></div>
</div>
</template>
<script>
export default {
name: "NavBar"
}
</script>
<style scoped>
.nav-bar {
display: flex;
height: 44px;
line-height: 44px;
text-align: center;
color: #fff;
box-shadow: 0 1px 1px rgba(100,100,100,.1);
}
.left,.right{
width: 60px;
}
.center{
flex: 1;
}
</style>
购物街使用center插槽
效果
5.1.2 请求首页多个数据
- 安装axios
- 创建axios实例
- 发送网络请求
- network新建home.js 返回首页数据请求
- 拿到数据
- vue结果验证
5.1.3 Swiper
轮播图组件展示
- 组件轮播图的实现:
Swiper
、SwiperItem
- 轮播组件使用
HomeSwiper
、DetailSwiper
- home.vue中使用
HomeSwiper组件
,初始化banners,并传入数据banners
效果
5.1.4 推荐信息展示
- homeComps下新建文件 recommendView.vue
展示组件,并传入从服务端获取的数据
效果
5.1.5 FeatureView的封装
- childComps下新建文件FeatureView.vue文件
- div>a>img
效果
5.1.6 首页商品数据的请求
- 先设计数据结构用于保存数据
- 发送数据请求
- 在home.js中封装getHomeGoods(type,page)
2. 在home.vue中,又在methods中getHomeGoods(type),通过调用this.getHomeGoods('pop')、this.getHomeGoods('new') 、this.getHomeGoods('sell'),
- 动态获取对应的page
- 获取到数据:res
-
this.goods[type].list.push(...res.data.list) this.goods[type].page += 1
结果:
goods:{
pop:page1/list[30]
new:page1/list[30]
sell:page1/list[30]
}
5.1.8 首页商品数据的展示
- 封装Goodlist.vue组件
- 封装Goodlistitem.vue组件
5.1.9 TabControl组件封装与切换商品
- props->titles
- div->根据titles v-for遍历div->span{{title}}
- css相关
- 选中哪一个tab,哪一个tab文字颜色变色,下面border-bottom
- 借助currentindex
对tab-control组件进行点击监控,要把所点击index传入到父组件home.vue,在home中根据index切换商品类型
5.1.10 对滚动进行重构- BScroll的封装和使用
原生scroll卡顿,且无法回弹,故使用封装后的bscroll,丝滑可回弹,content必须要有高度
- 对better-scroll进行封装:Scroll.vue
- Home.vue和Scroll.vue之间进行通信
- Home.vue将probeType设置为3
- Scroll.vue需要通过$emit,实时将事件发送到home.vue
- 中间content高度计算方法
5.1.11 回到顶部- Backtop组件的封装和使用
- 如何监听组件的点击?直接监听不可以,必须添加.native修饰符
- 点击回到顶部 this.$refs.scroll.scrollTo(0,0,500)
5.1.12 BackTop的显示和隐藏
- isShowBackTop : false
- 监听滚动,拿到滚动的位置
- 通过v-show决定标识是否被显示
5.1.13 上拉加载更多
pullUpLoad默认值是false
此处,pullUpLoad并没有给死,首页传递true,pullUpLoad就是true
5.1.14 tab-control的吸顶效果
思路:必须要知道向上滚动多少时,开始有吸顶效果=>获取到tabControl的offsetTop
踩坑:组件没有offsetTop,但所有组件都有一个属性$el:用于获取组件中的元素
直接在mounted中获取tabControl的offsetTop(console.log(this.$refs.tabControl.$el.offsetTop)这里获取不够准确,可能图片还没有加载完,故等轮播图加载完再获取
监听HomeSwiper中img的加载完成
加载完成后,发出事件,在home.vue中,获取正确的值
补充:为了不让HomeSwiper多次发出事件,可以使用isLoad的变量进行状态的记录
原本思路是让tabControl向上移动到一定程度,设置fixed固定定位。
但在动态改变tabControl的样式时,会出现两个问题
1.下面商品会突然上移(因为fixed脱标)
2.tabControl虽然设置了fixed但也跟着better-scroll一起上移
故采用在nav-bar底下多复制一份PlaceHolderTabControl组件对象,利用它来实现停留效果。
当用户滚动到一定位置,PlaceHolderTabControl显示
当用户滚动没有达到一定位置,PlaceHolderTabControl隐藏
这里要注意两个tabControl点击index还没有保持一致
措施:区分两个ref 在tabClick修改对应的currentIndex
此时,吸顶效果完成
5.1.13 Home离开时记录状态和位置
让Home不要随意销毁掉
- 每次离开home,数据都会被销毁 无法保存
措施:加keep-alive 但再次返回home页面 之前浏览位置记忆被消除,是bscroll的原因
措施:
- 每次离开home前保留y值,
- 再回到home时让页面滚动到之前的y值
- 为防止无法拖动,再次进行刷新
5.2 详情页开发
5.2.1 详情页数据获取并展示
- 新建Detail文件并配置路由关系
- GoodsListItem点击事件
- 点击之后获取商品IID,跳转详情页,并传入iid
- 根据id请求商品其余数据并展示
- 推荐数据获取并展示
详情页引用各个组件,具体各个组件见代码
- 在商品基本信息展示板块需要注意:当后端传递过来海量数据 数据获取并不统一,而是来自3个不同的对象
- 解决思路:把3个对象数据整合成一个对象数据(创建类-一个对象),传给组件,让组件面向这一个对象开发
5.2.2 顶部标题Detailnavbar实现
点击标题,对应高亮显示
5.2.3 顶部标题与页面内容的联动效果
- 点击标题,页面滚动到对应位置
themeTopYs[index] 里面的数据从哪里获取是个问题
以下是在Deatail----created中
函数调用放在图片加载完成后(等待图片加载完后,值才是正确的)
但图片加载后会出现多次回调,为提高性能,采用防抖
滚动到对应主题:获取所有主题的offsetTop
问题:哪里才能获取到正确的offsetTop?
- 1.created肯定不行,压根不能获取元素
- 2.mounted也不行,数据还没有获取到
- 3.获取到数据的回调中也不行,DOM还没有渲染完
- 4.$nextTick也不行(对应dom已经被渲染,但是图片依然没有加载完成),因为图片的高度没有被计算在内
最后,在图片加载完后,获取的高度才是正确
结果 在图片加载完后实现一次回调,同时可实现标题和页面内容上下联动
2、内容滚动,显示正确的标题
5.2.4 底部工具栏的封装
5.2.5 详情页返回顶部
仿照home返回顶部,同样的组件复制两遍,因此可将两个组件公共代码进行抽取放在mixin中
公共组件引入detail和home
5.2.6 点击加入购物车
保存需要存储到购物车的数据,此处用到vuex进行状态管理
1.获取购物车需要展示的商品信息
2.把商品添加到购物车--用到Vuex
利用vuex对状态进行保管,可以实现购物车相关数据在多个界面进行共享
安装vuex store中新建index.js
mutation需要进一步判断
验证结果:
- mutations唯一目的就是修改state中状态
- mtations中每个方法尽可能完成事件单一一点
Vuex中,有异步操作和复杂逻辑的建议放在action中修改state,便于后期对mutions直接跟踪和后期维护。
结果虽然原本简单的代码可能会被修改的稍微复杂,但在复杂大项目中优势比较明显
- 接下来需要对vuex进行重构
代码修改
1.把mutation中内容转移到actions中
2.之前mutation中一个方法判断两个情况,现在mutations中内容进行分情况处理(counter++,addtocart),在大项目中便于追踪
分开前
分开后
当前,是把state,mutations,actions全放在一起,因此还可以进一步重构
actions
mutations
indexs重组后
综上,重构体现在两个地方
1.mutation中之前一个操作通过actions分成两个操作,让mutation保持每种方法只办一件事
2.把index.js中state,mutations,actions进行分离,让代码看起来更简洁
5.2.7 封装工具函数utils.js进行时间格式化
5.3 购物车页面
5.3.1 购物车列表展示
CartListItem=》CartList=》cart
5.3.2 单选按钮CheckButton
以上是关于Vue项目—Supermall移动端购物商城的主要内容,如果未能解决你的问题,请参考以下文章