mpvue小程序架构搭建详细介绍
前言
mpvue小程序框架搭建很容易,官网提供vue init mpvue/mpvue-quickstart my-project
, 很迅速的创建项目,但是想要结合业务等,还是要废一番功夫,今天来学学wx.request的封装,mpvue的重构,如何搭建好用的mpvue小程序架构吧
创建项目
- 由于国内npm镜像慢的原因,考虑先把npm切到淘宝镜像。
npm set registry https://registry.npm.taobao.org/
- 全局安装vue-cli
npm install --global vue-cli@2.9
- 创建一个基于 mpvue-quickstart 模板的新项目, 一路回车选择默认就可以了
vue init mpvue/mpvue-quickstart mpvue-project
- 安装依赖
cd mpvue-project
npm install
npm run dev
到这里,你的项目已经能跑起来了,可以打开小程序调试工具预览效果,但是仅仅是能玩儿而已,下面更精彩。
全局图片,接口配置
-
找到项目(mpvue-project)下方的config->index.js文件,里面有两个对象,
build
和dev
,分别对应生产环境和开发环境,意思是你运行npm run dev
读的就是dev里面变量,npm run bulid
读的就是build的变量
这里我增加了3个变量,后续用到(这里的图片端口就是上图中的port)
接口请求地址(如:baseApi: ‘http://www.javanx.cn/rest’)
图片访问地址(如:imgPath: ‘http://localhost:8070/’)
web-view地址(如:baseUrl: ‘http://www.javanx.cn/’) -
来到项目(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+`'}
`);
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
这里的authorize
和getUserInfo
方法需要自己去写具体业务,同时上面用到的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插件
- 安装插件
npm install mpvue-entry
- 来到项目(mpvue-project)下方的build->webpack.base.conf.js文件
const MpvueEntry = require('mpvue-entry')
module.exports = {
entry: MpvueEntry.getEntry('src/pages.js'),
...
plugins: [
new MpvueEntry(),
...
]
}
- src目录下新建pages.js
module.exports = [{
path: 'pages/news/list', // 页面路径,同时是 vue 文件相对于 src 的路径,必填
config: { // 页面配置,即 page.json 的内容,可选
navigationBarTitleText: 'Javan的博客',
enablePullDownRefresh: true
}
}]
这样就没有建n个目录,n个main.js了
公告
以后每月5、15、25号更新原创文章,内容不限,喜欢小编的可以点击关注,也可在下方评论留言,你喜欢什么内容,小编根据大家喜欢的内容尝试更新
共同学习,写下你的评论
评论加载中...
作者其他优质文章