1 Star 2 Fork 0

Subaru / Vue_Program

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

购物街

介绍

  一个适用于手机端的 Vue 小项目,旨在锻炼开发能力
  该项目所用的各种数据来自于“蘑菇街”

使用说明

命令行输入

  • npm install 安装所需要的包
  • npm run serve 运行程序

注意:不要使用鼠标滚动滚动,而应该使用点击拖动(与手机端手指点击拖动类似)

接口文档

路径 方法 get 参数 备注
/home/multidata GET 请求首页轮播图和推荐行的数据
/home/data GET type, page 请求首页商品数据
/detail GET iid 请求商品详情页的商品详情数据
/recommend GET 请求商品详情页的推荐模块的商品数据
/category GET 请求分类页面的商品数据

项目基本设置

1.1 目录结构

  • assets
  • common
  • components -> common/content
  • network
  • router
  • store
  • views -> home/category/cart/profile/detail

1.2 设置 CSS 初始化和全局样式(assets -> css)

  • base.css
  • initialize.css

1.3 axios 的封装(network -> request.js)

  • 创建 axios 实例
  • 拦截响应,仅返回其中的 data 数据
  • 根据传入的 config 发送请求,调用者通过.then 获取结果
    输入图片说明

项目开发细节

一、公共组件(components -> common/content)

1.1 tabbar 底部导航栏的封装

  • 封装 TabBar
  • 封装 TabBarItem
  • 响应点击切换的设计
  • MainTabBar 组件对 TabBar 和 TabBarItem 重新包装

1.2 navbar 顶部展示栏的封装

  • 封装的 navbar 组件包含三个插槽:left、center、right
  • 设置 navbar 相关的样式
  • 直接使用 navbar 实现首页的顶部展示栏
    输入图片说明

1.3. swiper 轮播图的封装

  • 封装 Swiper
  • 封装 SwiperItem
  • HomeSwiper 组件对 Swiper 和 SwiperItem 重新包装
  • 使用 HomeSwiper 组件时,传入 banners 数据进行展示

1.4 滚动的封装 Scroll

  • 学习 BetterScroll 的使用
  • 安装 better-scroll
  • 封装一个独立的组件,用于作为滚动组件:Scroll
  • 组件内代码的封装:
      1. 创建 BetterScroll 对象,并且传入 DOM 和选项(probeType、click、pullUpLoad)
        输入图片说明
      1. 监听 scroll 事件,该事件会返回一个 position(监听滚动)
      • probeType: 0/1/2(手指滚动) / 3(只要是滚动)
      • scroll.on('scroll', (position) => {})
      • Home.vue 和 Scroll.vue 之间进行通信
        • Home.vue 将 probeType 设置为 3
        • Scroll.vue 需要通过 $emit, 实时将事件发送到 Home.vue
      1. click: false
      • button 可以监听点击
      • div 不可以
      1. 监听 pullingUp 事件,监听到该事件进行上拉加载更多
      • pullUpLoad: true
      • scroll.on('pullingUp', () => {})
      1. 封装刷新的方法:this.scroll.refresh()
      1. 封装滚动的方法:this.scroll.scrollTo(x, y, time)
      1. 封装完成刷新的方法:this.scroll.finishedPullUp
        输入图片说明

1.5 封装 tabControl

  • 独立组件的封装
  • 使用 TabControl 组件时,通过 props 传入 titles 数据进行展示
  • 监听点击,通过 currentIndex 判断当前选中是哪一个 tab, 则该 tab 的文字与 border-bottom 样式颜色均变色

1.6 goods 商品展示列表的封装

  • 展示商品列表,封装 GoodsList 组件

    • props: goods
    • v-for: goods 取出数据,传入 GoodListItem 组件进行展示
      GoodsListItem
  • 列表中每一个商品,封装 GoodsListItem 组件

    • props: goodsItem * goodsItem 取出数据, 并且使用正确的 div/span/img 基本标签进行展示
      GoodsListItem
  • 设置相关样式

  • 使用 GoodsList 组件时,传入相关的商品数据进行展示

1.7 返回顶部

  • 封装 BackTop 组件
  • 定义一个常量,用于决定在什么数值下显示 BackTop 组件
  • 监听滚动,决定 BackTop 的显示和隐藏
  • 监听 BackTop 的点击,点击时,调用 scrollTo 返回顶部

二、首页界面(views -> home)

1.1 请求首页数据

  • 封装请求首页数据的方法(network -> home.js)
    输入图片说明
  • 发送数据请求
  • 将 banner 数据放在 banners 变量中
  • 将 recommend 数据放在 recommends 变量中
  • 将不同 type 的 data 数据放在 goods 变量的不同对象中(根据 type 和 page 请求商品数据)
    输入图片说明
    输入图片说明

1.2 封装 RecommendView(home -> childComps)

  • 传入 recommends 数据,进行展示

1.3 封装 FeatureView(home -> childComps)

  • 独立组件封装FeatureView
  • 展示一张图片即可

1.4 tabControl 的吸顶效果

1.4.1 获取到 tabControl 的 offsetTop

  • 必须知道滚动到多少时, 开始有吸顶效果, 这个时候就需要获取 tabControl 的 offsetTop
  • 但是, 如果直接在 mounted 中获取 tabControl 的 offsetTop, 那么值是不正确(因为此时可能在图片还没加载完的情况下就计算出了高度)
  • 如何获取正确的值了?
    • 监听 HomeSwiper 中 img 的加载完成
    • 加载完成后, 发出事件, 在 Home.vue 中, 获取正确的值
    • 为了不让 HomeSwiper 多次发出事件,可以使用 isLoad 的变量进行状态的记录
    • 注意: 区分这里不进行多次调用和 debounce(防抖)的区别

1.4.2 监听滚动, 动态的改变 tabControl 的样式

  • 问题:动态的改变 tabControl 的样式时, 会出现两个问题:
    • 问题一: 下面的商品内容, 会突然上移(tabControl 设置了 fixed后,脱离了标准流)
    • 问题二: tabControl 虽然设置了 fixed, 但是也随着 Better-Scroll 一起滚出去了
      (Better-Scroll 通过改变 translate 属性进行滚动,所以设置了 fixed 属性的标签也会滚动出去)
  • 其他方案来解决停留问题:
    • 在 scroll 标签上面, 多复制了一份 tabControl(新) 组件对象, 利用它来实现停留效果(需要设置定位,否则会被盖住)
    • 当用户滚动超过 offsetTop 时, tabControl(新) 显示出来
    • 否则, tabControl(新) 隐藏起来

1.5 backTop 回到顶部

1.5.1 封装 BackTop 组件

1.5.2 BackTop 组件的显示和隐藏

  • Home 组件的 data 中 新建属性 isShowBackTop: false
  • 监听滚动, 拿到滚动的位置:
    • -position.y > 1000,则 isShowBackTop: true
    • isShowBackTop = -position.y > 1000

1.5.3 如何监听组件的点击

  • 不可以直接监听 back-top 的点击, 必须添加修饰.native
    输入图片说明
  • 回到顶部
    • scroll 对象, scroll.scrollTo(x, y, time)
      输入图片说明
    • this.$refs.scroll.scrollTo(0, 0, 300)
      输入图片说明

1.6 上拉加载更多

  • 通过 Scroll 监听上拉加载更多
    输入图片说明
  • 在 Home 中加载更多的数据
  • 请求数据完成后,调动 finishedPullUp
    输入图片说明
    输入图片说明
    输入图片说明

1.7 解决首页中可滚动区域的问题

  • Better-Scroll 在决定有多少区域可以滚动时, 是根据 scrollerHeight 属性决定

    • scrollerHeight 属性是根据放 Better-Scroll 的 content 中的子组件的高度
    • 但是我们的首页中, 刚开始在计算 scrollerHeight 属性时, 是没有将图片计算在内的
    • 所以计算出来的高度是错误的(1300+)
    • 后来图片加载进来之后有了新的高度, 但是 scrollerHeight 属性并没有进行更新.
    • 所以滚动出现了问题
  • 如何解决这个问题了?

    • 监听每一张图片是否加载完成, 只要有一张图片加载完成了, 执行一次 refresh()
    • 如何监听图片加载完成了?
      • 原生的 js 监听图片: img.onload = function() {}
      • Vue 中监听: @load='方法'
        输入图片说明
    • 调用 scroll 的 refresh()
  • 如何将 GoodsListItem.vue 中的事件传入到 Home.vue 中

    • 因为涉及到非父子组件的通信, 所以这里我们选择了事件总线
      • bus -> 总线
      • Vue.prototype.$bus = new Vue()
      • this.bus.emit('事件名称', 参数)
        输入图片说明
      • this.bus.on('事件名称', 回调函数(参数))
        输入图片说明
  • 问题一: refresh 找不到的问题

    • 第一: 在 Scroll.vue 中, 调用 this.scroll 的方法之前, 判断 this.scroll 对象是否有值
      eg: this.scroll && this.scroll.scrollTo(x, y, time);
    • 第二: 在 mounted 生命周期函数中使用 this.$refs.scroll 而不是 created 中
      (因为 created 在模板渲染成html前调用,组件还未挂载,this.scroll 可能为空;而 mounted 在模板渲染成html后调用)
  • 问题二: 对于refresh非常频繁的问题, 进行防抖操作

    • 防抖 debounce / 节流 throttle(研究一下)
    • 防抖函数起作用的过程:
      • 如果我们直接执行 refresh, 那么 refresh 函数会被执行 30 次.
      • 可以将 refresh 函数传入到 debounce 函数中, 生成一个新的函数.
      • 之后在调用非常频繁的时候, 就使用新生成的函数.
      • 而新生成的函数, 并不会非常频繁的调用, 如果下一次执行来的非常快, 那么会将上一次取消掉
      debounce(func, delay) {
        let timer = null
        return function (...args) {
          if (timer) clearTimeout(timer)
          timer = setTimeout(() => {
            func.apply(this, args)
          }, delay)
        }
      },

1.8 让 Home 保持原来的状态

1.8.1 让 Home 不要随意销毁掉

  • keep-alive

1.8.2 让 Home 中的内容保持原来的位置

  • 离开时, 保存一个位置信息 saveY
    输入图片说明
  • 进来时, 将位置设置为原来保存的位置 saveY 信息即可
    输入图片说明
    • 注意: 最好回来时, 进行一次 refresh()

项目界面(仅展示部分)

1. 首页

购物街首页

2. 商品详情

商品详情

3. 分类界面

分类界面

4. 购物车

购物车

5. 个人中心

个人中心

MIT License Copyright (c) 2021 Subaru Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

一个适用于手机端的 Vue 项目 展开 收起
JavaScript 等 4 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/chen-hongxin/Vue_Program.git
git@gitee.com:chen-hongxin/Vue_Program.git
chen-hongxin
Vue_Program
Vue_Program
master

搜索帮助