02_微信小程序常用的方法封裝

 

消息提示框封裝:

//消息提示框封裝
/**
// 提示的內容
  title: '消息提示框', // 提示的內容
  icon: 'success',   // 提示的圖標,success(成功)、error(失敗)、loading(加載)、none(不顯示圖標)
  duration: 2000,     // 提示的延遲時間
  mask: true         // 是否顯示透明蒙層,防止觸摸穿透
 */

const toast = ({ title = '數據加載中', icon = 'none', mask = true, duration = 3000 } = {}) => {
  wx.showToast({
    title,
    icon,
    mask,
    duration
  })
}
//掛載到全局
wx.toast=toast;
//導出
export {toast}

調用

//import {toast} from './utils/extendApi'
import './utils/extendApi'

//toast()
    //toast({"title":"成功","icon":"success"})
    //wx.toast();
    wx.toast({"title":"成功","icon":"success"})

----------------------------------------------------------漂亮的分割線----------------------------------------------------------------------------------------

消息對話框封裝:

wx.showModal({
      title: '提示', // 提示的標題
      content: '您確定執行該操作嗎?', // 提示的內容
      confirmColor: '#f3514f',
      // 接口調用結束的回調函數(調用成功、失敗都會執行)
      complete({ confirm, cancel }) {
        confirm && console.log('點擊了確定')
        cancel && console.log('點擊了取消')
      }
    })

封裝

const modal = (options = {}) => {
  // 使用 Promise 處理 wx.showModal 的返回結果
  return new Promise((resolve) => {
    // 默認的參數
    const defaultOpt = {
      title: '提示',
      content: '您確定執行該操作嗎?',
      confirmColor: '#f3514f',
    }
    // 將傳入的參數和默認的參數進行合併
    const opts = Object.assign({}, defaultOpt, options)
    wx.showModal({
      // 將合併的參數賦值傳遞給 showModal 方法
      ...opts,
      complete({ confirm, cancel }) {
        // 如果用戶點擊了確定,通過 resolve 拋出 true
        // 如果用戶點擊了取消,通過 resolve 拋出 false
        confirm && resolve(true)
        cancel && resolve(false)
      }
    })
  })
}

wx.modal = modal
//導出
export { modal }

如果全局使用:export const modal = (options = {}) => {

刪除:export { toast,modal }

使用:

import {modal} from './utils/extendApi'
//import './utils/extendApi'
App({
  async onShow(){
    // 第一種調用方式:不傳入任何參數
    // 不使用任何參數,使用默認值
    //const res = await modal()
    //console.log(res)

    // 第二種調用方式:更改默認配置
    const res = await modal({
      content: '鑑權失敗,請重新登錄',
      showCancel: false
    })
    console.log(res)
  }
})

 

----------------------------------------------------------漂亮的分割線----------------------------------------------------------------------------------------

封裝本地存儲

/**
 * @description 存儲數據
 * @param {*} key 本地緩存中指定的 key
 * @param {*} value 需要緩存的數據
 */
export const setStorage = (key, value) => {
  try {
    wx.setStorageSync(key, value)
  } catch (e) {
    console.error(`存儲指定 ${key} 數據發生錯誤:`, e)
  }
}

/**
 * @description 從本地讀取對應 key 的數據
 * @param {*} key 
 */
export const getStorage = (key) => {
  try {
    const value = wx.getStorageSync(key)
    if (value) {
      return value
    }
  } catch (e) {
    console.error(`獲取指定 ${key} 數據發生錯誤:`, e)
  }
}

/**
 * @description 從本地移除指定 key 數據
 * @param {*} key 
 */
export const removeStorage = (key) => {
  try {
    wx.removeStorageSync(key)
  } catch (e) {
    console.error(`移除指定 ${key} 數據發生錯誤:`, e)
  }
}

/**
 * @description 從本地清空全部的數據
 */
export const clearStorage = () => {
  try {
    wx.clearStorageSync()
  } catch (e) {
    console.error("清空本地存儲時發生錯誤:", e);
  }
}





/**
 * @description 將數據存儲到本地 - 異步方法
 * @param {*} key 本地緩存中指定的 key
 * @param {*} data 需要緩存的數據
 */
export const asyncSetStorage = (key, data) => {
  return new Promise((resolve) => {
    wx.setStorage({
      key,
      data,
      complete(res) {
        resolve(res)
      }
    })
  })
}

/**
 * @description 從本地讀取指定 key 的數據 - 異步方法
 * @param {*} key
 */
export const asyncGetStorage = (key) => {
  return new Promise((resolve) => {
    wx.getStorage({
      key,
      complete(res) {
        resolve(res)
      }
    })
  })
}

/**
 * @description 從本地移除指定 key 的數據 - 異步方法
 * @param {*} key
 */
export const asyncRemoveStorage = (key) => {
  return new Promise((resolve) => {
    wx.removeStorage({
      key,
      complete(res) {
        resolve(res)
      }
    })
  })
}

/**
 * @description 從本地移除、清空全部的數據 - 異步方法
 */
export const asyncClearStorage = () => {
  return new Promise((resolve) => {
    wx.clearStorage({
      complete(res) {
        resolve(res)
      }
    })
  })
}
View Code

 

調用:

import {setStorage,getStorage,removeStorage,clearStorage,asyncSetStorage,asyncGetStorage} from './utils/storage'

App({

  async onShow(){
    setStorage('name','張三')
    let _name= getStorage('name')
    console.log(_name)

    asyncSetStorage('age',28).then((res)=>{
      console.log(res.errMsg)
    })
    asyncGetStorage('age').then((res)=>{
      console.log(res.data)
    })

  }
})

 

----------------------------------------------------------漂亮的分割線----------------------------------------------------------------------------------------

網絡請求封裝

// 創建 WxRequest 類
// 通過類的方式來進行封裝,會讓代碼更加具有複用性
// 也可以方便添加新的屬性和方法

class WxRequest {
  // 定義實例屬性,用來設置默認請求參數
  defaults = {
    baseURL: '', // 請求基準地址
    url: '', // 接口的請求路徑
    data: null, // 請求參數
    method: 'GET', // 默認的請求方法
    // 請求頭
    header: {
      'Content-type': 'application/json' // 設置數據的交互格式
    },
    timeout: 60000, // 默認的超時時長,小程序默認的超時時長是 1 分鐘
    isLoading: true // 控制是否使用默認的 loading,默認值是 true 表示使用默認的 loading
  }

  // 定義攔截器對象
  // 需要包含請求攔截器以及響應攔截器,方便在請求之前以及響應以後時進行邏輯處理
  interceptors = {
    // 請求攔截器
    // 在請求發送之前,對請求參數進行新增或者修改
    request: (config) => config,

    // 響應攔截器
    // 在服務器響應數據以後,對服務器響應的數據進行邏輯處理
    response: (response) => response
  }

  // 定義數組隊列
  // 初始值需要是一個空數組,用來存儲請求隊列、存儲請求標識
  queue = []

  // 用於創建和初始化類的屬性以及方法
  // 在實例化時傳入的參數,會被 constructor 形參進行接收
  constructor(params = {}) {
    // 通過 Object.assign 方法合併請求參數
    // 注意:需要傳入的參數,覆蓋默認的參數,因此傳入的參數需要放到最後
    this.defaults = Object.assign({}, this.defaults, params)
  }

  // request 實例方法接收一個對象類型的參數
  // 屬性值和 wx.request 方法調用時傳遞的參數保持一致
  request(options) {
    // 如果有新的請求,就清除上一次的定時器
    this.timerId && clearTimeout(this.timerId)

    // 注意:需要先合併完整的請求地址 (baseURL + url)
    // https://gmall-prod.atguigu.cn/mall-api/index/findBanner
    options.url = this.defaults.baseURL + options.url

    // 合併請求參數
    options = { ...this.defaults, ...options }

    // 在請求發送之前,添加 loading 效果
    // wx.showLoading()

    if (options.isLoading && options.method !== 'UPLOAD') {
      // 判斷 queue 隊列是否爲空,如果是空,就顯示 loading
      // 如果不是空,就不顯示 loading,不調用 wx.showLoading()
      this.queue.length === 0 && wx.showLoading()

      // 然後立即向 queue 數組隊列中添加請求標識
      // 每個標識代表是一個請求,標識是自定義的
      this.queue.push('request')
    }

    // 在請求發送之前,調用請求攔截器,新增和修改請求參數
    options = this.interceptors.request(options)

    // 需要使用 Promise 封裝 wx.request,處理異步請求
    return new Promise((resolve, reject) => {
      if (options.method === 'UPLOAD') {
        wx.uploadFile({
          ...options,

          success: (res) => {
            // 需要將服務器返回的 JSON 字符串 通過 JSON.parse 轉成對象
            res.data = JSON.parse(res.data)

            // 合併參數
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            })

            resolve(this.interceptors.response(mergeRes))
          },

          fail: (err) => {
            // 合併參數
            const mergeErr = Object.assign({}, err, {
              config: options,
              isSuccess: false
            })

            reject(this.interceptors.response(mergeErr))
          }
        })
      } else {
        wx.request({
          ...options,

          // 當接口調用成功時會觸發 success 回調函數
          success: (res) => {
            // 不管是成功響應還是失敗響應,都需要調用響應攔截器
            // 響應攔截器需要接收服務器響應的數據,然後對數據進行邏輯處理,處理好以後進行返回
            // 然後在通過 resolve 將返回的數據拋出去

            // 在給響應攔截器傳遞參數時,需要將請求參數也一起傳遞
            // 方便進行代碼的調試或者進行其他邏輯處理,需要先合併參數
            // 然後將合併的參數傳遞給響應攔截器

            // 不管是請求失敗還是請求成功,都已經將響應的數據傳遞給了響應攔截器
            // 這時候在合併參數的時候,追加一個屬性:isSuccess
            // 如果屬性值爲 true,說明執行了 success 回調函數
            // 如果屬性值爲 false,說明執行了 fail 回調函數
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            })
            resolve(this.interceptors.response(mergeRes))
          },

          // 當接口調用失敗時會觸發 fail 回調函數
          fail: (err) => {
            // 不管是成功響應還是失敗響應,都需要調用響應攔截器
            const mergeErr = Object.assign({}, err, {
              config: options,
              isSuccess: false
            })
            reject(this.interceptors.response(mergeErr))
          },

          // 接口調用結束的回調函數(調用成功、失敗都會執行)
          complete: () => {
            if (options.isLoading) {
              // 在每一個請求結束以後,都會執行 complete 回調函數
              // 每次從 queue 隊列中刪除一個標識
              this.queue.pop()

              this.queue.length === 0 && this.queue.push('request')

              this.timerId = setTimeout(() => {
                this.queue.pop()

                // 在刪除標識以後,需要判斷目前 queue 數組是否爲空
                // 如果是空,說明併發請求完成了
                // 就需要隱藏 loading,要調用 wx.hideLoading()
                this.queue.length === 0 && wx.hideLoading()

                clearTimeout(this.timerId)
              }, 1)

              // 不管請求時成功還是失敗,都需要隱藏 loading
              // wx.hideLoading()
            }
          }
        })
      }
    })
  }

  // 封裝 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))
  }

  // 用來處理併發請求
  all(...promise) {
    // 通過展開運算符接收傳遞的參數
    // 那麼展開運算符會將傳入的參數轉成數組
    // console.log(promise)

    return Promise.all(promise)
  }

  /**
   * @description upload 實例方法,用來對 wx.uploadFile 進行封裝
   * @param {*} url 文件的上傳地址、接口地址
   * @param {*} filePath 要上傳的文件資源路徑
   * @param {*} name 文件對應的 key
   * @param {*} config 其他配置項
   */
  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({ url, filePath, name, method: 'UPLOAD' }, config)
    )
  }
}

export default WxRequest

 

----------------------------------------------------------漂亮的分割線----------------------------------------------------------------------------------------

mina-request的安裝

網站:mina-request - npm (npmjs.com)

安裝命令:npm install mina-request

工具——>構建npm

 

 

http.js

// 導入模塊、包提供的類
import WxRequest from 'mina-request'
// 導入封裝的本地存儲操作模塊
import { getStorage, clearStorage } from './storage'
// 導入封裝的增強 API
import { toast, modal } from './extendApi'

// 對類進行實例化
const instance = new WxRequest({
  baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
  timeout: 15000
  
})

// 添加請求攔截器 (在請求發送之前對請求參數進行新增或者修改)
instance.interceptors.request = (config) => {
  // 在實際開發中,有一些接口需要使用訪問令牌 token
  // 訪問令牌 token 通常是存儲到本地
  // 需要先從本地獲取到存儲的 token
  const token = getStorage('token')

  // 如果本地存在 token,這時候就需要在請求頭中添加 token 字段
  if (token) {
    config.header['token'] = token
  }

  // 在發送請求之前做些什麼
  return config
}

// 添加響應攔截器 (在服務器響應數據以後,對返回的數據進行邏輯處理)
instance.interceptors.response = async (response) => {
  // 從 response 對象中解構兩個數據
  const { isSuccess, data } = response

  // response 服務器響應的數據,只不過數據被 wx.request 進行了一層包裝
  // console.log(response)

  // response.config 封裝的包裏面提供的 config 屬性,是請求的參數信息
  // 可以使用請求參數進行代碼的調試

  // response.data 服務器真正響應的數據

  // response.isSuccess 判斷代碼執行了哪一個回調函數
  // isSuccess = true,說明代碼執行了 wx.request 方法的 success 回調函數
  // isSuccess = false,說明代碼執行了 wx.request 方法的 fail 回調函數

  // 如果 isSuccess = false,說明網絡出現了問題
  if (!isSuccess) {
    toast({
      title: '網絡異常請重試',
      icon: 'error'
    })

    return Promise.reject(response)
  }

  // 如果 isSuccess = true,說明代碼執行到了 success 回調函數
  // 需要開發者對返回的參數進行邏輯判斷
  // 需要對後端返回的業務狀態碼進行判斷
  // 業務狀態碼 === 200,接口調用成功,服務器成功返回了數據
  // 業務狀態碼 === 208,沒有 token 或者 token 失效,需要讓用戶重新進行登錄
  // 業務狀態碼既不等於 200,也不等於 208,說明出現了其他異常,需要給用戶統一進行提示
  switch (data.code) {
    case 200:
      // 接口調用成功,服務器成功返回了數據,只需要將數據簡化以後返回即可
      return data

    case 208:
      const res = await modal({
        content: '鑑權失敗,請重新登錄',
        showCancel: false
      })

      if (res) {
        // 既然用戶需要重新進行登錄,就需要把之前用戶存儲的信息(過期的 token) 進行清除
        clearStorage()

        wx.navigateTo({
          url: '/pages/login/login'
        })
      }

      return Promise.reject(response)

    default:
      toast({
        title: '程序出現異常,請聯繫客服或稍後重試!'
      })
      return Promise.reject(response)
  }

  // return response
}

// 導出實例
export default instance

 

接口地址環境變量設置

添加env.js 

// 獲取 小程序帳號信息
const { miniProgram } = wx.getAccountInfoSync()

// 獲取小程序當前開發環境
// develop 開發版, trial 體驗版, release 正式版
const { envVersion } = miniProgram

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

switch (envVersion) {
  //開發版
  case 'develop':
    env.baseURL = 'https://gmall-prod.atguigu.cn'
    break
  //體驗版
  case 'trial':
    env.baseURL = 'https://gmall-prod.atguigu.cn'
    break
  //正式版
  case 'release':
    env.baseURL = 'https://gmall-prod.atguigu.cn'
    break

    defaulr
}

export { env }

 

http.js

// 導入模塊、包提供的類
import WxRequest from 'mina-request'
// 導入封裝的本地存儲操作模塊
import { getStorage, clearStorage } from './storage'
// 導入封裝的增強 API
import { toast, modal } from './extendApi'

import {env} from './env'

// 對類進行實例化
const instance = new WxRequest({
  //baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
  baseURL:env.baseURL,
  timeout: 15000,
  isLoading:false
  
})

 

模塊API封裝

index.js

// 導入封裝的網絡請求工具 http.js
import http from '../utils/http'

/**
 * @description 獲取輪播圖數據
 * @returns Promise
 */
export const reqSwiperData = () => http.get('/mall-api/index/findBanner')
// 導入接口 API
import { reqSwiperData } from '../../api/index'

Page({
    
  // 頁面數據
  data: {
    swiperList: []
  },
  
  // 小程序頁面加載時執行
  onLoad () {
    // 調用獲取首頁數據的方法
    getHomeList()
  }
    
  // 獲取首頁數據
  async getHomeList() {
    // 獲取輪播圖數據
    const res = await reqSwiperData()
    
    console.log(res)
  }
})

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章