波多野吉不卡中文Av无码Av

      <strong id="fzzds"><track id="fzzds"></track></strong>
    1. <strong id="fzzds"></strong>
      <strong id="fzzds"></strong>
    2. <ruby id="fzzds"><bdo id="fzzds"><rp id="fzzds"></rp></bdo></ruby>
        <strike id="fzzds"></strike>
      1. 您現在的位置: 微信小程序 > 微信小程序運營 > 經驗 >

        人人都該具備封裝思維:Taro+Es6+Promise+Ts簡易構建微信小程序的全局請求方法

        來源:微信小程序 編輯:Yiyongtong.com 發布時間:2020-05-18 10:43熱度:

        無論是app還是小程序或者其他端,交互中請求無處不在。

        一個優秀的封裝類,能讓你的開發效率事半功倍,所以封裝邏輯至關重要,當然我也是個小菜鳥,跟著自己的思路寫過一些封裝方法,一方面是想不足之處還望路過的大神給予指正,二者是為新手打開一個善于封裝思維的大門,下面進入到前置知識。

        Api: cnodejs.org/api/v1

        Ts: 簡易的類型聲明、接口等

        Es6:結構賦值、擴展運算、promise、export等

        Taro:類react,以及小程序基礎知識等

        1.梳理Taro的請求 Taro.request,實現最簡易的請求方法

        import Taro from '@tarojs/taro'
        //回調調用
        function doRequestAction(){
          Taro.request({
            url: '',
            data: {},
            header: {},
            success: res => {},
            fail: err => {},
            complete: info => {}
          })
        }
        // promise調用
        function doRequestAction(){
          Taro.request({
            url: '',
            data: {},
            header: {}
          })
          .then(res=>{})
          .catch(err=>{})
          .finally(()=>{})
        }
        復制代碼

        其中利弊不多做介紹,我們將會用到promise的請求方式。

        2.梳理會用到的請求結構,以及定義的文件分類:

        • 接口地址,也就是我們常說的url,存放于api.ts文件中
        • 請求方法,也就是我們封裝的方法,我們存放于request.ts文件中
        • 接口類型,也就是我們聲明數據類型的文件,我們存放于inter.d.ts文件中
        • 配置文件,常用的全局請求域名,其他不動參數等,我們這里只是簡單的示例因此不需要,如果有需要請大家自行配置
        文件名 作用
        api.ts 存放接口地址、以及統一請求域名前綴
        request.ts 封裝公共請求方法、以及調用方法集合
        inter.d.ts ts的聲明文件,主要存放返回值類型,請求參數類型等

        3.接入promise聲明自己的方法并返回自己的promise請求對象

        我這里盡量寫es6寫法讓大家在今后的項目開發中更加順暢的使用,當然在自己的項目中請結合實際情況使用,不要盲目的接入一些新的寫法。下面進入知識點梳理:

        • 請求是否loading,真 ? 結束隱藏loading : ' '
        • loading層是否開啟mask
        • loading文字參數可自定義
        • 請求失敗是否彈出我們的報錯信息
        • url在不以http/https的情況下使用自定義接口
        import Taro from '@tarojs/taro'
        // 暫時考慮 req的屬性都會傳入
        const doRequestAction = (req) => {
          return new Promise((resolve, reject) => {
            if (req.loading) Taro.showLoading({ title: req.title ? req.title : '數據加載中...' })
            Taro.request({
              url: /^http(s?):\/\//.test(req.url) ? req.url : '', //暫時留空
              method: 'POST',
              data: {},
              header: { 'content-type': 'application/x-www-form-urlencoded' }
            })
            .then(res => {})
            .catch(err => { 
                //報錯提示 
            })
            .finally(() => {
              if (req.loading) Taro.hideLoading()
            })
          })
        }
        復制代碼

        4.分離請求參數并使用ts聲明傳入值與類型

        1.將使用到的參數進行分離 2.每個參數給出默認值,如果不傳人將用默認值代替 3.使用ts聲明參數類型

        export interface RequestBase {
          url: string, //字符串
          method: 'POST' | 'GET', //常規請求方式,根據項目要求添加
          data: any, // 每次的參數都是不固定的,因此我們暫時不聲明數據類型
          header: RequestHeader, // 下面的requestheader類型,
          loading: boolean, // 請求是否開啟loading層
          mask: boolean, //開啟loading層的情況下是否不能點擊,全屏遮罩
          title: string, //開啟loading層的提示內容
          failToast: boolean //如果請求是否,我是否直接彈出我的提示
        }
        
        export interface RequestHeader {
          'content-type': string // 表示content-type類型必須聲明
        }
        復制代碼

        上面的header,我重新定義了一個接口來聲明類型,是為了更方便的去管理這個數據,試想如果我們平時需要將用戶的token帶入到header里面,那么我們就會在RequestHeader中在聲明一個token字段。

        所謂的接口也就相當于我們這個數據里面有什么字段,字段是什么類型。

        所以,我們在header中在加入token字段,實際項目中,可能還會帶入加密串,時間,以及其他的輔助驗證字段,這里只為了大家方便開發做出示例,實際還需看項目聲明。

        特殊提醒:ts是可以不加逗號的

        export interface RequestHeader {
          'content-type': string // 表示content-type類型必須聲明
          token: string
        }
        復制代碼

        聲明我們的默認參數,在用戶沒有參數傳入的情況下,將會使用我們的默認參數來輔助請求。

        // 使用默認參數,當數據不傳入指定字段時替代
        const NormalRquestData: RequestBase = {
          url: api.DOMAIN, // 默認請求地址
          method: 'GET', // 默認get請求
          header : { // 默認使用的header頭
            "content-type": 'application/x-www-form-urlencoded',
            token: ''
          },
          data: {}, // 默認沒有參數,傳入空對象
          loading: true, //默認開啟loading層
          mask: true, //請求時不需要點擊
          title: '數據加載中', //loading提示文字
          failToast: false // 一般我們會處理相應業務邏輯,就不直接提示阻斷流程
        }
        復制代碼

        思考問題,我們如果每次動態 帶上我們token? 用戶剛開始進入小程序,這時可能是沒有授權,后面授權了我們要及時更新token來達到用戶交互目的 這時我們可以將header提出,當然我一般會在我的狀態管理中操作,這里做個例子為大家提供思路。

        • 將token作為可選字段
        • 封裝方法每次請求動態提取token
        • 方法返回類型為我們定義的RequestHeader類型
        // inter.d.ts
        export interface RequestHeader {
          'content-type': string // 表示content-type類型必須聲明
          token?: string // token可能不存在,如果存在就是字符串類型
        }
        //request.ts 獲取header頭 返回值是RequestHeader類型
        const getRequestHeader = (): RequestHeader => {
          let token: string = Taro.getStorageSync('token')
          return token ? {
            "content-type": 'application/x-www-form-urlencoded',
            token: token
          } : {
            "content-type": 'application/x-www-form-urlencoded'
          }
        }
        復制代碼

        5.在參數某些字段不傳入的情況下,我們使用自己的參數字段進行默認填充

        思考問題:RequestBase參數都是必傳,但是我們的請求的時候參數都是可傳,如果我們將其都改為可選參數,這個時候如果我們使用req.title(loading標題)、req.url('請求api地址') 在ts的檢測下,這些參數都是可能不存在的,這樣我們會寫大量判斷,那么我們的代碼就會變得相當糟糕~!因此我們再聲明一個接口用來可選參數的規范。

        // 遍歷RequestBase中所有key,都改為可選參,這樣我們就只管維護RequestBase
        type Request = {
          [K in keyof RequestBase]?: RequestBase[K]
        }
        復制代碼

        改造請求方法,并聲明各個類型,使ts更加規范, 將接口類使用inter導入,也將之前的api改成Api統一首字母大寫

        import Taro from '@tarojs/taro'
        import * as Api from './api'
        import * as Inter from './inter.d'
        
        
        // 請求傳入reqData參數   返回promise對象 因為全局請求我每次返回的類型都是不一樣的,所以我直接any
        const doRequestAction = (reqData: Inter.Request): Promise<any> => {
          // 將不存在的參數字段使用默認值進行替換
          let req: Inter.RequestBase = { ...NormalRquestData, ...reqData }
          return new Promise((resolve, reject) => {
            //檢測是否開啟loading層 是否打開msak
            if (req.loading) Taro.showLoading({ title: req.title, mask: req.mask })
            Taro.request({
              url: req.url, //引入我的接口是特殊聲明的,所以我就不檢測http/https了
              method: req.method,
              data: req.data,
              header: req.header
            })
            .then(res => {
              // 大多數請求中 success并不代表成功,需要我們自己檢測statusCode來確保
              if (res.statusCode === 200) {
                resolve(res.data) // 成功
              } else {
                // 如果失敗 檢測是否直接提示信息
                if(req.failToast) Taro.showToast({ title: '網絡不好,請求失??!' })
                reject(res) // 失敗
              }
            })
            .catch(err => {
              // 如果失敗 檢測是否直接提示信息
              if (req.failToast) Taro.showToast({ title: '網絡不好,請求失??!' })
              reject(err)
            })
            .finally(() => {
              // 請求結束 關閉loading層
              if (req.loading) Taro.hideLoading()
            })
          })
        }
        復制代碼

        ok,請求方法寫到這里我們暫時只能告一段落了

        6.完善api.ts,聲明全局域名以及每個接口的定義.

        //定義全局請求地址,因為我們用到的地址是https://cnodejs.org/api/v1
        export const DOMAIN: string = 'https://cnodejs.org/'
        // 聲明獲取主題首頁接口地址并導出
        export const topics: string = DOMAIN + 'api/v1/topics'
        復制代碼

        7.觀察api,聲明請求data文件,以及使用請求并返回promise以及返回類型 返回類型: cnodejs.org/api/v1/topi… 自己觀察我就不截圖了。

        // 請求主題接口參數類型
        export interface TOPICSDATA {
          page: number,
          tab: 'ask' | 'share' | 'job' | 'good',
          limit: number,
          mdrender?: boolean
        }
        // 獲取主題的接口
        export interface TOPICS {
          id: string,
          author_id: string,
          tab: string,
          content: string,
          title: string,
          last_reply_at: string,
          good: boolean,
          top: boolean,
          reply_count: number,
          visit_count: number,
          create_at: string,
          author: TOPICSAUTHOR
        }
        // 作者的類型
        export interface TOPICSAUTHOR {
          loginname: string,
          avatar_url: string
        }
        復制代碼

        8.自定義獲取方法,結合自己的請求方法返回新的promise對象

        // 調用封裝方法 返回promise對象 得到獲取到的數據
        const getTopics = (data: Inter.TOPICSDATA): Promise<Inter.TOPICS> => {
          return doRequestAction({
            url: Api.topics,
            data: data
          })
        }
        復制代碼

        9. 頁面內可以調用getTopics方法拿到我們的數據

        import { getTopics } from '../../utils/request/request'
        import { TOPICSDATA } from '../../utils/request/inter'
        
        useEffect(()=>{
            let data: TOPICSDATA= {
              page: 1,
              tab: 'ask',
              limit: 10
            }
            getTopics(data).then(res=>console.log(res))
          },[])
        復制代碼

        至此,一個簡易的封裝就完美的結束了,但是在實際開發中為了自己的便利,我們會封裝很多經常使用到的參數,這里只是提供一個封裝思維,具體還需要在大家的項目中去思考怎么才能去優化代碼。

        10.總結

        知識點

        • es6語法: ...展開運算, 解構賦值, promise
        • ts:類型聲明, 可選項, type , any類型 ,單個類型定義
        • 封裝思維,文件拆分

        相關閱讀

        波多野吉不卡中文Av无码Av

          <strong id="fzzds"><track id="fzzds"></track></strong>
        1. <strong id="fzzds"></strong>
          <strong id="fzzds"></strong>
        2. <ruby id="fzzds"><bdo id="fzzds"><rp id="fzzds"></rp></bdo></ruby>
            <strike id="fzzds"></strike>