一. 项目搭建
1. 新建小程序项目
通过微信开发者工具创建项目,填入appid
,创建完成后,如图:
2. 搭建目录结构
目录结构划分如下:
目录名 | 作用 |
---|---|
styles | 存放公共样式 |
components | 存放组件 |
lib | 第三方库 |
utils | 工具类 |
request | 自用接口帮助库 |
项目目录结构图如下:
3. 清理无用文件
- 将logs文件夹删除,并从app.json中移除
- 将index/index.js中Page对象内容删除,只保留声明周期相关函数
- 在index/index.json中添加标题"navigationBarTitleText": "优购首页"
- 在index/index.wxml中删除原内容,添加<view>首页</view>
- 在index/index.wxss中删除原样式内容
4 搭建项目页面
页面名称
|
名称
|
---|---|
首页 | index |
分类页面 |
category
|
商品列表⻚⾯
|
goods_list
|
商品详情⻚⾯
|
goods_detail
|
购物⻋⻚⾯
| cart |
收藏⻚⾯
|
collect
|
订单⻚⾯
|
order
|
搜索⻚⾯
|
search
|
个⼈中⼼⻚⾯
|
user
|
意⻅反馈⻚⾯
|
feedback
|
登录⻚⾯
|
login
|
授权⻚⾯
|
auth
|
结算⻚⾯
|
pay
|
5. 引入字体图标
6.搭建项⽬tabbar结构
- 在项目根目录下,新建
icons
文件夹,并将图标拷入改文件夹 - 修改
app.json
文件,添加tabBar
代码如下: -
"tabBar": { "color": "#999", "selectedColor": "#ff2d4a", "backgroundColor": "#fafafa", "position": "bottom", "borderStyle": "black", "list": [{ "pagePath": "pages/index/index", "text": "首页", "iconPath": "icons/home.png", "selectedIconPath": "icons/home-o.png" },{ "pagePath": "pages/category/category", "text": "分类", "iconPath": "icons/category.png", "selectedIconPath": "icons/category-o.png" },{ "pagePath": "pages/cart/cart", "text": "购物车", "iconPath": "icons/cart.png", "selectedIconPath": "icons/cart-o.png" },{ "pagePath": "pages/me/me", "text": "我的", "iconPath": "icons/my.png", "selectedIconPath": "icons/my-o.png" }] },
7. 初始化页面样式
/* 在微信小程序中,不支持通配符 '*' */
page,view,text,swiper,swiper-item,image,navigator{
padding: 0;
margin: 0;
box-sizing: border-box;
}
/* 主题颜色
1. less 中 存在变量这个知识
2. 原生的css和wxss也支持变量
*/
page{
/* 定义主题颜色 */
--themeColor: #eb4450;
/*
定义统一字体
此处假设设计稿大小为375px,那存在1px=2rpx,假定设计稿字体为14px,那在小程序中应定义为2rpx
*/
font-size: 28rpx;
}
7.2 使用定义的主题颜色
index/index.wxss
中使用定义的主题颜色,方式如下:
view{
/* 使用主题颜色 */
color: var(--themeColor);
}
7.3 设置导航栏和全局外观
在app.json
中设置导航栏和标题栏字体颜色,如下:
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ff2d4a",
"navigationBarTitleText": "黑马优购",
"navigationBarTextStyle": "white"
}
综上,设置完成后,效果如下:
二. 首页模块开发
效果图:
- 头部搜索
- 轮播图
- 导航
- 楼层
业务逻辑
1.搜索框
搜索框在项目内好几处都会使用到,因此,将其封装为组件。
1.2 新建组件
在components
目录下新建SearchInput
文件夹,并通过小程序开发工具,新建组件SearchInput
。
1.3 编写组件
在SearchInput.wxml
中编写页面,此处点击跳转搜索页面,代码如下:
<!--components/SearchInput/SearchInput.wxml-->
<view class="search_input">
<navigator url="/pages/search/index" open-type="navigate">
搜索
</navigator>
</view>
1.4 引用组件
在index/index.json
中,配置引入组件,代码如下:
{
"usingComponents": {
"SearchInput":"../../components/SearchInput/SearchInput"
},
"navigationBarTitleText": "优购首页"
}
1.5 使用组件
在index/index.wxml
中使用声明的组件,代码如下:
<!--index.wxml-->
<SearchInput></SearchInput>
1.6 效果预览

2.轮播图
轮播图需要使用到小程序提供的swiper
和swiper-item
组件。
<!-- 轮播图 开始 -->
<view class="index_swiper">
<!--
1 swiper标签存在默认的宽度和高度
100% * 150px
2 image标签也存在默认的宽度和高度
320px * 240px
3 设计图片和轮播图
1 先看一下原图的宽高 750 * 340
2 让图片的高度自适应 宽度 等于100%
3 让swiper标签的高度 变成和图片的高一样即可
4 图片标签
mode属性 渲染模式
widthFix 让图片的标签宽高 和 图片标签的内容的宽高都等比例的发生变化
-->
<swiper autoplay indicator-dots circular>
<swiper-item
wx:for="{{swiperList}}"
wx:key="goods_id"
>
<navigator url="{{item.navigator_url}}">
<image mode="widthFix" src="{{item.image_src}}"></image>
</navigator>
</swiper-item>
</swiper>
</view>
<!-- 轮播图 结束 -->
3.Promise请求
3.1 新建请求index.js
文件
export const request=(params)=>{
return new Promise((resolve,reject)=>{
wx.request({
...params,
success: (result)=>{
resolve(result);
},
fail: (error)=>{
reject(error);
}
});
})
}
3.2 导入request
在index/index.js
中导入上文创建的request
对象,代码如下:
import { request } from "../../request/index.js"
3.3 替换请求
onLoad: function (options) {
request({
url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata'
}).then(result => {
console.log(result)
this.setData({
swiperList: result.data.message
})
})
},
最终效果图如下:
三. 分类页面
1.效果图
由图分析:
- 上方是一个搜索
- 左侧是分类滑动
scroll-view
- 右侧是类别详情内容,也是一个
scroll-view
2.业务逻辑
3.关键技术
- scroll-view 组件
- es7的 async 和 await
web中的本地存储和 小程序中的本地存储的区别
1 写代码的方式不一样了
web: localStorage.setItem("key","value") localStorage.getItem("key")
小程序中: wx.setStorageSync("key", "value"); wx.getStorageSync("key");
2:存的时候 有没有做类型转换
web: 不管存入的是什么类型的数据,最终都会先调用以下 toString(),把数据变成了字符串 再存入进去
小程序: 不存在 类型转换的这个操作 存什么类似的数据进去,获取的时候就是什么类型
1 先判断一下本地存储中有没有旧的数据
{time:Date.now(),data:[...]}
2 没有旧数据 直接发送新请求
3 有旧的数据 同时 旧的数据也没有过期 就使用 本地存储中的旧数据即可
四.商品列表页面
1.效果
2.技能点
- 加载商品列表数据
- 启⽤下拉⻚⾯功能
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
this.setData({
goodsList: []
})
this.QueryParams.pagenum = 1;
this.getList()
},
- ⻚⾯的json⽂件中开启设置 enablePullDownRefresh:true
- ⻚⾯的js中,绑定事件 onPullDownRefresh
- 3. 启⽤上拉⻚⾯功能 onReachBottom ⻚⾯触底事件
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
if (this.totalPages == this.QueryParams.pagenum) {
wx.showToast({
title: '没有更多数据',
})
} else {
this.QueryParams.pagenum++;
this.getList()
}
},
- 加载下⼀⻚功能
五.商品详情页面
1.效果
- 渲染商品详情数据
- 点击收藏
Shouc() {
let isShouc = false
let collect = wx.getStorageSync("collect") || [];
let index = collect.findIndex(v => v.goods_id === this.cartList.goods_id);
if (index !== -1) {
collect.splice(index, 1)
isShouc = false
wx.showToast({
title: '取消收藏',
// icon: "fail",
})
} else {
collect.push(this.cartList)
isShouc = true
wx.showToast({
title: '收藏成功'
})
}
wx.setStorageSync("collect", collect)
this.setData({
isShouc
})
},
- 点击加入购物车
addCart() {
const cart = wx.getStorageSync("cart") || []
let index = cart.findIndex(v => v.goods_id === this.cartList.goods_id);
if (index === -1) {
this.cartList.num = 1;
this.cartList.checked = true;
cart.push(this.cartList);
} else {
cart[index].num++;
}
wx.showToast({
title: '加入购物车成功',
})
wx.setStorageSync("cart", cart);
},
- 联系客服
<button open-type="contact"></button>