商品分类
获取商品分类数据
1,在项目根目录下api目录下新建category·js文件,用来管理分类页面接口请求
2,在该文件中导入封装的网络请求模块,根据接口文档,创建获取分类数据的API函数reqCategoryData
3,在/pages/category/category.js中导入封装好的获取分类数据的API函数
4,页面数据需要在页面加载的时候进行调用,因此需要在onLoad钩子函数中调用 reqCategoryData方法
5,在获取到数据以后,使用后端返回的数据对页面进行渲染
javascript
api/category.js:
//导入封装的网络请求模块实例
import http from '../utils/http'
export const reqCategoryData=()=>{
return http.get('/index/findCategoryTree')
}
category.js:
//导入封装的接口api函数
import { reqCategoryData }from '../../api/category'
Page({
//初始化数据
data:{
catagoryList:[]//商品分类列表数据
},
//获取商品数据的方法
async getCategoryData(){
const res=await reqCategoryData()
if(res.code===200){
this.setData({
categoryList:res.data
})
}
console.log(res);
},
//监听页面的加载
onLoad(){
//调用获取商品数据的方法
this.getCategoryData()
}
})
渲染一级分类并实现切换功能
需求:
当进入分类页面的时候,第一个一级分类默认是高亮选中 的状态
当点击任意的一级分类 以后,对应的一级分类需要高亮选中(active类名),其余的一级分类取消高亮选中


获取并渲染二级分类数据
框架扩展
mobx-miniprogram介绍
小程序官方提供了一个扩展工具库:mobx-miniprogram
mobx-miniprogram是针对微信小程序开发的一个简单、高效、轻量级状态管理库,它基于Mobx状态管理框架实现。
使用mobx-miniprogram定义管理的状态是响应式的 ,当状态一旦它改变,所有关联组件都会自动更新相对应的数据
通过该扩展工具库,开发者可以很方便地在小程序中全局共享的状态 ,并自动更新视图组件,从而提升小程序的开发效率
需要注意:在使用mobx-miniprogram需要安装两个包:mobx-miniprogram和mobx-miniprogram-bindings
1.mobx-miniprogram的作用:创建Store对象,用于存储应用的数据
2.mobx-miniprogram-bindings的作用:将状态和组件、页面进行绑定关联,从而在组件和页面中操作数据
操作:打开内置终端,先init npm -y再npm install mobx-miniprogram mobx-miniprogram-bindings
mobx-miniprogram创建Store 对象
如果需要创建Store对象需要使用mobx-miniprogram,因此需要先熟悉mobx-miniprogram三个核心概念:
1**.observable** :用于创建一个被监测的对象,对象的属性就是应用的状态(state),这些状态会被转换成响应式数据。
2.action :用于修改状态(state)的方法 ,需要使用action函数显式的声明创建。
3.computed :根据已有状态(state)生成的新值。计算属性是一个方法,在方法前面必须加上get修饰符 
javascript
numStore.js:
//observable用于创建一个被监测的对象,对象的属性是应用对的状态,状态会被自动转换为响应式数据
//action函数是用来显示的定义action方法,action方法是用来修改、更新状态
import {observable,action}from 'mobx-miniprogram'
//开始创建Store对象
export const numStore=observable({
//对象的属性就是应用的状态
numA:1,
numB:2,
//定义action方法,用来修改状态
update:action(function(){
//在方法中如果需要获取状态,可以使用this进行获取
this.numA+=1
this.numB+=1
}),
//计算属性computed
//是根据已有的状态来产生新的状态
//计算属性前面需要使用get修饰符进行修饰
get sum(){
//计算属性内部必须要有返回值
return this.numA+this.numB
}
})
在组件中使用Store数据
如果需要Page或者Component中对共享的数据进行读取 、更新操作,需要使用mobx-miniprogram-bindings
mobx-miniprogram-bindings的作用就是将Store和页面或组件进行绑定关联
如果需要在组件中使用 状态,需要mobx-miniprogram-bindings库中导入Componentwithstore方法
在使用时:需要将Component方法替换成Componentwithstore方法,原本组件配置项也需要写到该方法中
在替换以后,就会新增一个storeBindings配置项 ,配置项常用的属性有以下三个:
1.store:指定要绑定的Store对象
2.fields:指定需要绑定的data字段
3.actions:指定需要映射的actions方法
注意事项:
导入的数据会同步 到组件的data中
导入的方法会同步到组件的methods中
javascript
custom01.js:
// 如果需要在组件中使用Store中的数据以及方法
//需要从mobx-miniprogram-bindings里面引入ComponentWithStore方法
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
//导入当前组件需要使用的Store对象
import{numStore}from '../../stores/numStore'
ComponentWithStore({
//用来配置当前组件需要与哪些Store进行关联
//注意:在从Store对象中引入数据和方法以后
//如果是数据,会被注到data对象中
//如果是方法,会被注入到method对象中
storeBindings:{
store:numStore,
fields:['numA','numB','sum'],
actions:['update']
}
})
custom01.wxml:
<view>{{numA}}+{{numB}}={{sum}}</view>
<button type="warn"plain bind:tap="update">更新Store中的数据</button>
在页面中使用Store数据-方式1
如果我们使用了Component方法来构建页面,那么页面中如果想使用Store中的数据,使用方式和组件的使用方式是一样的
1.从mobx-miniprogram-bindings库中导入Componentwithstore方法
2.将Component方法替换成 Componentwithstore方法
3.然后配置storeBindings从Store中映射数据和方法即可
javascript
cate.js:
import{ComponentWithStore}from'mobx-miniprogram-bindings'
import{numStore}from'../../stores/numStore'
//小程序页面也可以使用component方法进行构造
//如果使用Component方法进行构造、构建页面
//这时候页面中如果想使用Store对象中的数据,使用方式和组件的使用方式是一模一样的
ComponentWithStore({
storeBindings:{
store:numStore,
fields:['numA','numB','sum'],
actions:['update']
}
})
在页面中使用Store数据-方式2-behaviors配置项
在页面中使用store的数据和方法:
1.从mobx-miniprogram-bindings中导入BehaviorWithStore方法,再调用这个方法,方法里配置storeBindings配置项。
2.在页面js里导入cartBehaviors,使用behaviors配置项注册提取的behavior。behaviors:[cartBehavior]


fields、actions对象写法
如果fields写成对象方式,有两种写法:
1,映射形式 :指定data中哪些字段来源于store以及它们在store中对应的名字。
例如 {a: 'numA', b: 'numB'}
2.函数形式 :指定data中每个字段的计算方法
o例如{a:→store.numA,b:→anotherstore.numB}
如果actions写成对象方式,只有两种写法:
1.映射形式:指定模板中调用的哪些方法来源于store以及它们在store中对应的名字。
。例如 {buttonTap: 'update' }
javascript
// 如果需要在组件中使用Store中的数据以及方法
//需要从mobx-miniprogram-bindings里面引入ComponentWithStore方法
import { action } from 'mobx-miniprogram'
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
//导入当前组件需要使用的Store对象
import{numStore}from '../../stores/numStore'
ComponentWithStore({
//用来配置当前组件需要与哪些Store进行关联
//注意:在从Store对象中引入数据和方法以后
//如果是数据,会被注到data对象中
//如果是方法,会被注入到method对象中
storeBindings:{
store:numStore,
//fields和actions有两种写法:数组写法和对象写法
//数组写法
// fields:['numA','numB','sum'],
// actions:['update']
//对象写法
fields:{
//如果fields改成了对象写法
//数据也有两种写法
//映射形式:需要指定data中哪些字段来源于store,以及在store中的名字是什么
// numA:'numA',
// numB:'numB',
// sum:'sum'
//函数形式
//key:data中哪些字段来源于store
//value:函数,函数内部需要返回对应store数据的值
// numA:()=>numStore.numA,
// numB:()=>numStore.numB,
// sum:()=>numStore.sum
//自定义属性,如果对属性进行了自定义,模板中要使用和自定义以后的属性才可以
a:'numA',
b:'numB',
total:'sum'
},
actions:{
//如果将actions改成对象写法
//actions 只有映射形式一种写法
//指定模板中使用的哪些方法来源于store,并在store中的名字是什么
updateData:'update'
}
}
})
绑定多个store以及命名空间
1.7绑定多个store以及命名空间
在实际开发中,一个页面或者组件可能会绑定多个Store,这时候我们可以将storeBindings改造成数组 。数组每一项就是一个个要绑定的Store。
如果多个Store中存在相同的数据 ,显示会出现异常还可以通过namespace属性给当前Store开启命名空间 ,在开启命名空间以后,访问数据的时候,需要加上namespace的名字才可以。
javascript
//小程序页面如果想使用store对象中的数据或者方法
//需要从mobx-miniprogram-bindings中导入BehaviorWithStore方法
import {BehaviorWithStore} from 'mobx-miniprogram-bindings'
import { cloneStore } from '../../stores/clonestore'
import { numStore } from '../../stores/numStore'
//BehaviorWithStore方法的作用:
//让页面和store对象建立关联
const cartBehavior=BehaviorWithStore({
//如果一个组件或者页面需要绑定多个store对象,需要将storeBindings配置项改造成一个数组
//数组每一项是一个个要绑定的store对象
storeBindings:[
{
store: numStore,
fields:['numA','numB','sum'],
actions:['update']
},
//如果一个组件或者页面需要绑定多个Store对象
//从Store对象中引入了相同的数据或者方法
//这时候代码就会出现异常
{
store: cloneStore,
////第一个解决方案:将fields以及actions改成对象方式
// fields:{
// a:'numA',
// b:'numB',
// total:'sum'
// },
// actions:{
// updateData:'update'
// }
//第二种解决方案:添加命名空间
//如果是数据存在冲突(存在相同的数据或者方法),添加命名空间是没有问题的
//如果是方法冲突(存在相同的数据或者方法),依然需要使用对象的方式来改造
////在添加命名空间以后,如果需要访问数据,需要加上命名空间的名字才可以
// cloneStore.numA
namespace:'cloneStore',
fields:['numA','numB','sum'],
actions:{
updateData:'update'
}
}
]
})
export default cartBehavior
miniprogram-computed计算属性...
官方为开发者提供了拓展工具库miniprogram-computed。
该工具库提供了两个功能:
1.计算属性computed
2.监听器watch
2.1 计算属性
computed
知识点:
如果需要在组件中使用计算属性功能,需要miniprogram-computed库中Componentwithcomputed方法
在使用时:需要将Component方法替换成Componentwithcomputed方法 ,原本组件配置项也需要写到该方法中 ,在替换以后,就可以新增computed以及watch配置项。 
javascript
components/custom02/custom02.js
//如果需要在组件中使用计算属性功能,需要导入ComponentwithComputed方法
import {ComponentWithComputed} from 'miniprogram-computed'
//需要使用导入的ComponentWithComputed,替换Component方法
ComponentWithComputed({
//计算属性:基于已有的数据产生新的数据
//在使用ComponentWithComputed方法构建组件以后
//这时候,就可以新增两个配置项computed以及watch配置项
computed:{
total(data){
//计算属性方法内部必须有返回值
//在计算属性内部,不能使用this来获取data中的数据
//如果想获取data中的数据,需要使用形参
// console.log(this);
//计算属性具有缓存特性
//计算属性只执行一次,后续在使用的时候,返回的是第一次执行的结果
//只要依赖的数据,没有发生改变,返回的始终只第一次执行的结果
//只有计算属性依赖的数据发生了变化,计算属性就会重新执行
console.log('-------------------');
return data.a+data.b
}
},
// watch 数据监听器,用来监听数据是否发生了变化,在数据变化以后执行相应的逻辑
watch:{
//key:需要监听的数据
//value:是回调函数,回调函数有一个形参,形参是最新的、改变以后的数据
// a:function(a){
// console.log(a);
// },
// b:function(b){
// console.log(b);
// },
//同时监听多个数据,数据与数据之间使用,进行分割
'a,b':function(a,b){
//在watch内部监听到数据变化以后,就可以来执行相应的逻辑
// console.log(a,b);
this.setData({
c:a+b
})
}
},
//组件的初始数据
data: {
a:1,
b:2,
c:''
},
/**
* 组件的方法列表
*/
methods: {
updateData(){
this.setData({
a:this.data.a+1,
b:this.data.b+1
})
}
}
})
拓展:Mobx与Computed 结合使用
两个框架扩展提供的Componentwithstore与Componentwithcomputed方法无法结合使用。
如果需要在一个组件中既想使用mobx-miniprogram-bindings又想使用miniprogram-computed
解决方案是:
1.使用旧版API
自定义组件仍然使用Component方法构建组件,将两个扩展依赖包的使用全部改为l旧版API
omobx-miniprogram-bindings官方文档
ominiprogram-computed官方文档
2.使用兼容写法(推荐)
即要么使用Componentwithstore方法构建组件,要么使用Componentwithcomputed方法构建组件
如果使用了Componentwithstore方法构建组件,计算属性写法使用旧版API
如果使用了ComponentwithComputed方法构建组件,Mobx写法使用旧版API


用户登录
什么是Token
小程序登录流程介绍



实现小程序登录功能
Mobx允许开发人员在应用程序中统一管理所有组件之间的公共数据。通过使用Mobx,开发人员可以轻松地将token存储到全局状态中,并实现在整个应用程序中的共享。并且,存储到Mobx中的数据是响应式的,数据发生了变化,使用的地方也会发生变化
首先我们先安装Mobx,然后进行实例化 ,在实例化的时候,创建共享的数据Token,以及对Token修改的方法
然后使用Component构造页面,并导入Componentwithstore方法,并配置storeBindings方法让页面和Store对象关联
用户信息
获取用户信息并存储到Store
我们首先在store/index.js中新增userInfo 可观测字段,同时创建赋值和删除的action方法
然后熟悉接口文档:获取用户信息
在熟悉了接口文档以后,根据接口文档封装接口API函数
获取用户信息的接口需要使用token,所以我们需要在登录成功以后 ,调用获取用户信息的接口
登录成功以后,将用户信息存储到本地,然后调用action方法,将用户信息存储到Store



使用数据渲染用户信息
我们需要从Store中取出用户信息数据,并渲染到顶面上。个人中心页面展示用于展示个人信息
实现步骤:
1.在个人中心页面导入Componentwithstore方法构建页面
2.配置storeBindings让组件和Store建立关联
3.渲染页面

分包处理-配置分包以及预下载
配置分包(新增字段subPackage)和分包预下载(preloadRule),并配置对应的属性
更新用户信息
渲染用户信息
在这个页面中,我们需要先渲染信息用户,用户信息目前是存储到Store中的,因此我们需要先从Store中取出用户信息的数据 ,进行渲染的渲染。让页面和Store数据建立关联 ,可以使用mobx-miniprogram-bindings提供的Behaviorwithstore方法
实现步骤:
1.新建behavior.js文件,从mobx-miniprogram-bindings库中导入Behaviorwithstore方法
2.在BehaviorwithStore方法中配置storeBindings配置项从Store中映射数据和方法
3,在Page方法中导入创建的behavior,然后配置behavior属性,并使用导入的behavior
通过behaviorWithStore建立页面与store的关联,引入,注册后behaviors里的数据会映射到data,此时wxml里就可以渲染信息了 


更新用户头像
完成头像上传到服务器
如果需要使用小程序提供的头像填写能力,需要两步:
1.将button组件open-type的值设置为chooseAvatar
2.当用户选择需要使用的头像之后,可以通过bindchoospavatar事件回调获取到头像信息的临时路径



完成头像的更新
实现步骤:
1.在/api/user.js文件中根据接口文档,创建获取用户信息的API函数reqUpdateUserInfo
2.给修改个人资料的保存按钮绑定点击事件 ,触发updateUserInfo回调函数
3.在回调函数中调用接口API函数reqUpdateUserInfo ,同时传入用户的信息
4.更新用户信息以后,将用户信息存储到本地同时同步到Store



更新用户昵称


<form bindsubmit="getNickName"> 表单绑定了提交事件:点击 form-type="submit" 的按钮时,自动触发 getNickName 函数。
<input type="nickname" name="nickname"> type="nickname":微信专属,键盘上方会显示微信昵称,一键填入 name="nickname":form 会自动收集这个输入框的值
收货地址
定义新增参数以及封装接口API
收集新增地址其他请求参数
定义新增收获地址的请求参数,同时将收获地址模块所有的接口地址都封装好


收集省市区数据
思路分析:
省市区的结构使用了小程序本身自带的picker件,并将组件的mode属性设置为了region ,从而变成省市区选择器
如果想获取省市区的数据,需要给picker选择组件添加change
事件来监听属性值的改变,获取选中的省市区


默认地址
地理定位功能介绍
使用方法:
1.在app.json中配置requiredPrivateInfos进行声明启用
2.在调用wx.getLocation时需要在app.json配置permission字 段,同时使用scope.userLocation声明
收集用户选择的位置信息的目的,wx.chooseLocation 接口不需要配置该字段,可以直接进行调用
3.在配置好以后,调用wx.getLocation和wx.chooseLocation接口
拒绝授权和授权完整的流程

开通腾讯位置服务及逆地址解析获取地址
可以使用腾讯位置服务将返回的经度、纬度进行逆地址解析,转换成详细地址。
腾讯位置服务专为小程序开发提供了JavaScriptSDK,方便开发者在小程序中司以使用腾讯地图服务。
使用腾讯位置服务可以很方便的让开发者实现地址解析、逆地址解析等功能。







表单验证-async-validator基本使用
主流的UI组件库Ant-design和Element中的表单验证都是基于async-validator
使用async-validator可以方便地构建表单验证逻辑,使得错误提示信息更加友好和灵活。
1.安装并在项目中导入async-validator
2.创建验证规则
3.创建表单验证实例,将验证规则传递给构造函数,产生实例
4.调用实例方法validate对数据进行验证 。
第一个参数:需要验证的数据 。
第二个参数:回调函数,回调函数有两个参数errors,fields ●errors:如果验证成功,返回null,验证错误,返回数组 ●fields:需要验证的字段,属性值错误数组


新增收货地址表单验证

实现新增收货地址
思路分析:
在实现了新增收货地址的数据收集、表单验证以后,我们需要实现新增收货地址的功能,将用户的收货地址到服务器。我们直接根据接口文档,封装接口API,然后在表单验证以后,进行收货地址的添加即可。
实现步骤:
1,在对新增收货地址请求参数验证 以后,将封装好的新增收货地址的API函数调用
2,在新增收货地址成功以后,跳转到收货地址详情页面。


收货地址列表渲染
实现更新收货地址功能
新增和编辑收货地址页面是同一个页面,我们需要在这个页面处理新增和编辑功能
在收货地址列表页面,点击更新按钮时 ,需要跳转 到新增/更新页面,同时需要将更新这一项的id 传递给新增/更新页面。
在onLoad中获取id,并且使用id区分用户是进行新增还是编辑的操作 。
如果存在d,在获取需要更新的收货地址的数据,并进行页面的回显用户的收货地址,并且需要更新导航栏标题
因为我们之前直接是将数据放到data中的,所以我们直接将数据使用setData赋值即可

实现删除收货地址
























