mpvuempvuempvuempvue是一个使用vue.js开发小程序的框架。其官网 http://mpvue.com/ 的介绍是,mpvue框架基于Vue.js核心,mpvue修改了Vue.js的runtime和compiler实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套Vue.js开发体验。使用mpvue框架开发小程序,能够直接使用vue语法进行开发。Vant WeappVant WeappVant WeappVant Weapp是一套小程序UI组件库,可以使用这个UI库封装好的一些组件来实现某些功能,类似element组件的引入使用。flyioflyioflyiogithub: https://github.com/wendux/flyhttps://github.com/wendux/flyFlyio帮助文档: https://wendux.github.io/dist/#/doc/flyio/readmehttps://wendux.github.io/dist/#/doc/flyio/readme如官网所说,Fly.js是一个支持所有JavaScript运行环境的基于Promise、支持请求转发的http请求库,它可最大限度地在多个端上实现代码复用。其拥有的特点:1、提供统一的PromiseAPI2、浏览器环境下非常轻量3、支持多种JavaScript运行环境4、支持请求/响应拦截器5、自动转换JSON数据6、支持切换底层 HTTP Engine,可轻松适配各种运行环境7、浏览器端支持全局Ajax拦截8、H5页面内嵌到原生APP时,支持将HTTP请求转发到Native,支持直接请求图片本次搭建的小程序环境,将使用flyio这个http请求库来实现数据的请求,目前用到的方法为get、post。两者的使用示例在官网帮助文档有示例:项目初始化项目初始化项目初始化1、搭建mpvue脚手架基于mpvue-quickstart模版创建新项目
vue init mpvue/mpvue-quickstart one_hour_app
vue init mpvue/mpvue-quickstart one_hour_app2、打开并跑起项目新建的项目打开,dist文件夹尚未存在新建的项目打开,dist文件夹尚未存在跑起项目
cd one_hour_app
npm run dev
cd one_hour_app
npm run dev这样跑起来后项目中便多了一个dist文件夹,里面有个wx文件夹这个wx文件夹就是要导入到微信开发者工具中的文件。安装微信开发者工具,打开微信官网文档页面可下载: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.htmlhttps://developers.weixin.qq.com/miniprogram/dev/devtools/download.html安装好微信开发者工具后点击导入项目弹窗内输入导入的目录目录就是刚才说的那个在one_hour_app项目中npm run dev之后生成的dist下的wx。AppID的获取,需要先在微信公众平台注册,然后打开开发-开发设置找到。导入成功后显示这样这样,就可以在编辑器写我们的代码,然后在微信开发者工具里面可以像浏览器一样查看页面效果。查看项目vue文件可以发现,我们基本上可以像写vue一样写里面的vue文件。之后对项目结构进行删减,把原本提供的那些没用到的文件先删除。保留一个架构。开发主要关注的是src这个目录。statics里面的images、tabs删掉src/main.js保持不变src/App.vue里的代码删掉,剩下src/app.json对应到页面路由pages配置、头部windows的样式和文字设置、脚部tabBar菜单配置,现在只保留如下:src/utils文件先保持不变src/components/card.vue删掉src/pages只留下index那块的内容。接着是删掉index.vue的东西。修整完后,只剩下首页至此,基于mpvue的小程序项目架构已经搭建好了。接着是css扩展语言scss、Vant Weapp UI组件库、flyio、mpvue路由插件mpvue-router-patch。1、安装scss,sass-loader的版本是7.3.1,如果使用最新的版本会报错,这里安装这个低版本的。
npm i -D sass-loader node-sass
npm i -D sass-loader node-sass测试下:2、安装Vant Weapp
npm i vant-weapp -S --production
npm i vant-weapp -S --production打开Vant Weapp的官网找一个button的例子测试下,但是使用之前需要在app.json文件中配置引入组件。由于把这个组件安装到了node_modules/vant-weapp/dist,所以引入组件的路径跟官网给的不一样,需要手动修改一下路径:同时由于我们需要在微信开发者工具查看,而那里导入了的是dist/wx,跟编辑器里的目录是不一样的,所以为了能在微信开发者工具正常显示组件,还需要做一个配置,将整个node_modules/vant-weapp/dist目录拷贝到dist/wx/vant-weapp/dist目录,在wepack.base.conf.js添加如下配置:
if (/^wx$/.test(PLATFORM)) {
baseWebpackConfig = merge(baseWebpackConfig, {

plugins: [

new CopyWebpackPlugin([{

from: resolve('node_modules/vant-weapp/dist'),

to: resolve('dist/wx/vant-weapp/dist'),

ignore: ['.*']

}])

]
})
}
if (/^wx$/.test(PLATFORM)) {
baseWebpackConfig = merge(baseWebpackConfig, {

plugins: [

new CopyWebpackPlugin([{

from: resolve('node_modules/vant-weapp/dist'),

to: resolve('dist/wx/vant-weapp/dist'),

ignore: ['.*']

}])

]
})
}使用一个button组件测试下:
主要按钮
主要按钮这样组件就成功引入了,而且也可以看到刚才那个拷贝目录的配置也生效了,可以看到vant-weapp目录已在wx里生成。3、安装flyio、mpvue-router-push
npm i -S flyio
npm i -S mpvue-router-patch
npm i -S flyio
npm i -S mpvue-router-patch现在用不到这个路由插件,先安装着放着。接着是使用flyio来实现小程序授权登录的请求。首先在utils里创建request.js用来封装flyio的请求。
// 初始化flyio请求
function createFly () {
if (mpvuePlatform === 'wx') {

const Fly = require('flyio/dist/npm/wx')

return new Fly()
} else {

return null
}
}
// 初始化flyio请求
function createFly () {
if (mpvuePlatform === 'wx') {

const Fly = require('flyio/dist/npm/wx')

return new Fly()
} else {

return null
}
}
// 处理get请求、post请求,
//如果是post,就把get改成post就行,这里为了节省篇幅,省去了post的那段代码
export function get (url, params = {}, showErr = true) {
const fly = new createFly()
if (fly) {

return new Promise((resolve, reject) => {

fly.get(url, params).then(response => {

const data = (response && response.data) || {}

if (data.error_code === 0) {

resolve(response)

console.log(response)

} else {

if (showErr) {

mpvue.showToast({

title: data.msg || '请求失败',

icon: 'none',

duration: 1500

});

}

reject(response)

}

}).catch(err => {

console.log(err)

})

})
}
}
// 处理get请求、post请求,
//如果是post,就把get改成post就行,这里为了节省篇幅,省去了post的那段代码
export function get (url, params = {}, showErr = true) {
const fly = new createFly()
if (fly) {

return new Promise((resolve, reject) => {

fly.get(url, params).then(response => {

const data = (response && response.data) || {}

if (data.error_code === 0) {

resolve(response)

console.log(response)

} else {

if (showErr) {

mpvue.showToast({

title: data.msg || '请求失败',

icon: 'none',

duration: 1500

});

}

reject(response)

}

}).catch(err => {

console.log(err)

})

})
}
}如果遇到了 TypeError: __webpack_require__(...) is not a function这样的问题,就关闭微信开发者工具,删除dist包,再重新npm run dev跑一下,重新打开微信开发者工具应该就没问题了。接下来是用户授权的内容。授权登录授权登录授权登录首页的展示,需要调用mpvue.getSetting获取用户的当前设置。已授权就展示正常页面,未授权就展示auth.vue授权登录页面。未授权的状态,当用户同意授权使用的时候,这时首页就会变成正常的页面,同时,需要获取用户的信息userInfo。在成功获取了用户信息之后,需要使用存储器mpvue.setStorageSync把它存储起来供之后需要的时候使用getStorageSync来获取。这时会存在两种情况,一种是已存在openId的情况,另一种是还没获取openId的情况。当未取到openId时,需要调用接口获取openId,而调用这个接口需要获得code,这个code可以通过mpvue.login API获取到。当取得code之后就调用获取openId的接口,返回openId并存储起来。取得openId后,就可以把这个openId作为参数,传给获取首页数据的接口。当已经取得openId时,就直接调用首页接口数据并传openId作为接口的参数。在此之后,需要调用register注册接口,调用这个接口能够把用户的行为数据存储在后台,辨别不同的用户。流程示意图:auth.vue组件主要的按钮事件:


getUserInfo () {

this.$emit('getUserInfo')

}
getUserInfo () {

this.$emit('getUserInfo')

}src/api/index.js用来存放接口
import { get, post } from "@/utils/request.js"
const API_BASE = '后台接口前缀'

export function getOpenId (params) {
return get(`${API_BASE}/openId/get`, params)
}

export function getHomeData (params) {
return get(`${API_BASE}/book/home/v2`, params)
}

export function register (params) {
return post(`${API_BASE}/user/register`, params)
}
import { get, post } from "@/utils/request.js"
const API_BASE = '后台接口前缀'

export function getOpenId (params) {
return get(`${API_BASE}/openId/get`, params)
}

export function getHomeData (params) {
return get(`${API_BASE}/book/home/v2`, params)
}

export function register (params) {
return post(`${API_BASE}/user/register`, params)
}src/api/wechat.js用来存放微信平台相关的API
import { getOpenId } from '@/api'
const APP_ID = '填写微信公众平台的App_ID'
const SECRET = '填写微信公众平台的secret'

// 请求getSetting获取用户当前的授权
export function getSetting (auth, onSuccess, onFail) {
mpvue.getSetting({

success (res) {

if (res.authSetting[`scope.${auth}`]) {

onSuccess(res)

} else {

onFail(res)

}

},

fail (res) {

console.log(res)

}
})
}
import { getOpenId } from '@/api'
const APP_ID = '填写微信公众平台的App_ID'
const SECRET = '填写微信公众平台的secret'

// 请求getSetting获取用户当前的授权
export function getSetting (auth, onSuccess, onFail) {
mpvue.getSetting({

success (res) {

if (res.authSetting[`scope.${auth}`]) {

onSuccess(res)

} else {

onFail(res)

}

},

fail (res) {

console.log(res)

}
})
}
// 获取用户信息
export function getUserInfo (onSuccess, onFail) {
mpvue.getUserInfo({

success (res) {

onSuccess(res)

console.log(res)

},

fail (res) {

onFail(res)

}
})
}
// 获取用户信息
export function getUserInfo (onSuccess, onFail) {
mpvue.getUserInfo({

success (res) {

onSuccess(res)

console.log(res)

},

fail (res) {

onFail(res)

}
})
}
// 获取openId
export function getUserOpenId (callback) {
mpvue.login({
// 调用login API 获得code

success (res) {

console.log(res)

const { code } = res // 这个code是获取openId的前提

getOpenId({ code, appId: APP_ID, secret: SECRET }).then(response => {

const { openid } = response.data.data

mpvue.setStorageSync('openId', openid)

callback && callback(openid)

}).catch(err => {

console.log(err)

})

},

fail (res) {

console.log(res)

}
})
}
// 获取openId
export function getUserOpenId (callback) {
mpvue.login({
// 调用login API 获得code

success (res) {

console.log(res)

const { code } = res // 这个code是获取openId的前提

getOpenId({ code, appId: APP_ID, secret: SECRET }).then(response => {

const { openid } = response.data.data

mpvue.setStorageSync('openId', openid)

callback && callback(openid)

}).catch(err => {

console.log(err)

})

},

fail (res) {

console.log(res)

}
})
}index.vue页面:


import { get, post } from '@/utils/request'
import Auth from '@/components/base/auth.vue'
import { getHomeData, register } from '@/api'
import { getSetting, getUserInfo, getUserOpenId } from '@/api/wechat'
import { get, post } from '@/utils/request'
import Auth from '@/components/base/auth.vue'
import { getHomeData, register } from '@/api'
import { getSetting, getUserInfo, getUserOpenId } from '@/api/wechat'
data () {

return {

isAuth: false,

userInfo: {},

homeData: {}

}
},
mounted () {

this.init()
},
data () {

return {

isAuth: false,

userInfo: {},

homeData: {}

}
},
mounted () {

this.init()
},
// 获取首页数据
getIndexData (openId, userInfo) {

getHomeData({ openId }).then(response => {

console.log('getHomeData-----', response)

this.homeData = response.data.data

})
},
// 获取首页数据
getIndexData (openId, userInfo) {

getHomeData({ openId }).then(response => {

console.log('getHomeData-----', response)

this.homeData = response.data.data

})
},
// 在获得授权信息后调用以获得用户信息
getUserInfoData () {

const onCompleteGetOpenId = (openId, userInfo) => {

this.getIndexData(openId, userInfo) // 获取首页数据

register({ openId, platform: mpvuePlatform, ...userInfo }) // 注册

}

getUserInfo( // 获取用户信息

(res) => {

const { userInfo } = res

this.userInfo = userInfo

mpvue.getStorageSync('userInfo', userInfo)

const openId = mpvue.getStorageSync('openId')

if (!openId || openId.length === 0) { // 未存在openId

getUserOpenId((openId) => { // 需要请求接口获得

onCompleteGetOpenId(openId, userInfo)

})

} else {

onCompleteGetOpenId(openId, userInfo) // 已存在openId

}

},

(res) => {

console.log(res)

}

)
}
// 在获得授权信息后调用以获得用户信息
getUserInfoData () {

const onCompleteGetOpenId = (openId, userInfo) => {

this.getIndexData(openId, userInfo) // 获取首页数据

register({ openId, platform: mpvuePlatform, ...userInfo }) // 注册

}

getUserInfo( // 获取用户信息

(res) => {

const { userInfo } = res

this.userInfo = userInfo

mpvue.getStorageSync('userInfo', userInfo)

const openId = mpvue.getStorageSync('openId')

if (!openId || openId.length === 0) { // 未存在openId

getUserOpenId((openId) => { // 需要请求接口获得

onCompleteGetOpenId(openId, userInfo)

})

} else {

onCompleteGetOpenId(openId, userInfo) // 已存在openId

}

},

(res) => {

console.log(res)

}

)
}
// 一开始就需要获取授权信息,mounted里调用
init () {

getSetting(

'userInfo',

(res) => {

this.isAuth = true

console.log(res)

this.getUserInfoData()

},

(res) => {

this.isAuth = false

console.log(res)

}

)
}
// 一开始就需要获取授权信息,mounted里调用
init () {

getSetting(

'userInfo',

(res) => {

this.isAuth = true

console.log(res)

this.getUserInfoData()

},

(res) => {

this.isAuth = false

console.log(res)

}

)
}最后放上授权的过程示意图: