从最早发布的微信小程序,到后来的支付宝小程序、钉钉小程序,字节跳动小程序、百度小程序、QQ小程序等,面对这么多套的代码,开发者去编写多套原生代码的成本显然非常高,使用H5的话体验又没有原生好,这时候只需编写一套代码,就能够适配多端的能力就显得尤为需要。 下面进入正题,给大家介绍下uni-app字节小程序的开发 前置准备工作
项目开发新建项目可以通过 HBuilderX可视化界面 以及 vue-cli命令行 方式进行创建 下面主要介绍下通过vue-cli命令行这中方式来新建项目
npm install -g @vue/cli 复制代码
vue create -p dcloudio/uni-preset-vue user-uni-order 复制代码 安装成功后提示选择模板,我们选择默认模板就可以了 项目整体流程用户下单最短流首页下单-> 订单状态-> 完成支付, 如下: 综上我们需要做的页面维度: 首页,地址检索,城市选择,登录,个人中心,订单列表,webview(收费标准 , 预估价格, 订单状态, 订单详情,法律条款) 制定目录结构┌─components //uni-app组件目录 │ └─comp-a.vue //可复用的a组件 ├─common // 通用的js&css工具等 ├─hybrid //存放本地网页的目录 ├─platforms //存放各平台专用页面的目录 ├─pages //业务页面文件存放的目录 │ ├─index │ │ └─components // 页级别组件 │ │ └─vuex // index页面vuex主要存放index的逻辑 │ │ └─index.vue // index页面 ├─static //存放应用引用静态资源(如图片、视频等) │ ├─mp-weixin //条件编译png │ │ └─a.png │ │ └─b.png ├─store // 状态统一管理,将各个页面的vuex汇总 ├─service // 汇总请求,api等 │ └─api.js // 接口api相关 │ └─config.js // 环境配置 │ └─index.js │ └─request.js // 网络请求 ├─ttcomponents // 头条小程序自定义组件存放目录 ├─main.js //Vue初始化入口文件 ├─App.vue //应用配置,用来配置App全局样式以及监听 ├─manifest.json //配置应用名称、appid、logo、版本等打包信息 └─pages.json //配置页面路由、导航条、选项卡等页面类信息 复制代码 运行项目想运行到哪个平台小程序,首先需要把相应的APPID, IDE路径对应填写正确 npm run dev:mp-toutiao // 实时监听编译 复制代码 运行成功如下提示: 此时打开字节跳动IDE进行导入操作,就可以看见页面啦~~~ Tips:使用字节跳动编译器打开uni-app编译的小程序时,必须进行导入操作,而不是新建,因为新建会默认成代码片段,虽然也可以实时预览效果但是会导致上传功能确实 具体页面的开发首页开发
项目中其他页面的目录结构与首页均相同,后面不做多余赘述。 ├─pages │ ├─index │ │ └─components │ │ └─vuex │ │ │ └─index.js // 首页逻辑 │ │ └─index.vue 复制代码
const IndexPage = { namespaced: true, // 启用模块化vuex state: { ... // 需要共享的状态 }, mutations: { ... // 一些方法 }, actions: { ... // 请求相关 } } export default IndexPage //最后导出IndexPage 复制代码
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: { ... // 全局共用的状态 }, mutations: { }, actions: { }, modules: { IndexPage, // 首页vuex AddressSearch, // 地址检索页vuex CityListPage, // 城市列表页vuex }, }) export default store 复制代码
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() 复制代码 完整的首页逻辑交互框架就搭建成功了,以下是开发首页时遇见的问题 首页开发遇到的问题
问题原因:引入的 import swiper from "../../components/swiper/swiper" ,导致把自定义的swiper覆盖,所以不展示 解决:引入的 import uniSwiper from "../../components/swiper/swiper" ,不和原组件命名冲突即可
问题原因:百度设置http请求header如果有中文字符 解决:使用条件编译,如果是百度小程序需要encodeURI 一下, 或者删除header的中文部分
// 引不到 <image class="tip_icon" src="/static/sender{{endPoint.address ? '' : '_default'}}.png"/> 复制代码 // 可以引入 <image class="tip_icon" src="/static/sender.png"/> 复制代码
<view class="column_item" v-for="(item, idx) in item" :key="`timer__${idx}`" // 改成:key="idx" 即可 > {{item == "立即用车" ? "" : index == 1 ? "时" : index == 2 ? "分" : ""}} </view> 复制代码
watch: { searchType (to) { if (to) { // 如果是起始地回填起始地信息否则回填目的地信息 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 || '' } } 复制代码 个人中心开发
// template <web-view id='web-view' v-if='src' :src='src' @bindmessage='onmessage'></web-view> 复制代码 onLoad (options) { console.log('H5入口页获取到的参数', options) let { src, needLogin} = options if(!needLogin){ this.src = decodeURIComponent(src) return } // 需要登录的 就先获取临时token this.fetchTempToken(src) } 复制代码 如果不需要登录的H5我们直接赋值到src即可,需要登录才能正常访问的页面,首先要获取临时token,拿到临时token后回传给服务端并且采用中间页redirectUrl的形式跳转。 个人中心开发遇到的问题
官方说明“网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息” // 在小程序中调起H5中的打电话功能 onmessage (e) { let { phoneNumber, name } = e.detail if(name == 'makePhoneCall'){ uni.makePhoneCall({ number: phoneNumber }) } } 复制代码 需要注意的web-view的bindmessage属性并不是实时的
// 使用uni.makePhoneCall真机没反应 uni.makePhoneCall({ phoneNumber: '114'}); 复制代码 解决:改为头条api的tt开头 // 真机模拟器均可正常使用 tt.makePhoneCall({ phoneNumber: '114'}); 复制代码 登录开发
// 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"> <!-- #ifdef MP-BAIDU --> <button type="default" open-type="getPhoneNumber" @getphonenumber="authLoginTap" class="login authLogin">百度登录更快捷</button> <!-- #endif --> <!-- #ifdef MP-TOUTIAO --> <button type="default" class="login authLogin" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber" >授权手机号快捷登录</button> <!-- #endif --> </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失败') // 失败的操作,提示等 return } const { code } = data this.code = code }, // 头条获取到用户信息 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等操作 // 重新更新个人信息 } else { // 失败的提示等 } } catch (error) { // 登录失败异常情况处理 } }, // 百度获取到用户信息同理头条。。。 复制代码 登录开发遇到的问题手机验证码开发时,引入 checkbox-group 报错,如下图: 原因: components : { [CheckBox.name]: CheckBox } 引入组件方式不支持 发布到测试环境以字节跳动为例子,打开字节跳动开发者工具,在工具栏找到上传,填写版本号,发布。版本号不和上一次冲突就可以。 Tips: 前面有提过,新建代码片段是在开发者工具上是没有上传按钮的,要导入项目才可以。 上传成功后,会提示进入小程序开发者平台,现在可以看到开发者的版本。 上图二维码就可以只作为本次的体检版本来扫一扫了。 发布到正式环境
// 环境相关配置 export const ENV = { // 开发环境 RD: 'rd', // 测试环境 TEST: 'test', // 沙箱环境 BOX: 'box', // 线上环境 ONLINE: 'online' } // 环境切换 export function getCurrentEnv() { return ENV.ONLINE // 正式环境切到online } 复制代码
结束语以上就是uni-app转字节跳动、百度小程序的部分开发,相信大家对uni-app实战小程序已经有了初步认识,也欢迎大家指正,互相交流,共同进步 |