mpvue
mpvue是一個使用vue.js開發小程序的框架。其官網http://mpvue.com/ 的介紹是,mpvue框架基於Vue.js核心,mpvue修改了Vue.js的runtime和compiler實現,使其可以運行在小程序環境中,從而為小程序開發引入了整套Vue.js開發體驗。
使用mpvue框架開發小程序,能夠直接使用vue語法進行開發。
Vant Weapp
Vant Weapp是一套小程序UI組件庫,可以使用這個UI庫封裝好的一些組件來實現某些功能,類似element組件的引入使用。
flyio
github:https://github.com/wendux/fly
Flyio幫助文檔:https://wendux.github.io/dist...
如官網所説,Fly.js是一個支持所有JavaScript運行環境的基於Promise、支持請求轉發的http請求庫,它可最大限度地在多個端上實現代碼複用。
其擁有的特點:
1、提供統一的PromiseAPI
2、瀏覽器環境下非常輕量
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
2、打開並跑起項目
新建的項目打開,dist文件夾尚未存在
跑起項目
cd one_hour_app
npm run dev
這樣跑起來後項目中便多了一個dist文件夾,裏面有個wx文件夾
這個wx文件夾就是要導入到微信開發者工具中的文件。
安裝微信開發者工具,打開微信官網文檔頁面可下載:https://developers.weixin.qq....
安裝好微信開發者工具後點擊導入項目
彈窗內輸入導入的目錄
目錄就是剛才説的那個在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
測試下:
2、安裝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裏生成。
3、安裝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)
}
)
}
最後放上授權的過程示意圖: