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. 关于小程序获取手机号解密失败的踩坑历程
相关文章
相关标签/搜索