这里主要使用uni-app来把普通h5项目转成app项目。由于头一次使用,踩了很多坑。终于熬到app上线,来这总结下h5转app需要注意的点.方便后续再转项目。
持续更新~~
没有window 和 document对象
感受最大的就是这两点.
1.就是说比如获取元素不能使用document.getElementById
uni-app里这样查找元素
// 通过refs找到元素
<div ref='mydiv'></div>
<script>
onLoad() {
let element = this.$refs.mydiv
}
<script>
// 通过uni-api获取
const query = uni.createSelectorQuery().in(this);
query.select('#press').boundingClientRect(data => {
console.log(data)
this.pergressWidth = parseInt(data.width)
}).exec();
/* data的值参考如下
data ===> {
'height': 21,
'dataset': {},
'right': 534.2222290039062,
'id': 'press',
'bottom': 246,
'width': 534.2222290039062,
'left': 0,
'top': 225
}
*/
// 根据类名查找元素
let doms = query.selectAll('.press')
doms.fields({
rect: true, // 是否返回节点布局信息{top,bottom,right,left}
size: true, // 返回尺寸信息 width, height
scrollOffset: true, // 返回节点滚动信息 scrollTop scrollLeft
},function(res){ // res 包含第一个参数中指定true的相关信息
}).exec(function() {// 节点信息获取成功后的回调
})
2.不能通过window获取设备信息,比如窗口宽高
uni-app API的获取方式
uni.getSystemInfo({
success(res) {
// 成功了调用的函数
console.log(res.appId);
console.log(res.appName);
console.log(res.appVersion);
console.log(res.appLanguage);
console.log(res.appVersionCode);
console.log(res.browserName);
console.log(res.browserVersion);
console.log(res.deviceId);
console.log(res.deviceBrand);
console.log(res.deviceModel);
console.log(res.deviceType);
console.log(res.deviceOrientation);
console.log(res.devicePixelRatio);
console.log(res.hostName);
console.log(res.hostVersion);
console.log(res.hostLanguage);
console.log(res.hostTheme);
console.log(res.hostPackageName);
console.log(res.hostSDKVersion);
console.log(res.osName);
console.log(res.osVersion);
console.log(res.osLanguage);
console.log(res.osTheme);
console.log(res.osAndroidAPILevel);
console.log(res.romName);
console.log(res.romVersion);
console.log(res.uniPlatform);
console.log(res.uniCompileVersion);
console.log(res.uniRuntimeVersion);
console.log(res.ua); // userAgent标识
console.log(res.screenWidth); // 屏幕宽度
console.log(res.screenHeight); // 屏幕高度
console.log(res.windowWidth); // 屏幕可使用宽度
console.log(res.windowHeight); // 屏幕可使用高度
console.log(res.windowTop); // 可使用窗口顶部位置
console.log(res.windowBottom); // 可使用窗口底部位置
console.log(res.statusBarHeight); // 手机状态栏高度
console.log(res.safeArea); // 竖屏正方向下的安全区域
console.log(res.safeAreaInsets); // 竖屏正方向下的安全区域插入位置
},
fail (err) { // 失败了调用
},
complete () { // 成功失败都会调用
}
})
// 他还有个【同步方法】
let ref = uni.getSystemInfoSync() // 返回结构同上
类似的方法还有
uni.getWindowInfo()
它返回的参数如下
app生命周期 && 全局数据
这些周期对应整个app,即全局的周期控制在App.vue中定义这些函数即可控制。
还有个全局对象globallData, 也是在App.vue中用来定义全局数据的
<script>
export default {
globalData: {
text: 'text'
}
}
</script>
<script>
export default {
onLoad(option) {
//获取这样获取
console.log(getapp().globalData.text)
}
}
</script>
默认不支持 axios
需要做以下配置才行
// 只是app端不支持,需要做以下处理
axios.defaults.adapter = function(config) {
return new Promise((resolve, reject) => {
var settle = require('axios/lib/core/settle');
var buildURL = require('axios/lib/helpers/buildURL');
var buildFullPath = require('axios/lib/core/buildFullPath');
let fullurl = buildFullPath(config.baseURL,config.url)
uni.request({
method: config.method.toUpperCase(),
url: buildURL(fullurl, config.params, config.paramsSerializer),
header: config.headers,
data: config.data,
dataType: config.dataType,
responseType: config.responseType,
sslVerify: config.sslVerify,
complete:function complete(response){
response = {
data: response.data,
status: response.statusCode,
errMsg: response.errMsg,
header: response.header,
config: config
};
settle(resolve, reject, response);
}
})
})
}
路由跳转 不支持router 更不支持链接
它的跳转发方式与小程序如出一辙
// 基础的就是
// a标签需要替换成 navigator 标签,href属性换成url属性;animation-type规定跳转动画类型,可选值有slide-in-left,pop-in, zoom-out,zoom-fade-out,none等;animation-duration持续时间
<navigator animation-type='pop-in' animation-duration='300' url='../test/test'>navigator</navigator>
uni.navigateTo({
url: '/pages/index?a=5&b=7', // 【只有这一个必传参数】,跳转的页面,参数要param形式传递
// 接收参数要在跳转到的页面的onLoad(option)函数的option里接收:option.a
animationType: 'fade-in', // 动画
animationDuration: '300', // 动画时间
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success(res) {
// 调用成功执行,可以通过res.eventChannel继续像跳入的页面传数据
}
})
// 跳入页面可以通过如下操作来给来源页面传数据
onLoad: function(option) {
// #ifdef APP-NVUE
const eventChannel = this.$scope.eventChannel; // 兼容APP-NVUE
// #endif
// #ifndef APP-NVUE
const eventChannel = this.getOpenerEventChannel();
// #endif
eventChannel.emit('acceptDataFromOpenedPage', {data: 'data from test page'});
eventChannel.emit('someEvent', {data: 'data from test page for someEvent'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
}
// 【返回】 可以不传参数,默认返回上一级
uni.navigateBack({
delta: 1, // 返回几级,级数多于当前已有的级数回到首页
animationType: 'pop-in',
animationDuration: '500',
success() {},
fail(){},
complete(){}
})
// 替换当前链接
uni.redirectTo({
url: '/pages/mine', // 必传参数,规则同navigateTo
success(){},
fail(){},
complete(){}
})
没有img标签 使用 <image> 标签代替
uni-app里没有<img 标签,所以转换的时候图片是无法显示的,直接全局替换标签名为<image 即可,其他参数无差别
上传图片或文件逻辑需要更改
选择图片(可选拍照)需要调用uni-app原生的接口: uni.chooseImage({})
上传文件 也需要原生接口: uni.uploadFile({})
// 首先选择图片
uni.chooseImage({
count: 9, // 可选;的图片数量,默认9
sizeType: ['original', 'compressed'], // 可选;original 原图,compressed 压缩图,默认都有
extension: ['.jpg','.png],// 可选;根据拓展名过滤
sourceType: ['album', 'camera'], // 可选;来源;camera 相机 album相册,默认都有
crop:{
quality: 95, // 1-100 的数字,图像质量
width: 500, // 单位px
height: 500,
resize: true, // 默认true,将width height值作为真实像素值
},// 可选;设置图像裁剪参数, 如果有sizeType则失效
success (res) {
// 获取图片成功回调
res:{ // 返回值结构
tempFilePaths: [''], // 所有图片的路径列表
tempFiles: [file,file]// 所有图片的file列表
}
}
})
// 然后是上传图片
uni.uploadFile({
url: url, // 上传的链接,完整链接
header: { // 正常设置的header,不能设置referrer
token,
'Content-Type': 'multipart/form-data'
},
filePath: data.file, // 要上传的文件路径,就是上边的tempFilePaths中某一项的值
name:'file', // 服务器接收的key 名字
onUploadProgress (progress){ // 上传进度回调函数, 可以计算进度
progress.loaded // 文件已经上传的数量
progress.total // 文件所有的字节数
},
success(res) {
// 返回的 res的data里才是服务器处理的结果,如果服务器返回的json,需要自己手动转化下
let data = JSON.parse(res.data)
if (data.code != 200) {
Message({
type: 'error',
message: data.message || '未知错误~'
})
}
if (callback) {callback(data)}
resolve(data)
},
fail (err) {
if (callback) {callback(err)}
reject(err)
},
complete () {}
})