vue 实现一个商城项目

在学习了 vue 之后,决定做一个小练习,仿写了一个有关购物商城的小项目。下面就对项目做一个简单的介绍。

项目源码: github

项目的目录结构

-assets                            与项目有关的静态资源,包括 css,以及一些 images
-common                            公共的工具类方法
-components						   公共组件
-common						     与项目耦合度较低的组件
-content					     与项目耦合度较高的组件
-network						   网络请求相关
-router 						   路由相关
-store							   vuex 相关
-views							   主要展示的页面
-home								首页
-childcomps
-detail								详情页
-childcomps
-cart							    购物车页面
-childcomps
-profile						    个人信息页面
-childcomps

划分好目录结构后就可以对每个模块进行独立开发

主要实现的功能

首页

  1. 顶部轮播图的展示
  2. 中间选项卡点击可进行商品的切换以及吸顶效果
  3. 点击商品进入商品详情页
  4. 上拉展示更多商品
  5. 点击按钮回到顶部

详情页

  1. 根据首页中用户的点击进行每个商品的独立展示
  2. 点击商品信息对应的标题跳转到对应的内容区域
  3. 滑动页面过程中与顶部商品信息的标题联动效果
  4. 点击按钮回到顶部
  5. 加入购物车跳出弹窗

购物车页面

  1. 展示各种商品的数量
  2. 底部工具栏展示选中商品的总价格
  3. 全选与取消全选
  4. 结算时的两种弹窗

我的页面

  1. 个人信息的展示
  2. 点击我的购物车进入到购物车页面

主要思路介绍

底部 tabbar 的封装

移动端中比较常见的一种导航栏,需要根据用户的点击进行跳转到相应的页面,所以直接封装一个公共的组件。布局一般是图片加文字,图片一般有两种,需要根据当前是否处于活跃状态的路由和用户的点击来判断展示哪张。内部预留插槽,用户根据实际需求选择底部导航的个数。每个导航为其配置路由。

顶部导航 navbar 的封装

顶部的导航基本会出现在每个页面中,所以也直接封装为一个公共组件,布局通常是左中右三栏布局,所以组件内部预留三个插槽,采用 flex 布局。

数据请求

对 axios 再封装为一个 request.js 文件,让所有的页面都基于这个文件发送请求,这样做可以避免重复操作,提高了项目后期的可维护性。

在这个项目中将每个页面需要发送请求的部分又进行了一层封装,即每个页面都有独立的与之相对应的发送请求的文件,首页发送请求只需要面向 home.js,详情页发送请求面向 detail.js。

滚动组件 Scroll

  • 引入 better-scroll 来替换掉页面的原生滚动,Scroll.vue 是对 better-scroll 的封装,为了提高组件的可复用性,可以让 probeType, pullUpLoad,等值从外部传入(项目中 click 的值为 true)。
  • Scroll.vue 内代码的封装:
    创建一个 Better-Scroll 对象,传入 DOM 和 参数( probeType,click,pullUpLoad等),
    监听 scroll 事件,该事件会返回一个 position,
    监听 pullUpLoad 事件,表示该事件触发的时候是否上拉加载更多,
    封装一个滚动的方法 this.scroll.scrollTo(x,y,time),
    封装一个刷新的方法 this.scroll.refresh(),会重新计算可滚动区域的高度,
    封装完成上拉加载更多的方法 this.scroll.finishPullUp

全局插件 Toast

  • 项目中有两个地方用到了弹窗组件,一个是点击加入购物车时,一个是点击结算时,如果想要使用弹窗组件那么每次都需要导入还要加一些代码,这样做有点麻烦,如果有多个地方都需要使用这个弹窗组件那么此时需要做的重复工作量太大,所以采用 Vue.use() 方法全局注册了一个插件。
  • 需要在 main.js 中 import, 然后 Vue.use() 进行注册,Vue.use() 需要传入至少一个参数,该参数只能是 Object 或 Function ,如果是 Object 那么这个对象需要定义一个 install 方法,如果是 Funcion 那么这个函数就被当做 install 方法,在 Vue.use() 执行时 install 方法会默认执行,install 方法调用时会将 Vue 作为参数传入。Vue.use() 除了传入第一个参数外,也可继续传入一个选项对象。这里还要注意的是 Vue.use() 必须要在 new Vue() 之前被调用,这是因为在安装组件时,组件给 Vue 添加全局功能,所以必须写在 new Vue() 之前,否则创建的 Vue 实例就无法获取插件添加的全局功能。
  • 所以我们在项目中使用了 Vue.use() 注册了全局插件,在任何地方想使用只需要 this.$名称 即可。

首页

  • 数据处理
    banners 数组保存轮播图的数据,recommends 数组保存推荐的数据。
    还有其它的即需要展示的每一条商品的数据通过 goods 来保存。
    goods: {
    ‘pop’: {page: 0, list: [ ] },
    ‘new’: {page: 0, list: [ ] },
    ‘sell’: {page: 0, list: [ ] }
    }
  • 最上面的轮播图,可以根据图片数量自动进行轮播,也可手动滑动图片,是一个独立的子组件。
    轮播图下面的推荐部分是一个独立的子组件。
  • 对 goods 中的数据进行展示,封装 GoodsList 组件,而每一个商品又是一个独立的小组件 GoodsListItem.vue。
  • 点击选项卡进行数据的切换,监听选项卡的点击事件,通过 $emit() 发出事件(携带 index),在父组件中监听,根据 index 对应的数据类型(swicth(index)),父组件再通过 props 将 currentType 传给 GoodsList 进行展示。
  • 滑动过程中选项卡的吸顶效果,原理是复制一个选项卡(tabControl)在顶部,默认隐藏,通过 v-show 来决定何时出现,用一个变量保存原选项卡 (contentControl) 的 offsetTop,在页面滚动的过程中不断获取滚动的距离,当滚动的距离大于原选项卡 (contentControl) 的 offsetTop时,就显示 tabControl。
  • 上拉加载更多,Scroll 组件中的 pullingUp 一触发就会发送一个事件,父组件中进行监听然后当事件触发的时候去请求数据即可。
  • 回到顶部组件 BackTop,默认不显示,当页面滚动到设定的距离时显示。点击回到顶部需要监听组件的点击(@click.native),然后触发函数 scrollTo(x,y,time) 返回顶部。

详情页

  • 当用户点击商品时进入到详情页,首先要监听每个 GoodsListItem 的点击,点击时进行路由的跳转,并且携带商品的 id,根据 id 请求数据,再将数据进行展示。
  • 底部功能栏的封装也是一个独立的子组件,当点击加入购物车时,将点击事件发送给父组件 detail.vue,父组件中根据商品 id 获取购物车(cart.vue,与 detail.vue 同级)中需要保存的商品数据,提交到 vuex 进行全局状态管理,购物车组件中通过 $store.state 拿到数据进行渲染,加入购物车成功后弹出弹窗提示。
  • 将商品添加到购物车其实有两种情况,一种是 vuex 中还没有这个商品的添加,另一种是 vuex 中已经有了这个商品,所以为了使 mutation 里定义的函数职能单一,这里将点击添加购物车这个操作提交到 action 中管理,再由 action 提交到 mutation 来使 vuex 管理的状态进行更新。
  • 点击联动效果,商品详情页面中共有四个部分组成:商品,参数,评论,推荐,每个部分都是一个独立的子组件,当数据请求完成时去获得每个组件的 offsetTop ($refs.组件绑定的 ref 值.$el.offsetTop) 保存在一个数组中,监听商品详情栏中的点击,根据 index 触发 scrollTo() 进行跳转
  • 滑动联动效果,实时监听滚动位置,通过和上面数组中的值进行比较,在 0 – 参数之间的偏移这个高度时,currentIndex 为 0,在参数的偏移高度 – 评论的偏移高度时 currentIndex 为1,以此类推,这样就可以实现在滑动的过程中与顶部标题信息的联动。
  • 回到顶部,与首页中的一样。

购物车页

  • 渲染在详情页添加到购物车的数据,从 vuex 中拿到数据,封装 CartList 组件,而每一条商品又是一个独立的子组件 CartListItem。
  • 底部工具栏的封装,主要包括全选按钮,选中商品的总价格,去结算时的弹窗。
  • 全选按钮的实现,某商品第一次添加到购物车时,需要给这件商品的数据里定义一个是否选中 (checked)的属性,默认为 true。为了管理选中的状态,只能由 mucation 对状态进行修改,商品最终是否展示也由 mucation 最终修改的状态为准,监听全选按钮的点击,根据商品数组中每个商品的 checked 属性进行逻辑判断即可。
  • 点击去结算组件时,先判断当前购物车的商品列表中是否有数据,如果没有弹出提示信息,让用户选中商品。

我的页面

  • 展示用户的一些个人信息,点击“我的购物车”跳转到购物车页面,this.$router.push(‘/cart’)

项目中遇到的一些问题

博客园精华区
我还没有学会写个人说明!

你也可能喜欢

评论已经被关闭。

插入图片