uni-app-Video
一个优秀的uni-app案例,旨在帮助大家更快的上手uni-app,共同进步!
Features
- 代码编写简洁,注释清晰,快速入门必备;
- 支持在线模糊搜索;
- 程序类目懒加载,支持在线播放预告片;
- 更好的App跨平台框架、更方便的H5开发框架,加载新页面速度更快;
- 一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
扫码体验
启动准备
小程序账号及微信开发者工具: https://mp.weixin.qq.com
建议编辑器:HBuilderX
手摸手启动项目 ( 以小程序为例 ):
1.打开 HBuilderX导入项目:
2.进入manifest.json文件中修改成自己的相关ID(如遇无法加载配置文件,重启编辑器即可);
接下来就可以正常使用啦~
小程序启动可能会遇到问题:
HBuilderX报错:微信开发者工具拒绝HBuilderX访问端口
答:微信开发者工具 -- 设置 -- 安全设置,点击开启服务端口即可解决。
小程序报错:不在以下 request 合法域名列表中
答:这是因为在小程序中发起了wx.request请求,但是请求的域名没有在微信公众平台后台设置,管理员将需要使用的域名添加到小程序后台,(调试时可以点击微信开发者工具右上角 **详情 -- 本地设置 -- 勾选不校验合法域名 **,可暂时取消报错)。
小程序报错:Failed to load media http://xxx.xx server responded with a status of 403
答:这是小程序电影详情页面的预告片视频报错(不影响可忽略此错误),并不是加载视频错误,而是微信开发者工具中加载视频会提示这个错误,所以在调试带有视频的控件时,可以点击真机预览小程序。
项目结构
.
├─ colorui/ # 引入的UI文件
├─ components/ # uni-app组件目录
│ ├─ comp-a.vue # 可复用的a组件
├─ pages/ # 业务页面文件存放的目录
│ ├─ home/
│ │ ├─ index.vue # home页面
│ ├─ detail/
│ │ ├─ index.vue # detail页面
├─ static # 存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─ unpackage/ # 打包目录
├─ App.vue # 应用配置,用来配置App全局样式以及监听
├─ main.js # Vue初始化入口文件
├─ manifest.json # 配置应用名称、appid、logo、版本等打包信息
├─ package.json # 配置页面路由、导航条、选项卡等页面类信息
复制代码Tips:
static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。
css、less/scss 等资源同样不要放在 static 目录下,建议这些公用的资源放在 common 目录下。
uni-app之旅
前言:分享一下遇见过的问题难点和一些注意点,共同进步
像素单位
使用upx/rpx 而不是 px
修改内容(评论区大佬的订正): 1px = 2upx是不准确的,upx和rpx是响应式单位,以750px为基准宽度,根据设备屏幕宽度自动调整
路由
uni-app的路由全部配置在page.json
这个文件中,问题就在于多人开发的时候,路由无法拆分,如果处理的不好,经常发生冲突。至于其中的一些配置项,就请见官方文档。
在页面中没有专门的 $route
和 $router
对象 仅能在页面的生命周期里面接受路由传参,详情见文档。
路由传参方式
let url = `/pages/shopManagement/sonPage/billDetails?StoreID=${StoreID}`
复制代码
路由接参方式:
onLoad(route){
this.getData.StoreID=route.StoreID
this.getCurryInfo()
},
onLoad接收到一个参数对象
DOM操作
如果你的项目仅是h5,那可以放心大胆的使用dom操作,但如果要在小程序和app跑,就不要做dom操作了,不生效。
不过ref还是可以用的,一样可以获取到这个节点,该干啥干啥。
生命周期
说到ref我就要提一下生命周期
具体的生命周期在文档中可以看详情
大致上和vue的差不多,分成页面生命周期和应用生命周期,页面生命周期就是针对单页面的,应用生命周期就是针对整个小程序/app的,不过我提出在开发时的一些情况
在组件中,没有生命周期,对,你没看错!比如页面a引用了组件b 在组件b中,onLoad,onShow,onReady全部失效,不过用created和mounted是生效的,但是我在开发的时候还是没有用created和mounted,毕竟文档明确写到
所以我在组件中规避使用原vue的生命周期,另外,在上面说了ref,如果要在初始化使用ref要注意生命周期,在onload和show的钩子中,内部如果是同步操作是用不了的,拿不到$refs
,我不知道怎么解释这个问题,在vue中很好解释,在created拿不到ref是因为dom还没有渲染出来,只有在mounted时dom渲染出来了才能拿到ref,但是uniapp中不是没得dom嘛。。。。。我也没深究过,如果要用,只能异步,可以加setTimeout 或者 放在某个请求后用,这个时候是可以拿到ref的
关于请求
我最开始的时候是自己简单的封装了一下发送的请求
export const HttpRequest_ = {
config: function(name) {
var info = null;
if (name) {
var name2 = name.split("."); //字符分割
if (name2.length > 1) {
info = configdata[name2[0]][name2[1]] || null;
} else {
info = configdata[name] || null;
}
if (info == null) {
let web_config = cache.get("web_config");
if (web_config) {
if (name2.length > 1) {
info = web_config[name2[0]][name2[1]] || null;
} else {
info = web_config[name] || null;
}
}
}
}
return info;
},
post: function(url, data, header) {
header = header || "application/x-www-form-urlencoded";
//url = this.config("APIHOST")+url;
return new Promise((succ, error) => {
showLoading_()
uni.request({
url: url,
data: data,
method: "POST",
header: {
"content-type": header
},
success: function(result) {
hidLoading_()
succ.call(self, result.data)
},
fail: function(e) {
hidLoading_()
error.call(self, e)
}
})
}).then(res=>{
console.log(res)
return res
},err=>{
console.log('err:',err)
})
},
get: function(url, data, header) {
header = header || "application/x-www-form-urlencoded";
//url = this.config("APIHOST")+url;
return new Promise((succ, error) => {
showLoading_()// 加载中
uni.request({
url: url,
data: data,
method: "GET",
header: {
"content-type": header
},
success: function(result) {
hidLoading_() //关闭加载中
succ.call(self, result.data)
},
fail: function(e) {
hidLoading_() //关闭加载中
error.call(self, e)
}
})
}).then(res=>{
console.log(res)
return res
},err=>{
uni.showToast({
duration:2000,
title:'数据异常,请稍后再试',
icon:'none'
})
console.log('err:',err)
})
}
}
复制代码
之前我以为在Uniapp中发送请求只能用他们请求方法,后来同事说也可以用其他的。
我们便引入其他的库。这是uniapp插件市场别人封装好的,用起来还是比较舒服
动态的class style
具体的文档在这里:
我一开始是没有注意到这一点,按照我的一些常规习惯写并且一直在用h5调试,没有任何问题,后来上真机和小程序开发工具之后才发现全部失效。
打开第三方的网址或app
在app端想要打开第三方的网址或者程序,一定要区分ios和安卓端。
首先,ios和安卓唤起第三方app的地址是不一样的。
不管是在调试还是打包,要唤起第三方程序,在ios端要配置白名单
三方登录
以微信登录位例:
在app端,uni-app集成的几个方法,可以很顺利的拿到unionId,openid等一些列信息
uni.getProvider({//获取uniapp支持的第三方数据
service:'oauth'
}).then(data=>{
var [err,res] = data
var providers=res.provider//类型(微信,新浪,小米,qq)
var flagIndex=providers.indexOf(provider)
if(flagIndex>-1){
return providers[flagIndex] /
}
}).then(res=>{
return uni.login({//登陆接口(可以获取用户信息)
provider:res,
scopes:'auth_base',
timeout:20000,
})
}).then(data=>{//返回一系列登陆信息
var [err,res] = data
if(res.errMsg==="login:ok"){
self.authResult=res.authResult
return res.authResult
}
}
}).then(res=>{//获取用户的信息 头像,地址,等等等
return uni.getUserInfo({
provider:provider,
timeout:20000,
withCredentials:true
})
}).then(data=>{//得到一些列用户信息
var [err,res] = data
console.log(res)
if(res.errMsg==="getUserInfo:ok"){
return res
}
})
复制代码
但是如果在小程序端,很多方法就失效了,因为小程序有一套自己的三方登录交互策略。
还记得当时刚在app上测成功微信三方登陆后,领导过来看进度,问小程序怎么样,我给他放了个体验版,让他看看,他问我这个微信登录也可以吗?我拍拍胸脯说没得问题,随便登,结果。。。。。。。。。。。。。。。脸疼
uni.login({//登陆接口
provider:'weixin',
scopes:'auth_base',
timeout:20000,
}).then(data=>{//返回一系列登陆信息
let [err,res] = data
if(res.code){
let data ={//这个code很重要,需要拿到code向后台去换unionid等
js_code: res.code
}
return this.$Request.get(this.$store.state.getopenidUrl,data)
}else{
setTimeout(()=>{
this.$api.msg('数据异常')
},500)
uni.switchTab({
url:'/pages/index/index'
})
}
}).then(res=>{
let res_ = JSON.parse(res.Data)
if('unionid' in res_){
this.getIsBindData.openid=res_.unionid
this.getDataWX.openid = res_.unionid
this.getDataWX.unionid = res_.openid
}else{
this.getIsBindData.openid=res_.openid
this.getDataWX.openid = res_.openid
this.getDataWX.unionid = res_.openid
}
return this.WXuserInfo
})
复制代码
其他的三方登录我没有试过,但是一定要注意各端之间的差异性
另外,支付宝三方登录uni-app没有集成,要是自己想做,就用原生来写,理论上是可以做的。由于我们团队没有会原生的,我们试过用webview做支付宝的三方登录,最后还是卡在了授权这一块,不得而终,遂阉了该需求。
2019 8.20 更新:
在插件市场已经有了安卓端和ios端授权登录的插件(是付费插件)详情:
canvas
写成组件在小程序上失效,仅能在index页面上使用。在h5生效,封装成组件也可以,渲染效果也不是太好,app端没有试过,因为后来看效果不好就暂时搁置这个需求了。
评论区朋友的订正: canvas在组件中使用时,记得传递第二个参数组件实例对象:uni.createCanvasContext(canvasId, this)
我试过了,封装成组件的情况下,传入this,在小程序是生效的.之前是没有传入的
开屏引导
uni-app没得开屏这个配置项,只能用一些策略来做。
实质上是是用swiper组件+本地缓存做的模拟开屏引导,注意的是,如果产品一开始就定位了要做引导页,那就考虑好index的怎么写,我们是后期才打算加的,如果要把index改掉成本有点大,所以用了另一种策略,但如果在性能不好的手机上会出现尴尬的事情,就不细说怎么尴尬了,如果用上面的策略,再尴尬也不过是白屏,在上面的demo中,index仅是一个中转页面,什么都没有写。所以个人建议还是用以上的策略。
插件市场和生态
总的来讲,Uniapp的插件市场还是不错的,大多数能用到的插件都可以找到,找不到的也可以从个别相似的插件中找到灵感,自己再魔改一下,论坛也还行,基本上自己遇到的问题都能找到答案,但是也有找不到的或者有人提出却无人回答的,官方qq群也还是比较热闹,有些东西自己没遇见的看看别人的问题和解决方案也算是一种成长,自己遇见过的给别人解答,换来一声谢谢也是很开心的。
插件市场里面我看过or用过比较好的组件
先后推荐不分排名顺序
colorUI 我们四个项目,都是以colorUI做的基础样式,他不是一个组件库,是个css样式库,唯一的缺点就是没有太详细的文档,不过源码都在,过一遍基本上也都熟悉了。
===================================
uCharts 高性能跨全端图表,基本上所有类型的图表都包含了,而且文档也比较清楚,demo也全面 源码也可以根据自己的需求做改动,我自己在开发的时候也改动过源码,用起来很顺手。
===================================
手写签名组件,方便易操作。
===================================
答题模版,这个答题模板是基于colorUI做的,我当时自己懒得写了,就直接搬来用。
ext.dcloud.net.cn/plugin?id=4…
===================================
ThorUI组件库 这个库是个正儿八经的组件库,里面包含了常规的各种组件,我们也买了graceUI,其实对比一下,大体上不相上下的,有不同的需求也可以直接改源码啥的。
===================================
侧边导航 不过侧边导航也实现起来也比较简单,这个是我看到的一个组件,看了下源码,如果是拿来练手实现的话,是个比较好的参照对象。
===================================
O2O本地生活模版 这个模板用来快速开发电商项目很好,作者组件封装的很完善,有需求的只要自己改一下就可以用了。
===================================
mescroll的uni版本, 是在 uni-app 运行的下拉刷新和上拉加载的组件 第一个项目用到了他 不过后来我自己封装了一个就没用了。
===================================
基于flyio接口封装
===================================
腾讯云小程序音视频通讯Uniapp版
结尾提示
使用uni-app注意各端的差异性,很多东西,h5对着的,上真机就错了,真机好着的,换小程序就错了,不同小程序之间还有差异,总之就是考虑好不同的情况,重点是仔细阅读文档。
虽然可能一些原生可以实现的功能uniapp实现不了,不过整体开发下来还是比较愉快,很多的坑还是因为多端不兼容,除了写起来麻烦一点,基本上都还是有可以解决的策略。
也希望uniapp越做越好,各方面越来越完善,为我这种搬砖码农增加一份生存的筹码。