1 新建小程序项目
添加 APPID
清理文件
删除 log 页面和文件夹。
修改 app.js
文件,删除所有代码,App
快捷生成简单结构。
修改 index 文件夹相关的代码,样式、标签、index.js
快捷键 Page
生成简单结构;index.json
添加首页标题navigationBarTitleText
搭建项目目录结构
⽬录名 | 作⽤ |
---|---|
styles | 存放公共样式 |
components | 存放组件 |
lib | 存放第三方库 |
utils | 自己的帮助库 |
request | 自己的接口帮助库 |
搭建项目页面
首页,分类页面这些。。app.json
里的page添加
引入字体图标
1)在阿里巴巴字体库中选中图标加入购物车,导入项目,在项目总选择 Font-class ,打开下面的网址
2)将代码复制到 styles/iconfont.wxss 文件里
3)全局引入这个文件
1 | @import "./styles/iconfont.wxss" |
4)页面中直接引入 class
1 | <view class="iconfont icon-receipt-address">首页</view> |
搭建项⽬ tabbar 结构
tabbar 全局配置
小程序开发文档 中的配置小程序 —》 全局配置
样式初始化
通配样式,通配符替换
1 | /* 在微信小程序中不识别通配符 * */ |
公共样式
px 和 rpx 的转化关系
1 | /* 公用属性 */ |
window为设置顶部导航的样式
02 主页
主页的 index.json
文件注册子组件,主页和全局的导航不一样的也需要修改
1 | "usingComponents": { |
2.1 注册组件
1 导航栏组件 SearchInput,注册组件时组件的路径可以使用 根目录
2.2 网路请求数据处理
每个页面的数据请求放在 onload
声明周期函数,开发文档 API — 网络中介绍了网络处理的接口。请求网络是wx.request(Object object)
1 | onLoad: function(options) { |
回调地域
当一个请求完毕了之后,接着还有其他的请求,代码结构也就是 wx.request
内部嵌套 wx.request
,这样就会形成回调地域。解决方法—> Promise 函数/async 语法
新建一个文件夹 request/index.js
,把 promise 函数封装在 request 中。
优化请求的数据,一般从接口直接获取的 result 包含其他的网络请求,为了减少代码,可以在封装的函数里面直接返回需要的直接数据result.data.message
。
1 | export const request = (params) => { |
接口域名无法访问
将域名添加小程序:登录小程序 —> 开发—>开发设置 —>服务器域名(我添加失败了,可能域名有问题吧),另一方法就是在本地设置选择不校验合法域名。
优化网络请求
提取接口地址的公共部分记为 baseUrl
1 | wx.request({ |
es7的async语法
es7的 async 号称是解决回调的最终⽅案
- 在⼩程序的开发⼯具中,勾选 es6转es5语法
- 下载 facebook的regenerator库中的
regenerator/packages/regenerator-runtime/runtime.js
- 在⼩程序⽬录下新建⽂件夹 lib/runtime/runtime.js ,将代码拷⻉进去
- 在每⼀个需要使⽤async语法的⻚⾯js⽂件中,都引⼊(不能全局引⼊)
- 数据请求函数
1 | import regeneratorRuntime from '../../lib/runtime/runtime'; |
async 和 Promise
在 分类页面暂时只要一个数据请求函数,使用 async 解决回调地域更加简单。但是在 首页,一共有 3 个数据请求函数,且这三个函数没有前后之分(当第一个函数请求失败,就不会执行后面代码,其他数据也无法请求了),因此使用 Promise 更加合理
2.3 轮播图组件
轮播图最主要的问题是 swiper 组件 和 image 都自带高度和宽度。
1 | image :设置 width 是100%,设置 mode="widthFix" 随着宽度邓丽缩放 |
2.4 楼层
图片的处理,数据的梳理
03 分类页
3.1 数据的处理
1 | 左侧菜单 数组 index |
当数据不知道如何处理的时候,先把静态的页面完成,然后去寻找数据之间的结构联系。
3.2 顶部导航
json 文件修改顶部,搜索框复用组件
3.3 菜单导航
滚动—> scroll-view
组件
整个 page 的布局
1 | 上面的导航不算在内 |
scroll-view
的bug
第一次滑动到页面某个位置,切换左侧按钮,右侧的页面不是从顶部开始的,而是在上一次滑动的位置。
【解决】scroll-top属性,设置一个变量控制 scroll-top属性,每次左侧点击事件触发,就让这个值为 0
3.4 本地存储
分类页面数据量大,将数据缓存起来,优化体验
通过 key 值获取本地存储的数据,将数据存储在 Cates 里面
1 先判断 Cates 有没有数据,没有则发起请求
2 在数据请求成功之后,本地存储该数据,数据格式为 : {time:Date.now(), data:[...]}
记录当前时间戳,用于和当前时间比较,是否过时
3 如果 Cates 有旧数据,设置一个过期时间间隔,计算时间戳是否过期,过期就重新发送请求
4 没有过期就是用本地存储中的旧数据。此时还需要重新获取左右菜单的数据。
1 | this.Cates = Cates.data |
web 的本地存储 和 小程序中的本地存储的区别
- 写代码的方式
1 | web: localStorage.setItem("key","value") localStorage.getItem("key") |
- 存储时,有无类型转换
- web: 不管存入的是什么类型的数据,最终都会先调用以下 toString(),把数据变成了字符串 再存入进去
- 小程序: 不存在 类型转换的这个操作 存什么类似的数据进去,获取的时候就是什么类型
04 商品列表⻚⾯
4.1 url 动态传参
分类页面的 navigation 通过 url 跳转到 good_list 页面,每个商品都有不同的 id 。
1- navigation 的 url 也可以通过 params / query 方式传递参数。
1 | url="/pages/goods_list/index?cid={{item2.cat_id}}"> |
2 - 在跳转页面的 onload 中获取参数
1 | onLoad: function(options) { |
3 - 构造接口数据参数
1 | QueryParams: { |
4 - 数据请求方法
参数 data 必须是string/object/ArrayBuffer
,因此有时候 data 这里的数据{index}这种,index 是一个 Number 类型
1 | async getGoodsList() { |
4.2 自定义列表组件
Tab组件 ,父子组件传递数据
slot 和 tab 组件的切换结合
1 | <block wx:if="{{tabs[0].isActived}}">1</block> |
4.3 上拉加载数据
用户上滑页面 滚动条触底 开始加载下一页数据
1 - 找到滚动条触底事件 :onReachBottom
2- 判断还有没有下一页数据
判断 当前的页码是否大于等于 总页数
总页数 = Math.ceil(总条数 / 页容量 pagesize)
当前的页码 pagenum
3 - 有数据
- pagenum + 1
- 重新加载数据
- 数据中的商品信息需要数组合并,而不是直接复制
1 | this.setData({ |
4 - 没有数据
- 界面 —> 交互 —>
wx.showToast
,类似 toast 插件
1 | wx.showToast({ |
4.4 下拉刷新页面
触发下拉刷新事件
1- ⻚⾯的json⽂件中开启配置
1 | "enablePullDownRefresh": true, |
2 重置 数据 数组
3 重置页码 设置为1
4 重新发送请求
5 数据请求回来 需要手动的关闭 等待效果
1 | // 数据请求完毕,关闭下拉刷新窗口 如果没有调用下拉刷新的窗口 直接关闭也不会报错 |
4.5 添加全局正在加载图标
wx.showLoading
:打开提示框
打开和关闭的时间
打开提示框:发起数据请求的时候,因此封装在 request 函数中
关闭提示框:请求成功或者失败的时候,因此在 complete函数里面
考虑一个页面有多个异步请求:用一个 ajaxTimes 来记录异步请求的个数
1 | complete: () => { |
05 商品详情页
5.1 获取数据
动态 url 传参
5.2 富文本 图文详情
图文详情是接口传递来提前写好的,直接拿来用就好了。
1 | <rich-text nodes="{{goods.goods_introduce}}"></rich-text> |
5.3 优化动态渲染
1 - 去除无用数据
接口传递的数据每个上平有 23 个属性,但是实际 4 个属性,对数据进行处理,只保存需要的 4个属性
1 | this.setData({ |
2 - 处理 iOS 不支持 webp图片格式
商品详情传递来是完整的 html + css ,但是图片格式是 webp 格式。
【解决方法】:1)通常找后台修改数据2)在保证后台存在同名.jpg
文件的情况下,利用正则把代码 里面的 .webp 替换为 .ipg
1 | goods_introduce: goods.goods_introduce.replace(/\.webp/g, '.jpg') |
5.4 放大预览图片
点击轮播图的图片,放大图片,wx.previewImage
接口实现
1 | const current = e.currentTarget.dataset.url |
5.5 底部导航栏
客服、分享通过 button 实现,修改 button 的样式,透明且占据整个菜单项。

1 | <button open-type="share"></button> |
navgation 组件进行跳转的时候,如果跳转页面是 tabbar 所在的页面,需要修改默认 open-type。
5.6 点击 加入购物车
1 先绑定点击事件
1 | handelAddCart() { |
findIndex 用法类似 find 方法
5.7 商品收藏
页面收藏在 onShow 函数中实现,通过页面栈访问当前页面的 options 获取商品的 id
options 选项大概有各种页面相关的参数,比如 navigator 传递的参数。data - 数据绑定的数据,以及子传父组件的参数都在 e 里面
1 页面onShow的时候 加载缓存中的商品收藏的数据
2 判断当前商品是不是被收藏 。some 函数如果所有元素都 ok 就返回 true ,否则 false。
1 | // 1 获取缓存中的商品收藏的数数组 |
通过 isCollected 来决定图标的样式
3 点击商品收藏按钮
1 判断该商品是否存在于缓存数组中(collect)
2 已经存在 把该商品删除
3 没有存在 把商品添加到收藏数组中 存入到缓存中即可
5.8 获取收货地址
获取用户的收货地址
1 | 绑定点击事件 |
把getSetting、openSetting、openSetting封装成接口。异步调用。
1 | async handleGetAddress() { |
获取地址,页面刷新就需要获取,而不是一开始页面加载的时候,因此是在 onShow
中获取地址信息
06 购物车界面
全选按钮
1 | // evey 方法处理空数组会返回一个 true ,因此需要提前判断 |
点击全选按钮
1 |
|
+- 修改商品数量
弹框 API wx.showModal
1 | handleChangeNum(e) { |
没有商品的状态提示
1 | <block wx:if="{{cart.length != 0}}"> 有商品的逻辑代码 |
点击结算
判断是否有收获地址,是否选中商品,最后跳转到支付界面。(API wx.navigateTo
)
07 支付界面
数据处理
购物车界面的商品,用户可能并不全都打算买( ),因此支付界面要对cart 数组进行筛选,filter函数
1 | cart = cart.filter(v => v.checked); |
支付功能
微信支付
哪些人 哪些帐号 可以实现微信支付
企业帐号
企业帐号的小程序后台中 必须 给开发者 添加上白名单
- 一个 appid 可以同时绑定多个开发者
- 这些开发者就可以公用这个appid 和 它的开发权限
支付开发文档。简要的支付流程如下

支付实现
先判断缓存中有没有token
没有 跳转到授权页面 进行获取token
有token
创建订单 获取订单编号
已经完成了微信支付
手动删除缓存中 已经被选中了的商品
删除后的购物车数据 填充回缓存
再跳转页面
创建订单(后台的接口文档)会说明所需的参数。获取 token (后台接口文档)
08 个人中心
个人中心上部是登陆/用户头像id
- 通过判断 userinfor(button 的 open-type可以获取)是否存在
- 不存在,登录按钮,点击按钮跳转值登录界面,利用 wx 的API 获取用户信息 将 userinfo 存入缓存
- 存在就显示用户头像 id(需要在 个人用户中心的界面从缓存中获取 userinfo)
我的订单
接口文档会有不同的参数,跳转至订单查询界面
onShow 不同于onLoad 无法在形参上接收 options参数 ,所以使用getCurrentPages
可以获取当前页面栈,间接获取当前页面的 options参数
- 判断缓存中有没有token
- 没有 直接跳转到授权页面
- 有 直接往下进行
- 获取url上的参数type
- 根据type来决定页面标题的数组元素 哪个被激活选中
- 根据type 去发送请求获取订单数据
- 渲染页面
- 点击不同的标题 重新发送请求来获取和渲染数据
09 搜索功能
输入框绑定 值改变事件 input事件bindinput="handleInput"
获取到输入框的值(value) => e.detail
- value 合法性判断
- 检验通过 把输入框的值 发送到后台
根据文档请求数据(参数是 value),把数据渲染到页面
防抖 (防止抖动) 定时器 节流
防抖 一般 输入框中 防止重复输入 重复发送请求
节流 一般是用在页面下拉和上拉
- 定义全局的定时器id
1 | // 如果1s不到就发来第二次请求,就将第一次请求销毁 |
页面痕迹的重置
当输入框有值的时候,取消按钮出现。
当输入框的值删除时,检查结果是无,而且 取消按钮消失。
取消按钮通过一个 变量控制 + hideen
点击取消按钮页面也会重置,同时会删除输入框的文本 => 给 input 的 value 绑定一个变量,点击时候重置变量
10 意⻅反馈⻚⾯
小程序的 button 有原生的接口事件
wx.chooseImage
,内置选择图片的 api
总结
声明周期函数的选择很重要
01 调试相关
编译模式
当开发一个页面的时候,经常调试,每次默认打开 page 的第一个页面,这时候可以为当前页面添加一个编译模式。
当页面需要传递参数的时候,编译模式可以设置一个默认参数
数据处理
Page 对象里面 data属性存储一些交互的变量,如果只是临时存储可以在 data 外面定义变量
- 自定义事件或者绑定事件的时候都不需要花括号,初次之外所有跟data 相关的数据都要 花括号
1 | url="/pages/goods_detail/index?goods_id={{item.goods_id}}"> |
- navigation 代替 a 标签
导航相关需要用到 navigation 组件,比如轮播图里面的照片外部是需要导航的。
路径
- 微信小程序路径要写全,在vue里面index文件可以省略不写。
- url 按照根目录来写
less css
有 & 时解析的是同一个元素或此元素的伪类,没有 & 解析是后代元素
选择器:&:nth-last-child(-n + 4)
选择后面四个
less 中使用calc
1 | ~'calc()' |
currentColor
代表了当前元素被应用上的color
颜色值。
自适应布局webkit-box
Flexible Box Model可以自动计算宽度和自适应,更加方便
-webkit-line-clamp 是一个 不规范的属性unsupported WebKit property),它没有出现在 CSS 规范草案中。
限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他外来的WebKit属性。常见结合属性:
- `display: -webkit-box;必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 。
-webkit-box-orient
必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 。text-overflow
,可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本 。
1 | //文本显示为两行,超过部分`...` |
图片的处理
750rpx (屏幕宽度)= 100vw(视口宽度)
image 的 model 决定着设置的 hight 和width 是否有效
善于引用等比例,如果图片是等比例的,那么原图和不同模式下的比例都是相等的.,比如这个可以利用求大图现在的高度$232 / 386 = 33.33vm / 大图现在的高度$
图片的src 属性是变量的时候,需要加花括号
1 | <image src="item1.floor_title.image_src" /> |
属性字段有非字母符号的,获取这个属性的时候使用[]
…res.authSetting["scope.address"]

- 传递 data参数
只要data 只有双引号没有花括号,传递的就是字符串,否则需要加花括号。
1 | //传递 数字 -1 |
- storage 里面的 key 都是小写字母,即使存储的时候是驼峰命名法,获取的时候 key 值都要小写
- 组件首字母要大写
vue 很大的区别:
- data的数据访问,小程序需要
this.data.
访问,修改data 数据需要使用 setData 方法,可以在 Page 内 data 外定义不需要渲染的变量。 - vue—router ,通过简化的 api
- vuex ,数据暂时只能存放在 Storage
解构
1 | const { index} = options |
快捷键
Ctrl + alt + 方向键 : 上下可以多行光标
ctrl + shift + 方向键 :左右移动一个单词的光标
ctrl + D :匹配相同的文本,只匹配后面的最近一个
shift + end : 选中光标所在位置后的所有文本
ctrl+p:查找文件
无法padding margin
css-tree + vscode 使用
选择 DOM,c+s+p ,搜索插件,点击之后户出现一个文件。
**
数组的 splice 方法非常重要
js实参不可以是对象嘛
1 | //报错 parameter.content should be String instead of Object; |
Ctrl+S:保存文件
Ctrl+【, Ctrl+】:代码行缩进
Ctrl+Shift+【, Ctrl+Shift+】:折叠打开代码块
Ctrl+C Ctrl+V:复制粘贴,如果没有选中任何文字则复制粘贴一行
Shift+Alt+F:代码格式化
Alt+Up,Alt+Down:上下移动一行
Shift+Alt+Up,Shift+Alt+Down:向上向下复制一行
Ctrl+Shift+Enter:在当前行上方插入一行
Ctrl+End:移动到文件结尾
Ctrl+Home:移动到文件开头
Ctrl+i:选中当前行
Shift+End:选择从光标到行尾
Shift+Home:选择从行首到光标处
Ctrl+Shift+L:选中所有匹配
Ctrl+D:选中匹配
Ctrl+U:光标回退