uni-app開發小程序總結

最近開發項目中使用 uni-app 開發了 微信小程序,整個體驗下來還算流暢,下面作一些總結:javascript

HBuilderX安裝

HBuilderX安裝的時候選擇標準版,不要下載APP開發版,至於uni-app編輯均可以在標準版裏面經過插件安裝或者是直接經過vue-cli命令行建立項目,另外就我我的使用以後,APP開發版編譯小程序的時候,有時候會致使編譯出來的小程序頁面空白(只剩下<page></page>)。css

微信開發者工具

HBuilderX運行/發佈微信小程序在編譯完成以後會嘗試打開微信開發者工具,實際上就是用命令行控制微信開發者工具(命令行 V2),這個須要在開發者工具的設置 -> 安全設置中開啓服務端口。html

建立項目

官方提供了HBuilderX可視化界面和vue-cli命令行兩種方式建立項目,不過cli版若是想安裝less、scss、ts等編譯器,需本身手動npm安裝。在HBuilderX的插件管理界面安裝無效,那個只做用於HBuilderX建立的項目。vue

代碼目錄

以HBuilderX可視化界面建立的項目:java

  1. components:組件文件,不用引入聲明,直接使用。
  2. pages:頁面git

    1. index:首頁
  3. static:靜態資源
  4. store:全局狀態管理中心
  5. unpackage:打包文件
  6. .gitignore:忽略文件,暫時忽略 unpackage 文件
  7. APP.vue:應用配置,用來配置App全局樣式以及監聽
  8. main.js:Vue初始化入口文件
  9. manifest.json:配置應用名稱、appid、logo、版本等打包信息
  10. pages.json:配置頁面路由、導航條、選項卡等頁面類信息
  11. uni.scss:總體控制應用的風格,https://uniapp.dcloud.io/coll...
  12. mixins:混入
  13. utils:工具,uni.request 和 uni.uploadFile 方法封裝
  14. config:配置文件github

    1. index.js:相似於vue.config.js
    2. theme.js:配置在js中使用的主題配置
  15. sitemap.json:配置頁面是否被索引

完整代碼可查看https://github.com/vueBlog/bl...vue-cli

代碼封裝

config -> index.js 配置信息

export default {
  loginExpiredCode: '', // 用戶信息過時的code
  token: 'token', // 若是使用到用戶信息,須要存儲token時,設置此token值,表示token的key
  publicPath: process.env.NODE_ENV === 'development' ? '' : '' // 配置請求的域名
}

utils -> request.js uni.request 和 uni.uploadFile 方法封裝

// uni.request 和 uni.uploadFile 方法封裝
import store from '../store'
import config from '../config'

export function request(options) {
  return new Promise((resolve, reject) => {
    uni.request({
      url: `${config.publicPath}${options.url}`, // 統一配置域名信息
      method: options.method,
      header: options.header || {
        'content-type': 'application/json',
        'token': store.state.token
      },
      data: options.data || {},
      success(res) {
        /**
         * https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.html
         * uni.showLoading 和 uni.showToast 同時只能顯示一個
         * 咱們通常會在發起請求的時候 uni.showLoading ,此處須要先 uni.hideLoading() ,才方便後面的提示信息
         */ 
        uni.hideLoading()
        if (res.statusCode === 200) {
          // code 看公司及我的定義
          if (res.data.code === 0) {
            resolve(res.data)
          } else {
            // 返回的信息須要報錯錯誤的msg,進行uni.showToast
            uni.showToast({
              title: res.data.msg,
              icon: 'none'
            })
            // 此處再根據code統一作一些相關處理,好比登陸過時等操做
            if(res.data.code === config.loginExpiredCode) {
              // 刪除本地Storage的token
              uni.removeStorageSync(config.token)
              // uni.showToast 默認顯示 1500ms ,以後跳轉到登陸頁面
              setTimeout(() => {
                uni.reLaunch({
                  url: 'pages/login/index'
                })
              }, 1500)
            }
            reject(res.data)
          }
        } else {
          // statusCode 不爲 200 的時候先報網絡出錯加 statusCode
          uni.showToast({
            title: `網絡出錯: ${res.statusCode}`,
            icon: 'none'
          })
        }
      },
      fail(err) {
        uni.hideLoading()
        uni.showToast({
          title: '網絡出錯',
          icon: 'none'
        })
        reject(err)
      }
    })
  })
}

export function upload(options) {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${config.publicPath}${options.url}`,
      filePath: options.filePath,
      name: options.name,
      formData: options.formData || {},
      header: {
        'content-type': 'multipart/form-data',
        'token': store.state.token
      },
      success(result) {
        uni.hideLoading()
        if (result.statusCode === 200) {
          /**
           * https://uniapp.dcloud.io/api/request/network-file
           * data    String    開發者服務器返回的數據
           */
          const res = JSON.parse(result.data)
          if (res.code === 0) {
            resolve(res)
          } else {
            uni.showToast({
              title: res.msg,
              icon: 'none'
            })
            if(res.code === config.loginExpiredCode) {
              uni.removeStorageSync(config.token)
              setTimeout(() => {
                uni.reLaunch({
                  url: 'pages/login/index'
                })
              }, 1500)
            }
            reject(res)
          }
        } else {
          uni.showToast({
            title: `網絡出錯: ${result.statusCode}`,
            icon: 'none'
          })
        }
      },
      fail(err) {
        uni.hideLoading()
        uni.showToast({
          title: '網絡出錯',
          icon: 'none'
        })
        reject(err)
      }
    })
  })
}

網絡監控

我是在全局放了網絡監控,當斷網的時間彈出斷網彈窗禁止操做,再次聯網的時間,關閉彈窗。npm

App.vue :json

<script>
export default {
    onLaunch: function() {
        console.log('App Launch');
        uni.onNetworkStatusChange(({isConnected}) => {
      if (isConnected) {
        uni.hideToast()
      } else {
        uni.hideToast()
        uni.showToast({
          title: '您已斷網',
          icon: 'none',
          mask: true,
          duration: 6000000
        })
      }
    })
    },
    onShow: function() {
        console.log('App Show');
    },
    onHide: function() {
        console.log('App Hide');
    }
};
</script>

遇到的一些問題及解決方法

  1. 微信小程序用戶受權彈窗,獲取用戶信息。用戶拒絕受權時,引導用戶去從新受權
  2. 關於小程序獲取手機號解密失敗的踩坑歷程
相關文章
相關標籤/搜索