请添加图片描述

简介:

​ 这是一个基于Vue2实现的一个在线商城部分,部分图如上所示。该项目所用到的数据均为mock模拟,使用的组件部分主要有better-scroll vant2 vue2-verify vue-router vuex axios等等css部分采用less预编译。

目录结构为:
src
    │  App.vue(所有组件的'父亲')
    │  main.js(入口文件)
    │  
    ├─assets(阿里巴巴的iconfont)
    │  └─icon
    │          icon.css
    │          
    ├─common
    │  └─style(混入less以及公共的less)
    │          base.less
    │          mixin.less
    │          
    ├─components(一般组件,用于复用与嵌套)
    │      ListScroll.vue
    │      NavBar.vue
    │      SimpleHeader.vue
    │      Swiper.vue
    │      
    ├─mock(mock模拟数据)
    │      index.js
    │      
    ├─router(包含所有的路由信息)
    │      index.js
    │      
    ├─service(接口封装的异步请求方法)
    │      cart.js
    │      good.js
    │      goods.js
    │      home.js
    │      user.js
    │      useraddr.js
    │      
    ├─store(vuex部分)
    │      actions.js
    │      getters.js
    │      index.js
    │      mutations.js
    │      state.js
    │      
    ├─utils(使用axios拦截器)
    │      axios.js
    │      
    └─views(动态切换页面)
            Address.vue
            AddressEdit.vue
            Cart.vue
            Category.vue
            CreateOrder.vue
            Home.vue
            Login.vue
            ProductDetail.vue
            ProductList.vue
            PullLoading.vue
            User.vue
主要模块
1. 登录注册
2. 个人中心
3. 商城首页
4. 商品分类
5. 购物车,生成订单,地址列表,添加地址等等
功能实现

​ 1. 验证用户名,验证码是否正确

​ 2. 首页轮播图,下拉刷新页面内容

​ 3. 分类页面点击不同导航栏展示不同内容

​ 4. 商品详情页加入购物车

​ 5. 购物车选择功能

​ 6. 地址管理,添加地址,修改默认地址

1. 登陆页

验证部分使用组件vue2-verify,通过不同的type值来展示不同的验证类型。@error/success为验证码错误 / 正确后的操作。showButton默认为true 会显示按钮 ref绑定用户输入数据。

        <div class="verify">
          <Verify
            @error="error"
            @success="success"
            :showButton="false"
            :width="'100%'"
            :height="'40px'"
            font-size="'16px'"
            ref="loginVerifyRef"
            type="1"
          />
        </div>

验证码类型:

1:常规验证码 由数字与字母组成,不区分大小写

2:运算验证码 给出数字的加减乘除,填写运算结果验证

3:滑动验证码 通过简单滑动来完成验证

4:拼图验证码 通过拼图完成验证

5:选字验证码 通过顺序点击汉字完成验证

   // 验证码是否正确的验证方法,上方为登陆验证码
   dealTriVer() {
        // loginType是否是登陆 else为注册
      if (this.loginType) {
        this.$refs.loginVerifyRef.$refs.instance.checkCode();
      } else {
        this.$refs.registerVerifyRef.$refs.instance.checkCode();
      }
    },
2. 首页

上面部分采用轮播图,轮播图使用vant2组件Swipe,SwipeItem,代码如下

        <div class="carousel">
          <van-swipe class="my-swipe" :autoplay="3000" indicator-color="red">
            <van-swipe-item v-for="(item, index) in imgLis" :key="index">
              <img :src="item.carouselUrl" alt="" srcset="" />
            </van-swipe-item>
          </van-swipe>
        </div>

autoplay代表毫秒数,多长时间切换一次。indicator-color表示指示器颜色为红色,小红点部分。真正循环的是item。

补充:想要背景透明而字体不透明可以使用CSS3特性rgba() a为透明度

3. 商品分类页

上部分为搜索框,左侧为导航栏,右侧为导航栏对应的商品展示区。通过点击左侧导航栏的不同部分来切换右侧显示内容,达到动态显示的效果。此处采用判断currentIndex === category.categoryId。作用:首先是点击哪个切换为哪个为active,active是为左侧导航栏设置的样式;其次就是通过判断currentIndex的值来动态渲染右侧内容。

左侧导航栏代码:(categories是mock获取的分类页面数据)

        <div :scrollData="categories" class="nav-side-wrapper">
          <ul class="nav-side">
            <li
              v-for="(category, index) in categories"
              :key="index"
              :class="{ active: currentIndex === category.categoryId }"
              @click="selectMenu(category.categoryId)"
            >
              {{ category.categoryName }}
            </li>
          </ul>
        </div>
// 对应上面@click方法来切换currentIndex的值
selectMenu(id) {
      this.currentIndex = id;
    },

右侧展示部分代码:(通过 v-if 判断来切换内容)

            <template v-for="(category, index) in categories">
              <div
                :key="index"
                class="swiper-container wrapper"
                <!-- v-if  -->
                v-if="currentIndex === category.categoryId"
              >
                <div
                  class="category-list"
                  v-for="(products, index) in category.secondLevelCategory"
                  :key="index"
                >
                  <p class="catogory-title">{{ products.categoryName }}</p>
                  <div
                    class="product-item"
                    v-for="(product, index) in products.thirdLevelCategory"
                    :key="index"
                    @click="selectProduct(product)"
                  >
                    <img
                      src="//s.weituibao.com/1583591077131/%E5%88%86%E7%B1%BB.png"
                      alt=""
                    />
                    <p class="product-title">{{ product.categoryName }}</p>
                  </div>
                </div>
              </div>
            </template>
// 对应上述@click方法    
selectProduct(item) {
      this.$router.push({
        path: "/product",
        query: {
          // 下面说的是这个地方的good
          good: item,
        },
      });
    },
4. 商品详情页:

通过上面selectProduct(item) 方法获取用户点击的商品,以此展示不同商品详情。该方法是通过路由传递参数,使用了query。挂载的时候获取到this.$route.query.good,good就是上面方法的query当中的good拿到路由传过来的数据对象,使用插值语法把数据放到对用位置,来渲染页面。

// 需要在data当中提前定义一个参数good来接收数据
this.good = this.$route.query.good;

添加购物车功能,通过点击添加购物车触发事件,将该数据放到 vuex 当中,vuex当中应提前定义好一个数组用来存放购物车当中的数据,数组名为 cartArr 。有一个细节需要注意,在对象当中创建一个属性时,需要使用set ,例如 添加商品的数量属性Vue.set(good,‘count’,1)这个时候vue是可以检测到变化的。只有Set能被vue检测到。

5. 购物车页面

当购物车页面挂载的时候,通过遍历数组 cartArr 当中的内容来渲染购物车列表。

购物车相关操作:

​ 1. 通过勾选 / 取消,选择需要购买的商品

​ 2. 点击全选选中所有购物车商品,再次点击则为反选,所有商品取消选中

​ 3. 当购物车当中的商品一个个勾选直到全部勾选时,全选也应该勾选

实现方式:

data当中设置一个selectCount,刚开始遍历一遍,如果已经选中则selectCount++。这个时候回拿到一个值,然后判断selectCount的值与cartArr.length是否相等,即可判断是否全选。当不相等的时候,通过用户点击事件,当勾选的时候selectCount++,然后判断是否相等。若是取消勾选,则直接 – 。

商品的加减:当减到0,或者删除商品的时候需要再次遍历数组拿到selectCount与cartArr.length比较。

总价:建议使用vuex当中的getters,getters会根据数组的变化而改变(深度监视,对象当中的count修改也会触发刷新),更方便拿到总价。

6. 生成订单页面

获取getters当中的总价,与vuex当中的cartArr进行遍历,拿到选中的数据进行过滤,然后渲染页面。上面部分是地址栏,通过点击地址栏可以进入到地址栏列表。

7. 地址栏列表页面

首先是挂载的时候通过,mock模拟数据拿到数据,然后渲染页面。底部有按钮来新增地址(数组存储在vuex当中),若新增地址当中默认地址勾选,则该地址设置为默认地址。修改地址,修改vuex当中的数据即可。

8. 个人中心页面

此页面仅需要判断是否登陆,来显示底部按钮为立即登陆或者退出登录。

所遇问题
  1. BScroll滑动问题,首先使用better-scroll 基本上与this.$nextTick(callback)挂钩了。

(1)$nextTick:由于Vue DOM更新是异步执行的,即修改数据时,视图不会立即更新,而是会监听数据变化,并缓存在同一事件循环中,等同一数据循环中的所有数据变化完成之后,再统一进行视图更新。即确保得到的是更新后的DOM。

(2)使用BScroll 必须要有一个 wrapper ,来包含锁需要使用BScroll的部分。容器为15rem,而数据的长度为30rem。

  1. 数据传递遇到的问题,本来是想用全局事件总线来传递数据(由商品分类跳转到商品详情页面),但是全局时间总线必须先有 o n , 然 后 有 on,然后有 onemit 但是商品详情页必须要在点击商品之后才能进入,这时候就会触发这个bug。所以使用了路由来传递参数。

  2. 地址栏数据不显示问题,

    <span>{{addr.name || addrdef.name }}</span>
    

    使用插值语法发现数据不显示,这是因为addr为undefinied,一个空对象是没办法取值的,按理来讲这个时候为false,所以会执行后面的代码,但是由于前面的错误导致后面的代码并不能执行,所以一直不显示数据。望以此为戒。

总结

​ 通过使用Vue2对这个商城的实战练习,学到了组件vant2的应用,也发现了van2组件库的强大。靠自己编写的不一定有人家写得好,所以对组件库的使用也是一大罐,首先就是组件库官网文档,虽然很多但是很细,各种情况基本上都考虑好了,需要耐心去看。Vuex确实是一个非常强大的功能,解决了多组件共享数据的问题。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐