布景
从最早发布的微信小程序,到后来的支付宝小程序、钉钉小程序,字节跳动小程序、百度小程序、QQ小程序等,面临这么多套的代码,开发者去编写多套原生代码的本钱显然十分高,运用H5的话体会又没有原生好,这时候只需编写一套代码,就能够适配多端的才干就显得尤为需求。
下面进j { ] p M X入正题,给我们介绍下uni-app字节小程序的开发
前置预备工作
- 默认头条小程序的APPID已申请成功
- 装置开发东西
百度小程序开发者东西
字节跳动开发者东西
HBuilderX
或者其他自己喜爱的IDE都能够
项目开发
新建项目
能够通过HBuilderX可视化界面 以及 vue-cli命令行办法进行创立
下面首要介绍下通过vue-cli命令行这中办法c _ L 3 o ( W v来新建项目
- 大局装置vue-cli
npm install -g @vue/cli
- 创立
vue create -p dcloudio/uni-preset-vue user-uni-ordq - h . U s L + Mer
装置成功后提示挑选模板,咱们挑选默认模板就能够了
项目整体流程
用户下单最短流主页下单-> 订单状况-> 完结支付, 如下:
综上咱们需求做的页面维度: 主F ( $ ] ?页,地址检c . 2 Z g 4 b ` j索,城市挑选,登录,个人中心,订单列表,webview(收费规范 , 预估价格,i – O B I _ n j 订单状况, 订单概况,法令条款)
制定目录结构
┌─components //uni-app组件目7 ^ b - { 1录
│h H * 6 5 Z 6 $ └─comp-a.vue //I R 1 f P e可复用的a组件
├─common // 通用的js&css东西等
├─hybrid //寄存本地网页的目录
├─platforms //寄存各渠道专用页面的目录
├─pages //业务页面文件寄存的目录
│ ├─index
│ │ └─components // 页等级组件
│ │ └─vuex // inden w ` Q Jx页面vuex首要寄存index的逻辑
│ │ └─index.vue // index页面
├─static //寄存运用引用静态资源(如图片、视频等)
│ ├─mp-weixin //条件编译png
│ │ └─C 9 -a.png
│ │ └─b.png
├─store // 状况统一办理,将各个页面的vuex汇总
├─service // 汇总恳求,api等
│ └─api.js // 接口api相关
│ └─config.js // 环境装备
│ └─index.js
│ └─request.jd X Q 0s // 网络恳求
├─ttcomponents // 头条小程序自界说组件寄存目录
├─main.js //Vue初始化入口文件
├─App.vue //运用装备,用来装备App大局样式以及监听
├─manifest.jsonI j % 4 //装备运用名称、_ f O $appid、logo、版别等打包信息
└─pages.json //装备页面路由、导航条、选项卡等页面类信息
运转项目
想运转到哪个渠道小程序,首先需求把相应的APPID, IDE途径对应填写正确A u ; u ( l
npm run dev:mp-toutiao // 实时监听编译
运转成功如下提示:
此时翻开字节跳动IDE进行导入操作,就能够看见页面啦~~~
Tips:运用字节跳动编译器翻开uni-app编译的小程序时,有! [ @ y ] j ; C q必要进行导入操作,而不是新建,因为新建会默认成代码片段,尽管也能够实时预览作用可是会导致上传功用确实
具体页面的开发
主页开发
- 页面作用
- 主页目录结构
项目中其他页面M c H * L 的目录结构与主页均相同,后面不做剩余赘述。
├─pages
│ ├─index
│ │ └─components
│ │ └─vuex
│ │ │ └─index.jH $ W X E B Y Os // 主页逻辑
│ │ └─index.vue
- 咱们运用vuex来& 5 c 2 Q ) N j )办理状况,每个页面都有自己的vuex, 其中index.js寄存对应页面相关逻辑,为了避免频频切换目录,把stat E P G – se, mutations, actions, p ] w放在一个文件下,运用时! 8 h @并启用vuex的模b | ] g d B块化,如下
const IndexPH . oage = {
namespaced: true, // 启用模块化vue3 ? Hx
state:( * I ] p I x R {
... // 需求同享的状况
},
mutations: {
... // 一些办法
},
act^ 2 I n + X #ions: {
... // 恳求相关
}
}
export default IndexPage //最终导3 ^ R A t出IndexPat K W v y # Vge
- 各个页面的vuex统一放在store里
import Vue from ', D Ivue'
import Vuex from 'vuexB T I b ? o'
import IndexPage from '../pages/index/vuex'
import Add0 6 B D kressSearch from '../pages/address/vuex/index'
import CityListPage from '../pages/city-list/vuex/index'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
... // 大局共用的状况
},
mutations: {
},[ f * 6 X ~ T p
actions: {
},
modules: {
IV g + 6 n 3 UndexPage,s A O e O // 主页vuex
AddressSeo ) v Q Iarch, // 地址检索页vuex
CB . ?itys C l q R : R 8ListPage, // 城市列表页vuex
},
})
export default store
- 最终,在main.js里边引~ 4 ^ W J h 1 T用
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.producti` 7 E )onTip = false
App.mpType = 'ap r [ C Y u hp'
const app = new Vue({
...App,
store
})
app.$mount()
完好的主页逻辑交互结构就搭建成功了,以下是开发主页时遇见的问题
主页开发遇到的问题
- 运用swiper轮播组件,写好子组件,父组件因为无作用
问题原因:引进的import swiper from "../../components/swiper/swiper"
,导致把自界说的swiper覆盖,所以不展现
处理:引进的import uniSwiper from "../../components/swiper/sS Y G - ] ! 8 ]wiper"
,不和原组件命名冲突即可
- 转百度小程序header报错
问题原因:百度设置http恳求header假如有中文字符
处理:运用条件编译,假如是百度小程序需求encodeURI 一下, 或者删除headerz [ a 0 B ^的中文部分
- uni-app的images ! w 4 ( 6标签,在小程序端不支持动态引进图片
// 引不到
<image class="tip_icon" src="/static/sender{{endPoint.address ? '' : '_default3 J X ;'}}.png"Z K 1 v V R/>
// 能够引进
<z : K ) 7 w &;imageM 3 u g - class="tip_icon"Z r G e + [ 6 + src="/static/sender.png"/>
- uni.getLocation() 只能获取经纬度,获取不到具体地址信息
- 非 h5 渠道 :key 不支持表达式
因为:key=”timer__${idx}
“的写法,编译q 8 |时控制C t c L台8 L : U L ^ ?会正告,可是不影响| 5 ~ G X 3 r页面
<view
class="column_item"
v-for="(item, idx) in item"7 : q
:key="`timer__${idx}`" // 改成:key="idx" 即可
>
{{iteT v xm == "立即用车" ? "" : index == 1 ? "时" : index == 2 ? "分"M h ) y : ""}}
</view>
- 父子组件传参,类型界说不对不提$ [ h t o 5 &示错误信息,只展现null, 所以遇到nD % = _ Bull问题能够检查是否是类型界说不一致
- uni-app中的watc* [ R r zh不支持监听小程序,如下
watcH q e i ! Uh: {
searchType (to) {
if (to) {
// 假如是开始地回填开始地信息否则回填目的地信息
if (to === SEARCH_TYPE.START) {
this.detailAddress = this.startAddress.detailAddress || ''
} else {
this.detailAddress = this.endAddress.detailAddress || ''
}
}
}
}
改成d K K L s E 9 | @
mounted () {
if (this.searchType === SEARCH_TYPE.START) {z H , )
this.detailAddress = this.startAddress.detailAddress || ''
} else {
this.detailAddress^ % ] / ` y & e l =k i 4 - this.endAddr r 6 A f @ 5 @ress.detailAddress || '. e w { M } 6 b x'
}
}
个人中心开发, : y X E F ! L :
- 页面作用
个人中心首要涉及的H5页面以及小程序的授权登录功用。所以首要部分便是webview的完结。
- webview的完结
// template
<web-view id='web-view' v-if='src' :src='src' @bindmessage='onmessage'></web-view>
onLoad (options) {
console.log('U R x 8 , , $H5入口页获取到的参数', options)
let { src, needLogin} = options
if(!needLogin){
this.src = decodeUC ; ] s 5RIComponent(src)
return
}
// 需求登录的 就先获取暂时to[ X P G ) p %ken
this.fetchTempToken(src)
}
假如不需求登录的H5咱们直接赋值到src即可,需求登录才干正常访问的页面,首先要获取暂时token,拿到暂时token后回传给服务端而且采用中心页redirectUrl的方法跳转。
个人中心开发遇到的问题
- 向网页传递信息要运用头条api的bindmessage
官方说明“网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到音讯”
// 在小程序中调起H5中的打电话功用
onmessage (e) {
let { phoneNumber, name } = e.detail
if(name == 'makePhoneCall'){
uni.makePhoneCall({
number: phoneNuL ` B l h $ mmber
})
}
}
需求注意的web-+ D @vip T = d : V t Qew的bindmessagD Z *e特点并不是实时的
- 真机拨打1 h * S电话功用不能用
// 运用uni.makePhoneCall真机没反应
uni.makePhoneCall({ phoneNumber: '114'});
处理:改为头条api的tt最初
//C Z # j : 1 S ; 0 真机模拟器均可正常运用
tt.makePhoneCaz j U sll({ phoneNumber: '114'});
登录开发
-
头条授权登录作用
-
百度授权登录作用
-
大致思路:
1.首先获取获取服务供应商的信息
2.调用uni.getProvider
获取授权code
3.获取用户的手机号? _ S 0(用户登录头条app的)
4.从@getphonenumber
回调中获取到用户信息
5.调用授权登录服务api
6.获取token, openy Y Xid等信息
// template
<view class="login-page">
<view class="ti` 0 V e X f htle" z (>
<view class="h-line"></view>
<view class="page-title">授权登录更方便</view>
<view cla; r h iss="h-line"></v x L 5 ( P | O 0iewV R K j v Q + >
</vs m p R 8 Uiew>
<view class="authLogin-wrapper">
<!-- #ifdef MP-BAIDU -->
<button type="default" open-type="getPhoneNumber" @getphonenumbz ) G = E H Ner="authLoginTap" class="login authLogin">百度登录更方便</b) V s ^ ; Y C hutton>
<!-- #endif -->
<!-Q x z- #ifdef MP-TOUTIAO -->
<button
type="dej 9 ufault"
class="login authLogin"
open-type="getI | k PhoneNumber"
@getphonenumber="onGetPhoneNumber"
>授权手机号方便登录</button>
<!-- #endif -->
</view>
</view&gT ) qt;
// 完结渲染调用授权code办法
mounted () {
this.getCode()
}
// 获取授权code办法
async getCode () {
const [ errorProvider, provider ] = awai) U 0 at uni.getProvider({ service: 'oauth' })
if (errorProvider) {
cob J 9 U F unsole.log('获取provider失利')
return
}
const [ errLogin, data ] = await uni.login({
providd B t ?er: prD A B O Z g d g Jovider.provider[0],
force: true
})
if (errLogin) {
console.log('获取code失利')
// 失利的操作,提示等
return
}
const { code } = data/ q Q
this.code = code
},
// 头条获取到用户信息
asyncj a ~ w * 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等操作
// 重新更新个人信息
} else {
//1 u L p 0 L 失利的提示等
}
} catch (error) {
// 登录失利异常情况处理
}
},
// 百度获取到用户信息同理头条。。。
登录开发遇到的问题
手机验证码开发时,引进cV $ ; U ` Z -heckbox-grou| ) y e w p
报错,如下图:
原因:components : { [CheckBox.name]: CheckBox }
引进组件办法不支持
发布到测试环境
以字节跳动为例子,翻开字节跳动开发者东2 } v W N 8 I西,在东西栏找到上C ) H x +传,D / 3 l 9 w填写版别号,发布。版别号不和上一次冲突就能够。
Tips: 前面有提过,新建代码片段是在开发者东西上是没有上传按钮的,要导入项目才干够。
上传成功后,会提示进入小程序开发者渠道,现在能够看到开Q M N $ 6 X I 7 X发者的版别。
上图二维码就能够只作为本次的体检版别来扫一扫T T I v H y r x了。
发布到正式环境
- 前置预备,在后台装备好相关线上域名
- 切换到线上环境
// 环境相关装备
expor$ A L Qt const ENVN ; ; _ c X # = {
// 开发环境
RD: 'rd* @ ] _ L u h v',
// 测试环境
TEST: 'test',
// 沙箱环境
BOX: 's / 8 p $ P 0 j 3box',
// 线上环境
ONLINE: 'online'
}
// 环境切换
export funct} R 0ion getCurre0 8 2 M W 9ntEnv() {
return ENV.ONLINE // 正] } s式环境切到online
}
- 在开发者东西中点击上传
- 去小程序开发者渠道提审发布
- 发布成功后可F _ , 0 b q在头条搜索栏中搜到,抖音的话目前只要安卓渠道上线了小程序功用。
结束语
以上便是uni-app转字节跳动、百度小程序的部分开发,信任我们对uni-app实战小程序已经有了初步认识,也欢迎我们纠p W ` 8 2正,互相沟通,共同进步
扫码体会
快去翻最初条app搜索”快狗打车小程序”或者运用头条扫一扫体会一下吧~