uni

Easter79
• 阅读 1148

uni-app-Video

GitHub地址:https://github.com/Tzlibai/uni-app-video

一个优秀的uni-app案例,旨在帮助大家更快的上手uni-app,共同进步!

Features

  • 代码编写简洁,注释清晰,快速入门必备;
  • 支持在线模糊搜索;
  • 程序类目懒加载,支持在线播放预告片;
  • 更好的App跨平台框架、更方便的H5开发框架,加载新页面速度更快;
  • 一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。

扫码体验

uni

启动准备

​ 小程序账号及微信开发者工具: https://mp.weixin.qq.com

​ 建议编辑器:HBuilderX

手摸手启动项目 ( 以小程序为例 ):

1.打开 HBuilderX导入项目:

uni

2.进入manifest.json文件中修改成自己的相关ID(如遇无法加载配置文件,重启编辑器即可);

uni

接下来就可以正常使用啦~

小程序启动可能会遇到问题:

  • 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对象 仅能在页面的生命周期里面接受路由传参,详情见文档。

uniapp.dcloud.io/frame?id=路由…

路由传参方式
let url = `/pages/shopManagement/sonPage/billDetails?StoreID=${StoreID}`
复制代码

路由接参方式:

onLoad(route){
    this.getData.StoreID=route.StoreID
    this.getCurryInfo()
},
onLoad接收到一个参数对象

DOM操作

如果你的项目仅是h5,那可以放心大胆的使用dom操作,但如果要在小程序和app跑,就不要做dom操作了,不生效。

不过ref还是可以用的,一样可以获取到这个节点,该干啥干啥。

uni

生命周期

说到ref我就要提一下生命周期

具体的生命周期在文档中可以看详情

uniapp.dcloud.io/frame?id=应用…

大致上和vue的差不多,分成页面生命周期和应用生命周期,页面生命周期就是针对单页面的,应用生命周期就是针对整个小程序/app的,不过我提出在开发时的一些情况

在组件中,没有生命周期,对,你没看错!比如页面a引用了组件b 在组件b中,onLoad,onShow,onReady全部失效,不过用created和mounted是生效的,但是我在开发的时候还是没有用created和mounted,毕竟文档明确写到

uni

所以我在组件中规避使用原vue的生命周期,另外,在上面说了ref,如果要在初始化使用ref要注意生命周期,在onload和show的钩子中,内部如果是同步操作是用不了的,拿不到$refs,我不知道怎么解释这个问题,在vue中很好解释,在created拿不到ref是因为dom还没有渲染出来,只有在mounted时dom渲染出来了才能拿到ref,但是uniapp中不是没得dom嘛。。。。。我也没深究过,如果要用,只能异步,可以加setTimeout 或者 放在某个请求后用,这个时候是可以拿到ref的

uni

关于请求

我最开始的时候是自己简单的封装了一下发送的请求

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插件市场别人封装好的,用起来还是比较舒服

ext.dcloud.net.cn/plugin?id=5…

动态的class style

具体的文档在这里:

uniapp.dcloud.io/use

我一开始是没有注意到这一点,按照我的一些常规习惯写并且一直在用h5调试,没有任何问题,后来上真机和小程序开发工具之后才发现全部失效。

打开第三方的网址或app

在app端想要打开第三方的网址或者程序,一定要区分ios和安卓端。

首先,ios和安卓唤起第三方app的地址是不一样的。

uni

不管是在调试还是打包,要唤起第三方程序,在ios端要配置白名单

uni

三方登录

以微信登录位例:

在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
      }
    })
复制代码

但是如果在小程序端,很多方法就失效了,因为小程序有一套自己的三方登录交互策略。

developers.weixin.qq.com/miniprogram…

还记得当时刚在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端授权登录的插件(是付费插件)详情:

ext.dcloud.net.cn/plugin?id=6…

canvas

写成组件在小程序上失效,仅能在index页面上使用。在h5生效,封装成组件也可以,渲染效果也不是太好,app端没有试过,因为后来看效果不好就暂时搁置这个需求了。

评论区朋友的订正: canvas在组件中使用时,记得传递第二个参数组件实例对象:uni.createCanvasContext(canvasId, this)

我试过了,封装成组件的情况下,传入this,在小程序是生效的.之前是没有传入的 uni

开屏引导

uni-app没得开屏这个配置项,只能用一些策略来做。

ext.dcloud.net.cn/plugin?id=1…

实质上是是用swiper组件+本地缓存做的模拟开屏引导,注意的是,如果产品一开始就定位了要做引导页,那就考虑好index的怎么写,我们是后期才打算加的,如果要把index改掉成本有点大,所以用了另一种策略,但如果在性能不好的手机上会出现尴尬的事情,就不细说怎么尴尬了,如果用上面的策略,再尴尬也不过是白屏,在上面的demo中,index仅是一个中转页面,什么都没有写。所以个人建议还是用以上的策略。

插件市场和生态

总的来讲,Uniapp的插件市场还是不错的,大多数能用到的插件都可以找到,找不到的也可以从个别相似的插件中找到灵感,自己再魔改一下,论坛也还行,基本上自己遇到的问题都能找到答案,但是也有找不到的或者有人提出却无人回答的,官方qq群也还是比较热闹,有些东西自己没遇见的看看别人的问题和解决方案也算是一种成长,自己遇见过的给别人解答,换来一声谢谢也是很开心的。

插件市场里面我看过or用过比较好的组件

先后推荐不分排名顺序

colorUI 我们四个项目,都是以colorUI做的基础样式,他不是一个组件库,是个css样式库,唯一的缺点就是没有太详细的文档,不过源码都在,过一遍基本上也都熟悉了。

ext.dcloud.net.cn/plugin?id=2…

===================================

uCharts 高性能跨全端图表,基本上所有类型的图表都包含了,而且文档也比较清楚,demo也全面 源码也可以根据自己的需求做改动,我自己在开发的时候也改动过源码,用起来很顺手。

ext.dcloud.net.cn/plugin?id=2…

===================================

手写签名组件,方便易操作。

ext.dcloud.net.cn/plugin?id=3…

===================================

答题模版,这个答题模板是基于colorUI做的,我当时自己懒得写了,就直接搬来用。

ext.dcloud.net.cn/plugin?id=4…

===================================

ThorUI组件库 这个库是个正儿八经的组件库,里面包含了常规的各种组件,我们也买了graceUI,其实对比一下,大体上不相上下的,有不同的需求也可以直接改源码啥的。

ext.dcloud.net.cn/plugin?id=5…

===================================

侧边导航 不过侧边导航也实现起来也比较简单,这个是我看到的一个组件,看了下源码,如果是拿来练手实现的话,是个比较好的参照对象。

ext.dcloud.net.cn/plugin?id=7…

===================================

O2O本地生活模版 这个模板用来快速开发电商项目很好,作者组件封装的很完善,有需求的只要自己改一下就可以用了。

ext.dcloud.net.cn/plugin?id=1…

===================================

mescroll的uni版本, 是在 uni-app 运行的下拉刷新和上拉加载的组件 第一个项目用到了他 不过后来我自己封装了一个就没用了。

www.mescroll.com/uni.html

===================================

基于flyio接口封装

ext.dcloud.net.cn/plugin?id=5…

===================================

腾讯云小程序音视频通讯Uniapp版

ext.dcloud.net.cn/plugin?id=1…

结尾提示

使用uni-app注意各端的差异性,很多东西,h5对着的,上真机就错了,真机好着的,换小程序就错了,不同小程序之间还有差异,总之就是考虑好不同的情况,重点是仔细阅读文档。

虽然可能一些原生可以实现的功能uniapp实现不了,不过整体开发下来还是比较愉快,很多的坑还是因为多端不兼容,除了写起来麻烦一点,基本上都还是有可以解决的策略。

也希望uniapp越做越好,各方面越来越完善,为我这种搬砖码农增加一份生存的筹码。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
梦
3年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k