前言
本文章是对coderwhy vue项目仿蘑菇街做的一个步骤详解,此文章包含个人详解及主要步骤,由于代码较多较杂,就不放这了,代码大部分就用截图了
一、安装及创建
安装node,vue-cli,创建一个vue-cli3的项目
(我自己用的是Cli-4)
二、项目开发
1.目录结构
按下图创建好文件夹
2.设置CSS初始化和全局样式
- normalize.css (自行去github下载)
- base.css
在App.vue引用base.css
3.vue.config和editorconfig
- 新建vue.config.js
module.exports = {
configureWebpack: {
resolve: {
alias: {
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'network': '@/network',
'views': '@/views',
}
}
}
}
报错及解决方法
按照上述配置成功后,应特别注意使用,若还是报错:
These dependencies were not found:
则应该重启项目,再次运行之后就能成功。
- editorconfig 对代码风格进行统一,直接复制,如果你是项目组长的话,最好是有这个文件
4.TabBar引入和项目模块划分
1) tabbar
- 把day7的 tabbar 文件夹复制到项目的compontents-> common 文件夹
- 把day7的 mainTabBar 文件夹复制到项目的compontents-> content 文件夹
- 改一下MainTabBar里面的路径
- 在App.vue使用MainTabBar组件
2)项目模块划分:tabbar -> 路由映射关系
- 复制day7的tabbar下,views文件夹里面的东西到项目的views文件夹下
- 安装vue-router,复制 day7的router->index.js文件夹到项目里,在App.vue里面使用router-view
目前项目效果
5.小图标的修改以及路径问题
- 把favicon.ico图标替换掉
三、首页开发
1.首页导航栏的封装与使用
- 新建文件夹文件
// NavBar.vue
<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>
.nav-bar{
display: flex;
height: 44px;
background-color:red;
}
.left,.right{
width: 60px;
}
.center{
flex: 1;
background-color: blue;
}
</style>
// Home.vue
<template>
<div id="home">
<NavBar></NavBar>
</div>
</template>
<script>
import NavBar from "components/common/navbar/NavBar";
export default {
name: "Home",
components: {
NavBar,
},
};
</script>
<style scoped>
</style>
效果
- 修改一下样式
2.请求首页的多个数据
- 复制day9的request.js文件到项目的network文件夹,删掉其中不必要的东西
- 安装axios
- network文件夹下新建home.js文件,用来封装首页的所有网络请求
- 在首页App.vue使用
2.轮播图的展示
- 从Day9的预习代码复制components->common->swiper文件夹
- 引用
- 这样写Swiper又是一坨在Home.vue,把它封装一下,在home文件夹下新建文件夹childComps,再创建文件HomeSwiper.vue
// HommSwiper.vue
<template>
<Swiper>
<SwiperItem v-for="(item, index) in banners" :key="index">
<a :href="item.link">
<img :src="item.image" alt="" />
</a>
</SwiperItem>
</Swiper>
</template>
<script>
import { Swiper, SwiperItem } from "components/common/swiper";
export default {
name: "HomeSwiper",
components: {
Swiper,
SwiperItem,
},
props:{
banners:{
type:Array,
default(){
return []
}
}
}
};
</script>
<style>
</style>
3.推荐信息的展示
- homeComps下新建文件 recommendView.vue
<template>
<div class="recommend">
<div v-for="(item,index) in recommends" :key="index" class="recommend-item">
<a :href="item.link">
<img :src="item.image" alt="">
<div>{{item.title}}</div>
</a>
</div>
</div>
</template>
<script>
export default {
name:'RecommendView',
props:{
recommends:{
type:Array,
default(){
return []
}
}
}
}
</script>
<style>
.recommend{
display: flex;
text-align: center;
font-size: 12px;
padding: 10px 0 20px;
border-bottom: 10px solid #eee;
}
.recommend-item{
flex: 1;
}
.recommend-item img{
width: 70px;
height: 70px;
margin-bottom: 10px;
}
</style>
目前首页效果
4.FeatureView的封装
- childComps下新建文件FeatureView.vue文件
- 添加以下样式,使home-nav固定
5.TabControl的封装
- content新建文件TabControl,因为首页的tabcontrol与分类的只是文字不同,所以这里不用插槽,直接用props传值
- 修改一下样式
- 目前效果
- 实现点击添加样式功能
- 实现tabControl吸顶(停留效果)
6.保存商品的数据结构设计
goods: (流行/新款/精选)
goods: {
'pop': {page: 5, list: [150]},
'news': {page: 2, list: [60]},
'sell': {page: 1, list: [30]}
}
7.首页数据的请求和保存
- 默认请求三个的第一页数据,其他的等点击对应选项且下拉时再加载
- goods里面的news要改为new
- 此时created里面的代码有点多,一般created里面只做调用,把这些函数封装到methods里面
- 这样写的话,getHomeGoods也能动态传类型
- page的1不能写死,不然每次调用都是请求第一页的数据,应该是goods里面的page+1
- 保存商品数据
8.首页商品数据的展示
- content文件夹新建goods文件夹,新建GoodsList.vue和GoodsListItem.vue
- 用props把对应type的goods传给GoodsList.vue
- 用props把对应的goods里面的每一个商品item传给GoodsListItem.vue
- 把数据全部展示出来
- 添加一下样式,直接从Day9预习代码里面复制goodsListItem.vue的css代码,目前效果如下
- 让商品一行两个均等分显示
- 小bug:tabControl被覆盖了,加个z-index就行
9.TabControl切换商品
- 之前点击是在tabControl,要把index传到home里面
效果
- 封装一下
10.Better-Scroll的安装和使用
- 之前用的都是浏览器原生的滚动,不够顺滑,使用better-scroll做滚动
- 安装
- 在Category.vue组件做better-scroll的使用演示
- 实现局部滚动
- 浏览器原生方法,会比较卡顿
- better-scroll,丝滑,有回弹效果
- 浏览器原生方法,会比较卡顿
- html里面基本使用
- 检测滚动位置
11.BScroll的封装和使用
- better-scroll的使用要求
- 滚动条的区域就在wrapper,而我们的内容content则要大于等于滚动区域wrapper的高度,二者均需要指定高度
- 安装better-scroll,common新建文件夹scroll,新建文件Scroll.vue
ref如果是绑定在组件中的, 那么通过this.$refs.refname获取到的是一个组件对象.
ref如果是绑定在普通的元素中, 那么通过this.$refs.refname获取到的是一个元素对象.
- 效果,在300px的范围内实现了局部滚动
- 确定中间的高度
- 方案1
- 方案2
12.Backtop组件的封装和使用
- 文件夹content下新建backTop文件夹,文件BackTop.vue
- 实现点击回到最顶部 ,需要拿到scroll对象
13.BackTop的显示和隐藏
14.完成上拉加载更多
- 小bug,下拉之后滚动不了 ,这个后面再一起解决
15.滚动区域的Bug分析和解决
- 把上面关于上拉加载更多的代码删掉
- 分析
事件总线解决滑动bug
16.refresh函数找不到的bug处理
- created()有可能拿不到refs,最好判断scroll存不存在
17.刷新频繁的防抖函数处理
18.上拉加载更多的完成
直接看第14那里
19.tabControl的offsetTop获取分析
20.tabControl的吸顶效果完成
获取到tabControl的offsetTop
监听滚动, 动态的改变tabControl的样式
- 用动态绑定class会有bug,tabControl会消失
- 直接复制tabControl
- 停留效果完成,但是还有其他bug ,两个选项卡没有同步
- 改一下ref,做一下区分,在tabClick修改对应的currentIndex
- 吸顶效果完成
21.Home离开时记录状态和位置
让Home不要随意销毁掉
- 每次离开home,都会被销毁
- 加keep-alive,home没有被销毁了,但是滚动位置还是改变了,是better-scroll的原因,但最新版似乎没有这个问题
让Home中的内容保持原来的位置
-
离开时, 保存一个位置信息saveY.
-
进来时, 将位置设置为原来保存的位置saveY信息即可.
-
注意: 最好回来时, 进行一次refresh()
-
22.跳转到详情页并携带id
- 新建文件,配置路由关系,监听GoodsListItem点击事件
- 首页基本完成了