uni-app轉字節跳動、百度小程序手摸手實戰 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

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)中心開發

  • 頁面效果
    個(gè)人(rén)中心主要(yào / yāo)涉及的(de)H5頁面以(yǐ)及小程序的(de)授權登錄功能。所以(yǐ)主要(yào / yāo)部分就(jiù)是(shì)webview的(de)實現。
  • 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 獲取授權code

    3.獲取用戶的(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à)家指正,互相交流,共同進步

相關案例查看更多