小程序101~125

通用模块封装

好处:方便维护

消息提示模块封装toast

封装思路:

1.创建一个toast方法对wx.showToast方法进行封装

2.调用该方法时,传递对象作为参数 。如果没有传递任何参数,设置一个空对象作为默认参数 。从对象中包含title、icon、duration、mask参数,并给参数设置默认值

3,在需要显示弹出框的时候调用toast方法,并传入相关的参数,有两种参数方式: I.不传递参数,使用默认参值 。传入部分参数,覆盖默认的参数

javascript 复制代码
app.js:
import './utils/extendApi'
// import { toast } from './utils/extendApi'

App({
  onShow(){
     //wx.showToast({
     //  title:'消息提示框',
     //  icon:'success',
     //  提示的图标,success(成功)、error(失败)、1oading(加载)、none(不显示图标)
     //  duration:2000,//提示的延迟时间
     //  mask: true //是否显示透明蒙层,防止触摸穿透
     })

    //可以不传入参数
    // toast()
    // wx.toast()

    //可以传入参数,传入的参数会覆盖默认的参数
    // toast({title:'数据加载完毕',icon:'success'})
    wx.toast({title:'数据加载完毕',icon:'success'})

}

extendApi.js:
//在使用toast方法时,可以传入参数,也可以不传入参数
//如果需要传入参数,要传入对象作为参数
// const toast = (options ={}) =>{}

//如果用户传入了对象作为参数
//在形参位置通过解构的方式获取用户传入的参数,同时设置默认值
const toast=( {title='数据加载中...',icon='none',duration=2000,mask=true}={})=>{

  wx.showToast({
    title,
    icon,
    duration,
    mask
  })
}
//如果有很多.js文件,都需要调用toast方法
//每次使用都需要导入toast,然后进行调用,太麻烦
//可以将toast方法挂载到wx全局对象身上
//如果想挂载到w全局对象上这种写法生效,需要让当前文件执行一次
wx.toast = toast

export { toast }
//如果其他.js文件,需要使用toast方法
//需要先导入toast,然后进行调用才可以

模态对话框封装

封装思路:

1.对wx.showModal方法进行封装 ,封装后的新方法叫modal

2.调用该方法时,传递对象作为参数,对象的参数同Wx.showModal参数一致

3.封装的modal方法的内部通过Promise返回用户执行的操作 (确定和取消,都通过resolve返回)

4.在需要显示模态对话框 的时候调用modal方法 ,并传入相关的参数,有三种调用方式:

4/1不传递参数,使用默认参数

4/2传递参数,覆盖默认的参数

javascript 复制代码
app.js
import './utils/extendApi'


extendApi.js

// 1. 封装 modal 方法
const modal = (options = {}) => {
  // 2. 返回 Promise → 支持 async/await
  return new Promise((resolve) => {
    // 3. 默认配置(用户不传参时用这个)
    const defaultOpt = {
      title: '提示',
      content: '您确定执行该操作吗?',
      confirmColor: "#f3514f"
    }

    // 4. 合并参数:默认配置 + 用户传入的配置
    const opts = Object.assign({}, defaultOpt, options)

    // 5. 调用小程序官方模态框
    wx.showModal({
      // 展开合并后的参数
      ...opts,

      // 6. 执行完毕返回结果给调用者
      complete({ confirm, cancel }) {
        // 点确定 → 返回 true
        confirm && resolve(true)
        // 点取消 → 返回 false
        cancel && resolve(false)
      }
    })
  })
}

// 7. 挂载到 wx 全局对象 → 任何页面直接 wx.modal()
wx.modal = modal

// 8. 导出(可按需局部引入)
export { modal }

封装本地存储API

同步

javascript 复制代码
app.js:
import './utils/extendApi'
import{setStorage,getStorage,removeStorage,clearStorage}from './utils/storage'

App({
 async onShow(){
    setStorage('name','tom')
    setStorage('age','10')

    const name= getStorage('name')
    console.log(name);

    removeStorage('name')
    clearStorage('name','age')
  }
})


storage.js:
/**
 * @description 存储数据
 * @param{*}key 本地缓存中指定的key
 * @param{*} value 需要缓存的数据
 */


export const setStorage=(key,value)=>{
  try{
    wx.setStorageSync(key,value)
  }catch(error){
    console.error(`存储指定${key}数据发生了异常`,error)
  }
}
/**
 * @description 从本地读取指定key的数据
 * @param{*}key 本地缓存中指定的key
 */

export const getStorage=(key)=>{
  try{
    const value=wx.getStorageSync(key)
    if(value){
      return value
    }
  }catch(error){
    console.error(`读取指定${key}数据发生了异常`,error);
  }
}

/**
 * @description 从本地移除指定key的数据
 * @param{*}key 本地缓存中指定的key
 */
export const removeStorage=(key)=>{
  try{
    const value=wx.removeStorageSync(key)
  }catch(error){
    console.error(`移除指定${key}数据发生了异常`,error);
  }
}

/**
 * @description 从本地移除,清空全部数据
 */
export const  clearStorage=(key)=>{
  try{
    wx.clearStorageSync()
  }catch(error){
    console.error(`清除,清空数据发生了异常`,error)
  }
}

异步

javascript 复制代码
app.js:
//异步封装API(原本基础上加 async)
    // asyncSetStorage('name','jerry').then((res)=>{
    //   console.log(res);
    // })
    // asyncSetStorage('age',18).then((res)=>{
    //   console.log(res);
    // })

    // asyncGetStorage('name').then((res)=>{
    //   console.log(res.data);
    // })

    // asyncRemoveStorage('name').then((res)=>{
    //   console.log(res.data);
    // })
    
    asyncClearStorage().then((res)=>{
        console.log(res);
    })

storage.js:
/**
 * @description 存储数据
 * @param{*}key 本地缓存中指定的key
 * @param{*} value 需要缓存的数据
 */


export const setStorage=(key,value)=>{
  try{
    wx.setStorageSync(key,value)
  }catch(error){
    console.error(`存储指定${key}数据发生了异常`,error)
  }
}
/**
 * @description 从本地读取指定key的数据
 * @param{*}key 本地缓存中指定的key
 */

export const getStorage=(key)=>{
  try{
    const value=wx.getStorageSync(key)
    if(value){
      return value
    }
  }catch(error){
    console.error(`读取指定${key}数据发生了异常`,error);
  }
}

/**
 * @description 从本地移除指定key的数据
 * @param{*}key 本地缓存中指定的key
 */
export const removeStorage=(key)=>{
  try{
    const value=wx.removeStorageSync(key)
  }catch(error){
    console.error(`移除指定${key}数据发生了异常`,error);
  }
}

/**
 * @description 从本地移除,清空全部数据
 */
export const  clearStorage=(key)=>{
  try{
    wx.clearStorageSync()
  }catch(error){
    console.error(`清除,清空数据发生了异常`,error)
  }
}

网络请求封装

为什么要封装wx.request:微信requestAPI不支持Promise方式 ,需要开发者自行封装

request实例方法

1.在WxRequest类内部封装一个request实例方

2.request实例方法中需要使用Promise封装wx.request,也就是使用Promise处理wx.request的返回结果

3.request实例方法接收一个options对象作为形参,options参数和调用 wx.request 时传递的请4求配置项一致 ·

4.接口调用成功时,通过resolve返回响应数据 ●接口调用失败时,通过reject返回错误原因

javascript 复制代码
text.js:
import  instance from '../../utils/request'

Page({

  async handler(){
    //第一种调用方式,.then方式进行调用
    // instance.request({
    //   url:'https://jsonplaceholder.typicode.com/posts/1',
    //   method:'GET'
    // })
    // .then((res)=>{
    //   console.log(res);
    // })

    //第二种调用方式:await + async的方法进行调用
    const res= instance.request({
      url:'https://jsonplaceholder.typicode.com/posts/1',
      method:'GET'
    })
    console.log(res);
    

  }
})



request.js;
//创建wx.request类
//通过类的方式进行封装,使代码有复用性
//也可以方便添加新的属性和方法

//1.创建WxRequest类
class wxRequest{
  //用于创建和初始化类的属性以及方法
  constructor(){}

  //2.封装request实例方法接收一个对象类型的参数
  //属性值和wx.request方法调用时传递的参数保持一致
  request(options){
    //需要使用Promise来封装wx.request,处理异步请求
    return new Promise((resolve,reject)=>{
      wx.request({
        ...options,

        //当接口调用成功时触发success回调函数
        success:(res)=>{
          resolve(res)
        },

        //当接口调用失败时触发fail回调函数
        fail:(err)=>{
          reject(err)
        }
      })
    })
  }
}


// -----------以下是实例化的代码----------------
//目前写到同一个文件中,是为了方便进行测试,以后会提取成多个文件

//对wx.request进行实例化
const instance=new wxRequest()

//将WxRequest实例进行暴露出去,方便在其他文件中进行使用
export default instance

设置请求参数

类内部定义了默认 的请求参数,当用户在实例化 时会传入 对应参数,传入的参数被construct形参接收 ,在construct函数内部合并请求参数 。在调用实例方法时,也会传入请求参数 ,传入的请求参数需要在实例化方法内容进行合并先合并拼接完整的请求地址 后,再来合并请求参数 ,最后拿到请求参数发送请求

javascript 复制代码
request.js:
//创建wx.request类
//通过类的方式进行封装,使代码有复用性
//也可以方便添加新的属性和方法

//1.创建WxRequest类
class wxRequest{
  //定义实例属性,用来设置默认请求参数
  defaults ={
      baseURL:'',//请求基准地址
      url:'',//接口的请求路径
      data:null,//请求参数
      method:'GET',//默认的请求方法
      //请求头
      header:{
        "Content-type":'application/json'  //设置数据的交互格式
      },
      timeout:60000//默认的超时时长是1min
  }
  //用于创建和初始化类的属性以及方法

  //在实例化时传入的参数,需要被constructor形参进行接收
  constructor(params={}){
    //通过object.assign方法合并并请求参数
    //注意:需要传入的参数,覆盖默认的参数,因此传入的参数放到最后
    this.defaults= Object.assign({},this.defaults,params)
  }

  //2.封装request实例方法接收一个对象类型的参数
  //属性值和wx.request方法调用时传递的参数保持一致
  request(options){
    //需要先合并完整的请求地址(baseURL + url)
    //'https://gmall-prod.atguigu.cn/mall-api/index/findBanner'
    options.url=this.defaults.baseURL + options.url

    //合并请求参数
    options={...this.defaults,...options}


    //需要使用Promise来封装wx.request,处理异步请求
    return new Promise((resolve,reject)=>{
      wx.request({
        ...options,

        //当接口调用成功时触发success回调函数
        success:(res)=>{
          resolve(res)
        },

        //当接口调用失败时触发fail回调函数
        fail:(err)=>{
          reject(err)
        }
      })
    })
  }
}


// -----------以下是实例化的代码----------------
//目前写到同一个文件中,是为了方便进行测试,以后会提取成多个文件

//对wx.request进行实例化
const instance=new wxRequest({
  baseURL:'https://gmall-prod.atguigu.cn/mall-api',
  timeout:15000
})

//将WxRequest实例进行暴露出去,方便在其他文件中进行使用
export default instance


// pages/test/test.js
import  instance from '../../utils/request'

Page({

  async handler(){
    //第一种调用方式,.then方式进行调用
    // instance.request({
    //   url:'https://jsonplaceholder.typicode.com/posts/1',
    //   method:'GET'
    // })
    // .then((res)=>{
    //   console.log(res);
    // })

    //第二种调用方式:await + async的方法进行调用
    const res= instance.request({
      url:'index/findBanner',
      method:'GET'
    })
    console.log(res);
    

  }
})

封装请求快捷方法

请求快捷方法同时传递相关参数 ,把参数传递 给请求并解方法,参数传递过来后,再请求并解方法内部会对参数进行组织 ,进行合并 ,合并后把参数传递给request请 求方法(request(options)),request请求方法就能接收到合并后的参数,然后拿参数发送请求(wx.request ...options) 。请求响应成功后(success)返回数据r eturn new Promise(resolve(res)),再请求并列方法内部 ,再把数据return出去,所以在请求方法对应位置就能接受到返回的数据

请求拦截器与响应拦截器

为了方便统一处理请求参数以及服务器响应结果,为WxRequest添加拦截器功能,拦截器包括请求拦截器和响应拦截器

请求拦截器本质上是在请求之前调用的函数 ,用来对请求参数进行新增和修改

响应拦截器本质上是在响应之后调用的函数 ,用来对响应数据做点什么

注意:不管成功响应还是失败响应,都会执行响应拦截器

定义请求

在使用wx.request发送网络请求时。 只要成功接收到服务器返回,无论statusCode是多少,都会进入success回调 开发者根据业务逻辑对返回值进行判断。 什么时候会有fail回调函数?一般只有网络出现异常、请求超时等时候,才会走fai回调

完善请求

使用请求

javascript 复制代码
//创建wx.request类
//通过类的方式进行封装,使代码有复用性
//也可以方便添加新的属性和方法

//1.创建WxRequest类
class wxRequest{
  //定义实例属性,用来设置默认请求参数
  defaults ={
      baseURL:'',//请求基准地址
      url:'',//接口的请求路径
      data:null,//请求参数
      method:'GET',//默认的请求方法
      //请求头
      header:{
        "Content-type":'application/json'  //设置数据的交互格式
      },
      timeout:60000//默认的超时时长是1min
  }

  //定义拦截器对象
  //需要包括请求拦截器和响应拦截器,方便在请求之前和响应以后时进行逻辑处理
  interceptors={
    // 请求拦截器
    //在请求发送之前,对请求参数进行新增或者修改
    request:(config)=>config,
    //响应拦截器
    //在服务器响应数据以后,对服务器响应的数据进行逻辑处理
    response:(response)=>response
  }


  //用于创建和初始化类的属性以及方法
  //在实例化时传入的参数,需要被constructor形参进行接收
  constructor(params={}){
    //通过object.assign方法合并并请求参数
    //注意:需要传入的参数,覆盖默认的参数,因此传入的参数放到最后
    this.defaults= Object.assign({},this.defaults,params)
  }

  //2.封装request实例方法接收一个对象类型的参数
  //属性值和wx.request方法调用时传递的参数保持一致
  request(options){
    //需要先合并完整的请求地址(baseURL + url)
    //'https://gmall-prod.atguigu.cn/mall-api/index/findBanner'
    
    // 合并默认配置(baseURL、timeout、header都会合并)
    // options = Object.assign({}, this.defaults, options)
    options.url=this.defaults.baseURL + options.url
    
    //合并请求参数
    options={...this.defaults,...options}

    console.log(options);

    //在请求发送之前调用请求拦截器,新增和修改请求参数
    options=this.interceptors.request(options)

    //需要使用Promise来封装wx.request,处理异步请求
    return new Promise((resolve,reject)=>{
      wx.request({
        ...options,
        //当接口调用成功时触发success回调函数
        success:(res)=>{
          //不管是成功响应还是失败响应都会调用响应拦截器
          //响应拦截器需要接收服务器响应的数据,然后对数据进行逻辑处理,处理好以后进行返回
          //然后在通过resolve将返回的数据抛出去

          //在给响应拦截器传递参数时,需要将请求参数也一起传递
          //方便进行代码的调试或者进行其他逻辑处理,需要先合并参数
          //然后将合并的参数传递给响应拦截器
          const mergeRes=Object.assign({},res,{config:options})
          resolve(this.interceptors.response(mergeRes))
        },
        //当接口调用失败时触发fail回调函数
        fail:(err)=>{
          //不管是成功响应还是失败响应都会调用响应拦截器
          const mergeErr=Object.assign({},err,{config:options})
          reject(this.interceptors.response(mergeErr))
        }
      })
    })
  }
  //封装GET实例方法
  get(url, data = {}, config = {}) {
    //需要调用request请求方法发送请求,只需要组织好参数,传递给request方法即可
    //当调用get方法时,需要将request方法的返回值return出去
    return this.request(Object.assign({ url, data, method: "GET" }, config))
  }
  //封装delete实例方法
  delete(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: "DELETE" }, config))
  }
  //封装Post实例方法
  post(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: "POST" }, config))
  }
  //封装put实例方法
  put(url, data = {}, config = {}) {
    return this.request(Object.assign({ url, data, method: "PUT" }, config))
  }
}
// -----------以下是实例化的代码----------------
//目前写到同一个文件中,是为了方便进行测试,以后会提取成多个文件

//对wx.request进行实例化
const instance=new wxRequest({
  baseURL:'https://gmall-prod.atguigu.cn/mall-api/',
  timeout:15000
})

// //配置请求拦截器
instance.interceptors.request=(config)=>{
  //在请求发送之前做点什么
  return config
}
instance.interceptors.response=(response)=>{
  //对服务器响应的数据做点什么
  return response
}


//将WxRequest实例进行暴露出去,方便在其他文件中进行使用
export default instance

请求封装-添加并发请求

需要判断是请求成功,还是请求失败,然后进行不同的业务逻辑处理

封装需求:

1.如果请求成功 ,将响应成功的数据传递给响应拦截器 ,同时在传递的数据中新增issuccess:true字段,表示请求成功

2.如果请求失败,将响应失败的数据传递给响应拦截器,同时在传递的数据中新增isSuccess:false字段,表示请求失败

在实例调用的响应拦截中,根据传递的数据进行以下的处理:

·如果issuccess:true 表示服务器响应了结果,我们可以将服务器响应的数据简化以后进行返回

●如果isSuccess:false 表示是网络超时或其他网络问题,提示网络异常,同时将返回即可

javascript 复制代码
test.js:
//测试并发请求
  async allhandler(){
   //演示通过Promise.all同时发送多个请求
    //Promise.all能够将多个请求同时进行发送
    //Promise.all能够将多个异步任务同时进行发送,也就是并行发送
    //并不会造成请求的阻塞,从而不会影响页面的渲染速度
    // await Promise.all([instance.get('/index/findBanner'),instance.get('/index/findCategory1'),instance.get('/index/findBanner'),instance.get('/index/findCategory1')])
  
    const res=await instance.all(instance.get('/index/findBanner'),instance.get('/index/findCategory1'),instance.get('/index/findBanner'),instance.get('/index/findCategory1'))
   
    console.log(res);
  }

添加 loading

1.在请求发送之前,需要通过wx.showLoading展示Loading效果

2.当服务器响应数据 以后,需要调用wx.hideLoading隐藏loading效果

要不要加loading添加到WxRequest内部

1.在类内部进行添加,方便多个项目直接使用类提供的1oading效果,也方便统一优化 wx.showLoading使用体验。

但是不方便自己来进行1oading个性化定制。

2.如果想自己来控制1oading效果,带来更丰富的交互体验,就不需要将1oading封装到类内部,但是需要开发者自己

来优化wx.showLoading使用体验,每个项目都要写一份。

在类内部来添加了loading效果,在请求发送之前需要展示loading效果,complete:()=>{ //不管请求是成功还是失败,都需要隐藏loading wx.hideLoading() }

完善loading

队列的方式 解决这三个问题:首先在类中新增一个实例属性queue ,初始值是一个空数组

1.发起请求之前 ,判断queue如果是空数组则显示1oading ,然后立即向queue新增请求标识

2.在complete 中每次请求成功结束 ,从queue中移除一个请求标识 ,queue为空时隐藏loading

3.为了解决网络请求过快产生1oading闪烁问题,可以使用定时器来做判断即可

javascript 复制代码
// 创建 wx.request 封装类
class WxRequest {
  // ==========================
  // 一、默认基础配置
  // ==========================
  defaults = {
    baseURL: '',
    url: '',
    data: null,
    method: 'GET',
    header: {
      "Content-type": 'application/json'
    },
    timeout: 60000
  }

  // ==========================
  // 二、拦截器
  // ==========================
  interceptors = {
    request: (config) => config,    // 请求之前
    response: (response) => response // 响应之后
  }

  // ==========================
  // 三、请求队列 + 定时器(防 Loading 闪烁)
  // ==========================
  queue = []
  timerId = null

  // ==========================
  // 四、构造函数:合并配置
  // ==========================
  constructor(params = {}) {
    this.defaults = Object.assign({}, this.defaults, params)
  }

  // ==========================
  // 五、核心 request 方法
  // ==========================
  request(options) {
    // 1. 新请求 → 清除上一次定时器
    this.timerId && clearTimeout(this.timerId)

    // 2. 合并完整请求地址
    options.url = this.defaults.baseURL + options.url

    // 3. 合并所有请求参数
    options = { ...this.defaults, ...options }

    // 4. 队列空 → 显示 Loading
    this.queue.length === 0 && wx.showLoading()

    // 5. 加入请求标识
    this.queue.push('request')

    // 6. 执行请求拦截器
    options = this.interceptors.request(options)

    // 7. 发起网络请求
    return new Promise((resolve, reject) => {
      wx.request({
        ...options,
        success: (res) => {
          const mergeRes = { ...res, config: options, isSuccess: true }
          resolve(this.interceptors.response(mergeRes))
        },
        fail: (err) => {
          const mergeErr = { ...err, config: options, isSuccess: false }
          reject(this.interceptors.response(mergeErr))
        },

        // ==========================
        // 六、complete:老师核心防闪烁逻辑
        // ==========================
        complete: () => {
          // 1. 请求结束 → 删除一个队列标识
          this.queue.pop()

          // 2. 队列为空 → push 占位,不让 Loading 立刻消失
          this.queue.length === 0 && this.queue.push('request')

          // 3. 开启 1ms 窗口期
          this.timerId = setTimeout(() => {
            // 4. 删除占位标识
            this.queue.pop()

            // 5. 真正空了 → 隐藏 Loading
            this.queue.length === 0 && wx.hideLoading()

            // 6. 清除定时器
            clearTimeout(this.timerId)
          }, 1)
        }
      })
    })
  }

  // ==========================
  // 七、快捷请求方法
  // ==========================
  get(url, data = {}, config = {}) {
    return this.request({ url, data, method: "GET", ...config })
  }
  post(url, data = {}, config = {}) {
    return this.request({ url, data, method: "POST", ...config })
  }
  put(url, data = {}, config = {}) {
    return this.request({ url, data, method: "PUT", ...config })
  }
  delete(url, data = {}, config = {}) {
    return this.request({ url, data, method: "DELETE", ...config })
  }

  // ==========================
  // 八、并发请求
  // ==========================
  all(...promises) {
    return Promise.all(promises)
  }
}

export default WxRequest

控制 loading显示

就需要一个开关来控制1oading显示。

1.类内部设置默认请求参数isLoading属性 ,默认值是true,在类内部根据isLoading属性做判断 即可

2.某个接口不需要显示loading效果,可以在发送请求的时候,可以新增请求配置isLoading设置为false

3.整个项目都不需要显示loading效果,可以在实例化的时候,传入isLoading配置为false

封装uploadFile

使用npm包发送请求

之前有网络封装,则只需要修改from后面

环境变量

javascript 复制代码
http.js:
import WxRequest from './request'
import {getStorage} from './storage'
import {model,toast} from'./extendApi'
import{env}from './env'
// -----------以下是实例化的代码----------------
//目前写到同一个文件中,是为了方便进行测试,以后会提取成多个文件

//对wx.request进行实例化
const instance=new WxRequest({
  baseURL:env.baseURL,
  timeout:10000,
  isLoading:false
})

env.js:
//就是用来配置当前小程序项目的环境变量

//获取当前小程序的账号信息
const {miniProgram}=wx.getAccountInfoSync()
//相当于:const info = wx.getAccountInfoSync()
//       const miniProgram = info.miniProgram

//获取小程序的版本
const{ envVersion }=miniProgram
//相当于:const envVersion = miniProgram.envVersion

let env={
  baseURL:'https://gmall-prod.atguigu.cn/mall-api',
}

switch(envVersion){
  //开发版
  case'develop':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  //体验版
  case'trial':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  //正式版
  case'release':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  default:
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
}

export{env}

打瞌睡的朱尤: 05-12 08:29:13
这样做的有以下几点好处:
1,易于维护:一个文件就是一个模块,一个方法就是一个功能,清晰明了,查找方便
2,便于复用:哪里使用,哪里导入,可以在任何一个业务组件中导入需要的方法
3.团队合作:分工合作

小程序设置环境变量

wx.getAccountInfoSync()miniprogram的enversion

1,易于维护:一个文件就是一个模块,一个方法就是一个功能,清晰明了,查找方便

2,便于复用:哪里使用,哪里导入,可以在任何一个业务组件中导入需要的方法

3.团队合作:分工合

javascript 复制代码
http.js:
import WxRequest from './request'
import {getStorage} from './storage'
import {model,toast} from'./extendApi'
import{env}from './env'
// -----------以下是实例化的代码----------------
//目前写到同一个文件中,是为了方便进行测试,以后会提取成多个文件

//对wx.request进行实例化
const instance=new WxRequest({
  baseURL:env.baseURL,
  timeout:10000,
  isLoading:false
})

env.js:
//就是用来配置当前小程序项目的环境变量

//获取当前小程序的账号信息
const {miniProgram}=wx.getAccountInfoSync()
//相当于:const info = wx.getAccountInfoSync()
//       const miniProgram = info.miniProgram

//获取小程序的版本
const{ envVersion }=miniProgram
//相当于:const envVersion = miniProgram.envVersion

let env={
  baseURL:'https://gmall-prod.atguigu.cn/mall-api',
}

switch(envVersion){
  //开发版
  case'develop':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  //体验版
  case'trial':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  //正式版
  case'release':
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
  default:
    env.baseURL='https://gmall-prod.atguigu.cn/mall-api'
    break;
}

export{env}

接口调用方式说明

在开发中,我们会将所有的网络请求方法放置在api目录下统一管理 ,然后按照模块功能来划分成对应的文件 ,在文件中将接口封装成一个个方法单独导出

javascript 复制代码
//miniprogram/api/index.js
//导入封装的网络请求模块实例
import http from'../utils/http'

/**
 * @description 用来获取首页轮播图数据
 */
export const reqSwiperData=()=> http.get('/index/findBanner')

// 相当于export const reqSwiperData=()=>{
//   return http.get('/index/findBanner')
// }

项目首页

获取首页数据

javascript 复制代码
api/index.js:
//导入封装的网络请求模块实例
import http from'../utils/http'

export const reqIndexData=()=>{
  //通过并发请求获取首页的数据,提升页面的渲染速度

//通过Promise.all进行并发请求
//  return Promise.all([
//     http.get('/index/findBanner'),
//     http.get('/index/findCategory1'),
//     http.get('/index/advertisement'),
//     http.get('/index/findListGoods'),
//     http.get('/index/findRecommendGoods'),
//   ])

//是通过封装的all方法发送请求
//两种方法都可以
return http.all(
  http.get('/index/findBanner'),
  http.get('/index/findCategory1'),
  http.get('/index/advertisement'),
  http.get('/index/findListGoods'),
  http.get('/index/findRecommendGoods'),
)
}


index.js:
import{ reqIndexData }from'../../api/index'
Page({
  //初始化数据
  data:{
    bannerList:[],  //轮播图数据
    categoryList:[],//商品导航数据
    activeList:[],  //活动渲染区域
    hotList:[],//人气推荐
    guessList:[]//猜你喜欢
  },

  //获取首页数据
  async getIndexData(){
    //调用接口API函数,获取数据
    //reqIndexData内部使用all或者Promise.all
    //返回的是一个数组,是按照接口的调用数据来的
    const res=await reqIndexData()
    this.setData({
      bannerList:res[0].data,
      categoryList:res[1].data,
      activeList:res[2].data,
      hotList:res[3].data,
      guessList:res[4].data
    })

    console.log(res);
  },

  //监听页面的加载
  onLoad(){
    //在页面加载以后,调用获取首页数据的方法
    this.getIndexData()
  }
})

分析轮播图区域并渲染

实现轮播图和指示点的联动(当前高亮)

商品导航+活动区域+猜你喜欢+人..

首页骨架屏组件

骨架屏是页面的一个空白版本,开发者会使用CSS绘制一些灰色的区块,将页面内容大致勾勒出轮廓。

通常会在页面完全渲染之前,将骨架屏代码进行展示,待数据加载完成后,再替换成真实的内容。

相关推荐
Azhao11063 小时前
小程序购物车结算体验优化详解:从入门到实战全攻略
小程序
Haibakeji3 小时前
拼团小程序定制开发适合哪些行业
小程序·软件需求
2501_915918415 小时前
iOS性能数据监控:从概念到工具实践,让应用运行更流畅
android·macos·ios·小程序·uni-app·cocoa·iphone
silvia_Anne5 小时前
微信小程序(组件通讯和全局数据共享)
微信小程序·小程序
博客zhu虎康17 小时前
小程序:实现下拉刷新和上拉加载更多功能
小程序
2501_9159090621 小时前
全面解析前端开发中常用的浏览器调试工具及其使用场景
android·ios·小程序·https·uni-app·iphone·webview
王者鳜錸1 天前
企业解决方案十一-各类小程序定制开发
图像处理·人工智能·小程序·大模型·语音处理·定制开发
互联科技报1 天前
商城小程序选择哪家平台比较好?预算有限也能选对!
大数据·小程序
小盼江1 天前
Uniapp小程序鲜花商城推荐系统 买家卖家双端(web+uniapp)
前端·小程序·uni-app