uni-app轉字節跳動、百度小程序手摸手實戰
發表時(shí)間:2021-1-5
發布人(rén):融晨科技
浏覽次數:98
從最早發布的(de)微信小程序,到(dào)後來(lái)的(de)支付寶小程序、釘釘小程序,字節跳動小程序、百度小程序、QQ小程序等,面對這(zhè)麽多套的(de)代碼,開發者去編寫多套原生代碼的(de)成本顯然非常高,使用H5的(de)話體驗又沒有原生好,這(zhè)時(shí)候隻需編寫一套代碼,就(jiù)能夠适配多端的(de)能力就(jiù)顯得尤爲(wéi / wèi)需要(yào / yāo)。
下面進入正題,給大(dà)家介紹下uni-app字節小程序的(de)開發
前置準備工作
- 默認頭條小程序的(de)APPID已申請成功
- 安裝開發工具
百度小程序開發者工具
字節跳動開發者工具
HBuilderX
或者其他(tā)自己喜歡的(de)IDE都可以(yǐ)
項目開發
新建項目
可以(yǐ)通過 HBuilderX可視化界面 以(yǐ)及 vue-cli命令行 方式進行創建
下面主要(yào / yāo)介紹下通過vue-cli命令行這(zhè)中方式來(lái)新建項目
- 全局安裝vue-cli
npm install -g @vue/cli
複制代碼
- 創建
vue create -p dcloudio/uni-preset-vue user-uni-order
複制代碼
安裝成功後提示選擇模闆,我們選擇默認模闆就(jiù)可以(yǐ)了(le/liǎo)
項目整體流程
用戶下單最短流首頁下單-> 訂單狀态-> 完成支付, 如下:
綜上(shàng)我們需要(yào / yāo)做的(de)頁面維度: 首頁,地(dì / de)址檢索,城市選擇,登錄,個(gè)人(rén)中心,訂單列表,webview(收費标準 , 預估價格, 訂單狀态, 訂單詳情,法律條款)
制定目錄結構
┌─components //uni-app組件目錄
│ └─comp-a.vue //可複用的(de)a組件
├─common // 通用的(de)js&css工具等
├─hybrid //存放本地(dì / de)網頁的(de)目錄
├─platforms //存放各平台專用頁面的(de)目錄
├─pages //業務頁面文件存放的(de)目錄
│ ├─index
│ │ └─components // 頁級别組件
│ │ └─vuex // index頁面vuex主要(yào / yāo)存放index的(de)邏輯
│ │ └─index.vue // index頁面
├─static //存放應用引用靜态資源(如圖片、視頻等)
│ ├─mp-weixin //條件編譯png
│ │ └─a.png
│ │ └─b.png
├─store // 狀态統一管理,将各個(gè)頁面的(de)vuex彙總
├─service // 彙總請求,api等
│ └─api.js // 接口api相關
│ └─config.js // 環境配置
│ └─index.js
│ └─request.js // 網絡請求
├─ttcomponents // 頭條小程序自定義組件存放目錄
├─main.js //Vue初始化入口文件
├─App.vue //應用配置,用來(lái)配置App全局樣式以(yǐ)及監聽
├─manifest.json //配置應用名稱、appid、logo、版本等打包信息
└─pages.json //配置頁面路由、導航條、選項卡等頁面類信息
複制代碼
運行項目
想運行到(dào)哪個(gè)平台小程序,首先需要(yào / yāo)把相應的(de)APPID, IDE路徑對應填寫正确
npm run dev:mp-toutiao // 實時(shí)監聽編譯
複制代碼
運行成功如下提示:

此時(shí)打開字節跳動IDE進行導入操作,就(jiù)可以(yǐ)看見頁面啦~~~
Tips:使用字節跳動編譯器打開uni-app編譯的(de)小程序時(shí),必須進行導入操作,而(ér)不(bù)是(shì)新建,因爲(wéi / wèi)新建會默認成代碼片段,雖然也(yě)可以(yǐ)實時(shí)預覽效果但是(shì)會導緻上(shàng)傳功能确實
具體頁面的(de)開發
首頁開發
- 頁面效果

- 首頁目錄結構
項目中其他(tā)頁面的(de)目錄結構與首頁均相同,後面不(bù)做多餘贅述。
├─pages
│ ├─index
│ │ └─components
│ │ └─vuex
│ │ │ └─index.js // 首頁邏輯
│ │ └─index.vue
複制代碼
- 我們使用vuex來(lái)管理狀态,每個(gè)頁面都有自己的(de)vuex, 其中index.js存放對應頁面相關邏輯,爲(wéi / wèi)了(le/liǎo)避免頻繁切換目錄,把state, mutations, actions放在(zài)一個(gè)文件下,使用時(shí)并啓用vuex的(de)模塊化,如下
const IndexPage = {
namespaced: true, // 啓用模塊化vuex
state: {
... // 需要(yào / yāo)共享的(de)狀态
},
mutations: {
... // 一些方法
},
actions: {
... // 請求相關
}
}
export default IndexPage //最後導出(chū)IndexPage
複制代碼
- 各個(gè)頁面的(de)vuex統一放在(zài)store裏
import Vue from 'vue'
import Vuex from 'vuex'
import IndexPage from '../pages/index/vuex'
import AddressSearch from '../pages/address/vuex/index'
import CityListPage from '../pages/city-list/vuex/index'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
... // 全局共用的(de)狀态
},
mutations: {
},
actions: {
},
modules: {
IndexPage, // 首頁vuex
AddressSearch, // 地(dì / de)址檢索頁vuex
CityListPage, // 城市列表頁vuex
},
})
export default store
複制代碼
- 最後,在(zài)main.js裏面引用
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App,
store
})
app.$mount()
複制代碼
完整的(de)首頁邏輯交互框架就(jiù)搭建成功了(le/liǎo),以(yǐ)下是(shì)開發首頁時(shí)遇見的(de)問題
首頁開發遇到(dào)的(de)問題
- 使用swiper輪播組件,寫好子(zǐ)組件,父組件因爲(wéi / wèi)無效果
問題原因:引入的(de) import swiper from "../../components/swiper/swiper"
,導緻把自定義的(de)swiper覆蓋,所以(yǐ)不(bù)展示
解決:引入的(de) import uniSwiper from "../../components/swiper/swiper"
,不(bù)和(hé / huò)原組件命名沖突即可
- 轉百度小程序header報錯
問題原因:百度設置http請求header如果有中文字符
解決:使用條件編譯,如果是(shì)百度小程序需要(yào / yāo)encodeURI 一下, 或者删除header的(de)中文部分
- uni-app的(de)image标簽,在(zài)小程序端不(bù)支持動态引入圖片
// 引不(bù)到(dào)
class="tip_icon" src=http://www.wxapp-union.com/"/static/sender{{endPoint.address ? '' : '_default'}}.png"/>
複制代碼
// 可以(yǐ)引入
class="tip_icon" src=http://www.wxapp-union.com/"/static/sender.png"/>
複制代碼
- uni.getLocation() 隻能獲取經緯度,獲取不(bù)到(dào)詳細地(dì / de)址信息
- 非 h5 平台 :key 不(bù)支持表達式
由于(yú):key="timer__${idx}
"的(de)寫法,編譯時(shí)控制台會警告,但是(shì)不(bù)影響頁面
<view
class="column_item"
v-for="(item, idx) in item"
:key="`timer__${idx}`" // 改成:key="idx" 即可
>
{{item == "立即用車" ? "" : index == 1 ? "時(shí)" : index == 2 ? "分" : ""}}
view>
複制代碼
- 父子(zǐ)組件傳參,類型定義不(bù)對不(bù)提示錯誤信息,隻展示null, 所以(yǐ)遇到(dào)null問題可以(yǐ)查看是(shì)否是(shì)類型定義不(bù)一緻
- uni-app中的(de)watch不(bù)支持監聽小程序,如下
watch: {
searchType (to) {
if (to) {
// 如果是(shì)起始地(dì / de)回填起始地(dì / de)信息否則回填目的(de)地(dì / de)信息
if (to === SEARCH_TYPE.START) {
this.detailAddress = this.startAddress.detailAddress || ''
} else {
this.detailAddress = this.endAddress.detailAddress || ''
}
}
}
}
複制代碼
改成
mounted () {
if (this.searchType === SEARCH_TYPE.START) {
this.detailAddress = this.startAddress.detailAddress || ''
} else {
this.detailAddress = this.endAddress.detailAddress || ''
}
}
複制代碼
個(gè)人(rén)中心開發
- 頁面效果
- webview的(de)實現
// template
'web-view' v-if='src' :src=http://www.wxapp-union.com/'src' @bindmessage='onmessage'>
複制代碼
onLoad (options) {
console.log('H5入口頁獲取到(dào)的(de)參數', options)
let { src, needLogin} = options
if(!needLogin){
this.src = http://www.wxapp-union.com/decodeURIComponent(src)
return
}
// 需要(yào / yāo)登錄的(de) 就(jiù)先獲取臨時(shí)token
this.fetchTempToken(src)
}
複制代碼
如果不(bù)需要(yào / yāo)登錄的(de)H5我們直接賦值到(dào)src即可,需要(yào / yāo)登錄才能正常訪問的(de)頁面,首先要(yào / yāo)獲取臨時(shí)token,拿到(dào)臨時(shí)token後回傳給服務端并且采用中間頁redirectUrl的(de)形式跳轉。
個(gè)人(rén)中心開發遇到(dào)的(de)問題
- 向網頁傳遞信息要(yào / yāo)使用頭條api的(de)bindmessage
官方說(shuō)明“網頁向小程序 postMessage 時(shí),會在(zài)特定時(shí)機(小程序後退、組件銷毀、分享)觸發并收到(dào)消息”
// 在(zài)小程序中調起H5中的(de)打電話功能
onmessage (e) {
let { phoneNumber, name } = e.detail
if(name == 'makePhoneCall'){
uni.makePhoneCall({
number: phoneNumber
})
}
}
複制代碼
需要(yào / yāo)注意的(de)web-view的(de)bindmessage屬性并不(bù)是(shì)實時(shí)的(de)
- 真機撥打電話功能不(bù)能用
// 使用uni.makePhoneCall真機沒反應
uni.makePhoneCall({ phoneNumber: '114'});
複制代碼
解決:改爲(wéi / wèi)頭條api的(de)tt開頭
// 真機模拟器均可正常使用
tt.makePhoneCall({ phoneNumber: '114'});
複制代碼
登錄開發
-
頭條授權登錄效果
-
大(dà)緻思路:
1.首先獲取獲取服務供應商的(de)信息
2.調用
uni.getProvider
獲取授權code3.獲取用戶的(de)手機号(用戶登錄頭條app的(de))
4.從
@getphonenumber
回調中獲取到(dào)用戶信息5.調用授權登錄服務api
6.獲取token, openid等信息
// template
<view class="login-page">
<view class="title">
<view class="h-line">view>
<view class="page-title">授權登錄更快捷view>
<view class="h-line">view>
view>
<view class="authLogin-wrapper">
<button type="default" open-type="getPhoneNumber" @getphonenumber="authLoginTap" class="login authLogin">百度登錄更快捷button>
<button
type="default"
class="login authLogin"
open-type="getPhoneNumber"
@getphonenumber="onGetPhoneNumber"
>授權手機号快捷登錄button>
view>
view>
複制代碼
// 完成渲染調用授權code方法
mounted () {
this.getCode()
}
複制代碼
// 獲取授權code方法
async getCode () {
const [ errorProvider, provider ] = await uni.getProvider({ service: 'oauth' })
if (errorProvider) {
console.log('獲取provider失敗')
return
}
const [ errLogin, data ] = await uni.login({
provider: provider.provider[0],
force: true
})
if (errLogin) {
console.log('獲取code失敗')
// 失敗的(de)操作,提示等
return
}
const { code } = data
this.code = code
},
// 頭條獲取到(dào)用戶信息
async onGetPhoneNumber ({ detail }) {
const { errMsg } = detail
// 授權失敗
if (errMsg.indexOf('auth deny') > -1) {
// 取消授權進行手機驗證碼登錄
return
}
try {
// 調用服務授權接口
const { data } = await authLogin({
code: this.code,
...detail,
})
if (data.code === SUCCESS) {
// 存token, openid等操作
// 重新更新個(gè)人(rén)信息
} else {
// 失敗的(de)提示等
}
} catch (error) {
// 登錄失敗異常情況處理
}
},
// 百度獲取到(dào)用戶信息同理頭條。。。
複制代碼
登錄開發遇到(dào)的(de)問題
手機驗證碼開發時(shí),引入 checkbox-group
報錯,如下圖:

原因: components : { [CheckBox.name]: CheckBox }
引入組件方式不(bù)支持
發布到(dào)測試環境
以(yǐ)字節跳動爲(wéi / wèi)例子(zǐ),打開字節跳動開發者工具,在(zài)工具欄找到(dào)上(shàng)傳,填寫版本号,發布。版本号不(bù)和(hé / huò)上(shàng)一次沖突就(jiù)可以(yǐ)。
Tips: 前面有提過,新建代碼片段是(shì)在(zài)開發者工具上(shàng)是(shì)沒有上(shàng)傳按鈕的(de),要(yào / yāo)導入項目才可以(yǐ)。

上(shàng)傳成功後,會提示進入小程序開發者平台,現在(zài)可以(yǐ)看到(dào)開發者的(de)版本。


上(shàng)圖二維碼就(jiù)可以(yǐ)隻作爲(wéi / wèi)本次的(de)體檢版本來(lái)掃一掃了(le/liǎo)。
發布到(dào)正式環境
- 前置準備,在(zài)後台配置好相關線上(shàng)域名
- 切換到(dào)線上(shàng)環境
// 環境相關配置
export const ENV = {
// 開發環境
RD: 'rd',
// 測試環境
TEST: 'test',
// 沙箱環境
BOX: 'box',
// 線上(shàng)環境
ONLINE: 'online'
}
// 環境切換
export function getCurrentEnv() {
return ENV.ONLINE // 正式環境切到(dào)online
}
複制代碼
- 在(zài)開發者工具中點擊上(shàng)傳
- 去小程序開發者平台提審發布
- 發布成功後可在(zài)頭條搜索欄中搜到(dào),抖音的(de)話目前隻有安卓平台上(shàng)線了(le/liǎo)小程序功能。
結束語
以(yǐ)上(shàng)就(jiù)是(shì)uni-app轉字節跳動、百度小程序的(de)部分開發,相信大(dà)家對uni-app實戰小程序已經有了(le/liǎo)初步認識,也(yě)歡迎大(dà)家指正,互相交流,共同進步