uni-app高分开源电影项目源码案例分析,支持一套代码发布小程序、APP平台多个平台(前端入门必看)

05/16 13:12
阅读数 1.6K

uni-app-Video

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

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

Features

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

扫码体验

H5

启动准备

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

​ 建议编辑器:HBuilderX

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

1.打开 HBuilderX导入项目:

H5

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

H5

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

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

  • 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还是可以用的,一样可以获取到这个节点,该干啥干啥。

img

生命周期

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

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

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

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

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

img

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

img

关于请求

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

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的地址是不一样的。

img

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

img

三方登录

以微信登录位例:

在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,在小程序是生效的.之前是没有传入的 img

开屏引导

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越做越好,各方面越来越完善,为我这种搬砖码农增加一份生存的筹码。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部