小程序

mpvue小程序架构搭建详细介绍

前言

mpvue小程序框架搭建很容易,官网提供vue init mpvue/mpvue-quickstart my-project, 很迅速的创建项目,但是想要结合业务等,还是要废一番功夫,今天来学学wx.request的封装,mpvue的重构,如何搭建好用的mpvue小程序架构吧

创建项目

  1. 由于国内npm镜像慢的原因,考虑先把npm切到淘宝镜像。
npm set registry https://registry.npm.taobao.org/
  1. 全局安装vue-cli
npm install --global vue-cli@2.9
  1. 创建一个基于 mpvue-quickstart 模板的新项目, 一路回车选择默认就可以了
vue init mpvue/mpvue-quickstart mpvue-project
  1. 安装依赖
cd mpvue-project
npm install
npm run dev

到这里,你的项目已经能跑起来了,可以打开小程序调试工具预览效果,但是仅仅是能玩儿而已,下面更精彩。

全局图片,接口配置

  1. 找到项目(mpvue-project)下方的config->index.js文件,里面有两个对象,builddev,分别对应生产环境和开发环境,意思是你运行npm run dev读的就是dev里面变量,npm run bulid读的就是build的变量
    mpvue小程序架构搭建详细介绍
    这里我增加了3个变量,后续用到(这里的图片端口就是上图中的port)
    接口请求地址(如:baseApi: 'https://www.javanx.cn/rest')
    图片访问地址(如:imgPath: 'http://localhost:8070')
    web-view地址(如:baseUrl: 'https://www.javanx.cn/')

  2. 来到项目(mpvue-project)下方的build->utils.js文件,添加下方代码

var config = require('../config')
const fs = require('fs');

var imgUrlPrefix = process.env.NODE_ENV === 'production'
    ? config.build.imgPath
    : config.dev.imgPath
var cssImgStr = `$imgUrlPrefix = '` + imgUrlPrefix + `';`;

fs.writeFileSync(`./src/css/imgUrlPrefix.styl`, cssImgStr);

const BASE_API = process.env.NODE_ENV === 'production'
    ? config.build.baseApi
    : config.dev.baseApi;
const BASE_URL = process.env.NODE_ENV === 'production'
    ? config.build.baseUrl
    : config.dev.baseUrl;

fs.writeFileSync(`./src/commons/baseApi.js`, `module.exports = {IMG_API: '`+imgUrlPrefix+`', BASE_API: '`+BASE_API+`', BASE_URL: '`+BASE_URL+`'}\r\n`);

process.env.NODE_ENV是判断你输入的命令是什么(构建到dev还是生产),然后写入两个文件,一个是styl文件,一个是js文件,分别存放根据环境的全局变量
用到的地方之间引入这两个文件,如:

index.styl中需要用到一个图片

@require  "./imgUrlPrefix.styl"
.icon-more-right
  position absolute
  display block
  width px2rpx(44px)
  height px2rpx(44px)
  right 0
  top 50%
  margin-top px2rpx(-22px)
  background url($imgUrlPrefix + "/images/right.png") center no-repeat
  background-size 100% 100%

index.js中需要用到BASE_API,如

import {BASE_API} from './baseApi'

图片这样的好处是,图片都不用打包到项目里面了,减少了小程序的体积,本身小程序体积有限。
所以就可以去掉打包static到dist的配置了
来到项目(mpvue-project)下方的build->webpack.base.conf.js文件,去掉下方代码

new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: path.resolve(__dirname, '../dist/static'),
    ignore: ['.*']
  }
])

封装wx.request

取名叫http.js

import Loading from './gloading'
import {BASE_API} from './baseApi'

const gloading = new Loading({
  sync: true
})
function request (options) {
  return new Promise((resolve, reject) => {
    // 遮罩,默认不显示菊花
    if (options.mask) {
      // 这里写菊花转
      gloading.start()
      // delete options.mask;
    }
    const headers = (options.header = options.header || {})
    // 是否要设置token
    if (!options.noToken && options.token !== false) {
      // headers['x-auth-token'] = 'ad6b5cbd-010e-4dee-aabc-884790d1e288';
      headers['x-auth-token'] = wx.getStorageSync('x-auth-token')
      delete options.token
    }
    // 对所有request请求中的OBJECT参数对象统一附加时间戳属性
    options.timestamp = +new Date()
    let url = options.url
    // 简化类型设置
    if (options.json === false) {
      headers['content-type'] =
        'application/x-www-form-urlencoded; charset=UTF-8'
      delete options.json
    }
    url = BASE_API + url
    wx.request({
      url: url,
      data: options.data,
      header: headers,
      method: options.method,
      success: (res) => {
        if (options.mask) {
          gloading.stop()
        }
        if (res.statusCode === 200) {
          resolve(res)
        } else {
          // 判断错误码
          // 比如这里1003是用户登录过期,token是否失效
          switch (res.data.code) {
            case 1003:
              console.log('------------token变更,重新授权-----------')
              var pages = global.getCurrentPages() // 获取加载的页面
              var currentPage = pages[pages.length - 1] // 获取当前页面的对象
              var url = currentPage.route // 当前页面url
              // 调用授权登录接口,获取新的token
              authorize(() => {
                // 获取用户信息,验证新token
                getUserInfo((data) => {
                  // 成功代表成功,跳转到之前的页面
                  console.log('------------获取用户信息成功-----------')
                  wx.redirectTo({
                    url: '/' + url + ''
                  })
                }, (err) => {
                  // 失败跳回登录页面
                  console.log('-----------获取用户信息失败------------')
                  if (url !== 'pages/user/login' && err.data.code === 1003) {
                    wx.showToast({
                      icon: 'none',
                      mask: true,
                      title: res.data.message,
                      duration: 3000
                    })
                    wx.redirectTo({
                      url: '/pages/user/login'
                    })
                  }
                })
              })
              break
            default:
              let message = res.data.message
              wx.showToast({
                icon: 'none',
                mask: true,
                title: res.data.message,
                duration: 3000
              })
          }
          reject(res)
        }
      },
      fail: (res) => {
        reject(res)
      },
      complete: (res) => {
        if (options.mask) {
          gloading.stop()
        }
      }
    })
  })
}

request.all = (arr) => {
  return Promise.all(arr.map(n => request(n)))
}
export default request

这里的authorizegetUserInfo方法需要自己去写具体业务,同时上面用到的wx.getStorageSync('x-auth-token')是在authorize方法成功后,返回的token,存在Storage里面了wx.setStorageSync('x-auth-token', res.header['x-auth-token'])
上面用到了一个gloading插件

gloading插件

取名gloading.js

class Loading {
  constructor (options) {
    this.queueNum = 0
    options = this._options = options || {}
    if (!options.title) {
      options.title = '请等待...'
    }
  }

  start () {
    if (this._options.sync) {
      this.queueNum += 1
    }
    this._start()
    return this
  }

  _start () {
    wx.showLoading({
      title: this._options.title,
      mask: true
    })
  }

  stop (force) {
    if (this._options.sync) {
      this.queueNum -= 1
    }
    if (this.queueNum <= 0 || force) {
      this.queueNum = 0
      this._stop()
    }
    return this
  }

  _stop () {
    wx.hideLoading()
  }
}
export default Loading

去掉目录的main.js

mpvue每个页面必须对应一个main.js,导致每个页面都需要建一个目录,目录下方建一个main.js,感觉非常的繁琐
有大神开发了mpvue-entry插件
1. 安装插件

npm install mpvue-entry
  1. 来到项目(mpvue-project)下方的build->webpack.base.conf.js文件
const MpvueEntry = require('mpvue-entry')

module.exports = {
  entry: MpvueEntry.getEntry('src/pages.js'),
  ...
  plugins: [
    new MpvueEntry(),
    ...
  ]
}
  1. src目录下新建pages.js
module.exports = [{
  path: 'pages/news/list', // 页面路径,同时是 vue 文件相对于 src 的路径,必填
  config: { // 页面配置,即 page.json 的内容,可选
    navigationBarTitleText: 'Javan的博客',
    enablePullDownRefresh: true
  }
}]

这样就没有建n个目录,n个main.js了

推荐

快速搭建mpvue框架小程序—初始篇(视频教程)

公告

以后每月5、15、25号更新原创文章,内容不限,喜欢小编的可以点击关注,也可在下方评论留言,你喜欢什么内容,小编根据大家喜欢的内容尝试更新

(20)

本文由 Web秀 作者:Javan 发表,转载请注明来源!

热评文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注