参考源码:https://pan.baidu.com/s/17y6r44hrocXVjnPBVgJd5g
提取码:fk83
接口档案:https://www.showdoc.cc/128719739414963?page_id=2612486239891213
一、首页
关键点
1、⼩程序内置 request API
2、es6的 promise
3、⼩程序 swiper 组件及常用属性(autoplay、indicator-dots、circular)
4、⾃定义组件——搜索框
1、在首页 index.js 中引入子组件 SearchInput
"usingComponents": {
"SearchInput": "../../components/SearchInput/SearchInput"
},
2、⾃定义组件——搜索框
<view class="search_input">
<navigator url="/pages/search/index" open-type="navigate"> 搜索 </navigator>
</view>
3、在index.js中使用API轮播图接口
① 第一种
onLoad:function(){
wx.request({
url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
success: (result) => {
// console.log(result)
this.setData({
swiperList: result.data.message
})
}
})
}
② 第二种
在request/index.js下使用 es6的 promise 进行封装
export const request=(params)=>{
const baseUrl="https://api-hmugo-web.itheima.net/api/public/v1";
return new Promise ((resolve,reject)=>{
wx.request({
...params,
url:baseUrl+params.url,
success:(result)=>{
resolve(result);
},
fail:(err)=>{
reject(err);
}
});
})
}
在index.js中引入,使用getSwiperList()来直接在onLoad:function()中调用
import { request } from "../../request/index.js";
// 获取轮播图数据
getSwiperList(){
request({url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata'})
.then((result) => {
// 轮播图接口问题解决办法
result.data.message.forEach((v, i) => {result.data.message[i].navigator_url = v.navigator_url.replace('main', 'index');});
this.setData({
swiperList: result.data.message
})
})
.then()......
}
效果图
二、分类页面
关键点
scroll–view 组件
es7的 async 和 await
1、认识*this
<!-- *this 代表在 for 循环中的item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字 -->
<!-- class="menu_item {{index===currentIndex?'active':''}}" 这是给点击的标题默认高亮 -->
<view
class="menu_item {{index===currentIndex?'active':''}}"
wx:for="{{leftMenuList}}"
wx:key="*this"
bindtap="handleItemTap"
data-index="{{index}}"
> {{item}}</view>
2、缓存问题的解决办法
web中的本地存储 和 小程序中的本地存储 的区别:
1、代码不一样
web: localStorage.setItem(“key”,“value”); localStorage.getItem(“key”)
小程序中: wx.setStorageSync(“key”, “value”); wx.getStorageSync(“key”);
2、类型转换
web: 不管存入的是什么类型数据,最终都会先调用 toString(),把数据变成了字符串再存
小程序: 不存在类型转换的这个操作,存什么类似的数据进去,获取的时候就是什么类型
onLoad: function (options) {
//获取本地存储中的数据
const Cates = wx.getStorageSync("cates");
// 1、先判断一下本地存储中有没有旧的数据
if (!Cates) {
// 不存在 发送请求获取数据
this.getCates();
}
// 2、有旧的数据 同时 旧的数据也没有过期 就使用 本地存储中的旧数据即可 定义过期时间
else {
if (Date.now() - Cates.time > 1000 * 10) {
// 有旧数据 但是过期了 直接发送新请求 重新发送请求
this.getCates();
}
else {
// 有数据 没有过期 可以使用旧的数据
this.Cates = Cates.data;
let leftMenuList = this.Cates.map(v => v.cat_name);
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
}
}
},
3、es7的 async 和 await
先在category/index.js 引入 import regeneratorRuntime from '../../lib/runtime/runtime'
使用es7的 async
async getCates() {
// request({
// url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
// })
// .then(res => {
// this.Cates = res.data.message;
// // 把接口的数据存入到本地存储中
// wx.setStorageSync("cates", { time: Date.now(), data: this.Cates });
// 构造左侧的大菜单数据
// let leftMenuList = this.Cates.map(v => v.cat_name);
// 构造右侧的商品数据
// let rightContent = this.Cates[0].children;
// this.setData({
// leftMenuList,
// rightContent
// })
// })
//使用es7的async await来发送请求
const res = await request({
url: "/categroies"
});
this.Cates = res.data.message;
// 把接口的数据存入到本地存储中
wx.setStorageSync("cates", {
time: Date.now(),
data: this.Cates
});
// 构造左侧的大菜单数据
let leftMenuList = this.Cates.map(v => v.cat_name);
// 构造右侧的商品数据
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
},
效果图
三、商品列表页面
关键点
1、上拉 和 下拉 效果
2、tab⾃定义组件
1、子父组件传值:
自定义组件tabs要点
在子组件里面,先进行事件绑定
bindtap="handleItemTap"
data-index="{{index}}"
基本结构以及传参设置好后,在Tabs.js中写入
properties: {
tabs:{
type:Array,
value:[]
}
},
// 点击事件
handleItemTap(e){
// 1 获取点击的索引
const {index}=e.currentTarget.dataset;
// 2 触发 父组件中的事件 自定义
this.triggerEvent("tabsItemChange",{index});
}
父组件
<!-- 在index.wxml中,自定义事件的监听 -->
<Tabs tabs="{{tabs}}" bindtabsItemChange="handleItemChange"></Tabs>
标题点击事件 从子组件传值过来的
handleItemChange(e) {
// 1、获取被点击事件的标题索引
const {index} = e.detail;
//2、修改源数组
let {tabs} = this.data;
tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
//3、赋值到data中
this.setData({
tabs
})
}
2、上拉 和 下拉 效果
onReachBottom(){
// 1 判断还有没有下一页数据
if(this.QueryParams.pagenum>=this.totalPages){
// 没有下一页数据
wx.showToast({ title: '没有下一页数据' });
}else{
// 还有下一页数据
this.QueryParams.pagenum++;
this.getGoodsList();
}
},
// 下拉刷新事件
onPullDownRefresh(){
// 1 重置数组
this.setData({goodsList:[]})
// 2 重置页码
this.QueryParams.pagenum=1;
// 3 发送请求
this.getGoodsList();
}
效果图
四、商品详情页面
关键点
1、本地存储实现
2、富⽂本标签的使用
3、⼩程序 预览图⽚接⼝ previewImage
1、为了方便展示图文,使用富⽂本标签来进行图文渲染
<!-- {{goodsObj.goods_introduce}} -->
<rich-text nodes="{{goodsObj.goods_introduce}}"></rich-text>
2、⼩程序 预览图⽚接⼝————previewImage
在 wxml 的 swiper-item 标签中
bindtap="handlePreviewImage"
data-url="{{item.pics_mid}}"
在对应文件的index.js中
// 点击轮播图 放大预览
handlePreviewImage(e) {
// 1 先构造要预览的图片数组
const urls = this.GoodsInfo.pics.map(v => v.pics_mid);
// 2 接收传递过来的图片url
const current = e.currentTarget.dataset.url;
wx.previewImage({
current, //解构赋值,原型current:current
urls //解构赋值,原型urls:urls
});
}
3、购物车——本地存储实现
// 点击 加入购物车
handleCartAdd() {
// 1 获取缓存中的购物车 数组
let cart = wx.getStorageSync("cart") || [];//第一次可能没有缓存数据,则设置cart为空
// 2 判断 商品对象是否存在于购物车数组中
let index = cart.findIndex(v => v.goods_id === this.GoodsInfo.goods_id);
if (index === -1) {
//3 不存在 第一次添加
this.GoodsInfo.num = 1;
this.GoodsInfo.checked = true;
cart.push(this.GoodsInfo);
} else {
// 4 已经存在购物车数据 执行 num++
cart[index].num++;
}
// 5 把购物车重新添加回缓存中
wx.setStorageSync("cart", cart);
// 6 弹窗提示
wx.showToast({
title: '加入成功',
icon: 'success',
// true 防止用户 手抖 疯狂点击按钮
mask: true
});
},
效果图
补充:⼩程序中⽀持es7的async语法
es7的 async 据说是解决回调的最终⽅案
- 在⼩程序的开发⼯具中,勾选 es6转es5语法
- 下载 facebook的regenerator库中的 regenerator/packages/regenerator-runtime/runtime.js
- 在⼩程序⽬录下新建⽂件夹 lib/runtime/runtime.js ,将代码拷⻉进去
- 在每⼀个需要使⽤async语法的⻚⾯js⽂件中,都引⼊(不能全局引⼊)
import regeneratorRuntime from '../../lib/runtime/runtime'