mpvue是一个使用vue.js开发小程序的框架。其官网http://mpvue.com/ 的介绍是,mpvue框架基于Vue.js核心,mpvue修改了Vue.js的runtime和compiler实现,使其能够运行在小程序环境中,从而为小程序开发引入了整套Vue.js开发体验。css
使用mpvue框架开发小程序,可以直接使用vue语法进行开发。html
Vant Weapp是一套小程序UI组件库,可使用这个UI库封装好的一些组件来实现某些功能,相似element组件的引入使用。vue
github:https://github.com/wendux/fly
Flyio帮助文档:https://wendux.github.io/dist...
如官网所说,Fly.js是一个支持全部JavaScript运行环境的基于Promise、支持请求转发的http请求库,它可最大限度地在多个端上实现代码复用。
其拥有的特色:
一、提供统一的PromiseAPI
二、浏览器环境下很是轻量
三、支持多种JavaScript运行环境
四、支持请求/响应拦截器
五、自动转换JSON数据
六、支持切换底层 HTTP Engine,可轻松适配各类运行环境
七、浏览器端支持全局Ajax拦截
八、H5页面内嵌到原生APP时,支持将HTTP请求转发到Native,支持直接请求图片node
本次搭建的小程序环境,将使用flyio这个http请求库来实现数据的请求,目前用到的方法为get、post。webpack
二者的使用示例在官网帮助文档有示例:git
一、搭建mpvue脚手架
基于mpvue-quickstart模版建立新项目 vue init mpvue/mpvue-quickstart one_hour_app
github
二、打开并跑起项目
新建的项目打开,dist文件夹还没有存在web
跑起项目cd one_hour_app
npm run dev
这样跑起来后项目中便多了一个dist文件夹,里面有个wx文件夹vue-router
这个wx文件夹就是要导入到微信开发者工具中的文件。
安装微信开发者工具,打开微信官网文档页面可下载:https://developers.weixin.qq....npm
安装好微信开发者工具后点击导入项目
弹窗内输入导入的目录
目录就是刚才说的那个在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。
一、安装scss,sass-loader的版本是7.3.1,若是使用最新的版本会报错,这里安装这个低版本的。
npm i -D sass-loader node-sass
测试下:
二、安装Vant Weapp
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: ['.*'] }]) ] }) }
使用一个button组件测试下:<van-button type="primary">主要按钮</van-button>
这样组件就成功引入了,并且也能够看到刚才那个拷贝目录的配置也生效了,能够看到vant-weapp目录已在wx里生成。
三、安装flyio、mpvue-router-push
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 } }
// 处理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组件主要的按钮事件:
<button class="auth-btn" open-type="getUserInfo" @getuserinfo="getUserInfo">受权登陆</button>
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) }
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) } }) }
// 获取用户信息 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) } }) }
index.vue页面:
<template> <div> <div v-if="isAuth"> <div class="index">首页</div> <van-button type="primary">主要按钮</van-button> <div> 获取userInfo示例: <div> {{ userInfo.nickName }} </div> 获取homeData数据示例: <div>{{ homeData.hotSearch && homeData.hotSearch.num }}</div> </div> </div> <auth v-if="!isAuth" @getUserInfo="init" /> </div> </template>
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() },
// 获取首页数据 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) } ) }
// 一开始就须要获取受权信息,mounted里调用 init () { getSetting( 'userInfo', (res) => { this.isAuth = true console.log(res) this.getUserInfoData() }, (res) => { this.isAuth = false console.log(res) } ) }
最后放上受权的过程示意图: