uni-app
官方解释是一款用vuejs
开发前端应用的跨端框架
,从官方解释的第一句话,其实就可以看出,uni-app
集成了vuejs
所有特性,然后具有跨端
的特性,什么是跨端
,通俗理解就是使用uni-app
一套代码开发h5
,App
,微信小程序
,快应用
,支付宝小程序
,QQ小程序
等等。
看到上面uni-app
可以开发多个平台应用,是不是内心很兴奋,what,android
,ios
程序员是不是要失业了,千万不要让我老板看到这种技术,我只会原生ios,android
开发,什么?一套代码代码多端运行?我只是一个切图的,我还要做小程序?APP?快应用?
除了吃惊,更多的是uni-app
简直是万能钥匙啊,面对复杂的多端兼容性需求,程序员掉头发肯定少不了,特别是小程序那主包不得超过1.5M
,总包不得超过2M
的要求,你能想像所有的微信小程序都是2M以内的,而我一张高清图都有6M
了,除了优化再优化,没有更好的选择。
本文是一篇uni-app
入门的笔记,uni-app
这个系列大概会写十来篇,主要会从uni-app
到云开发
,会以实际例子由浅入深认识uni-app
与云开发
,同时也是记录开发中遇到的一些坑。
正文开始...
在开始本文之前,本文主要以下几个方面认识uni-app
uni-app
初始化基础项目有哪些关键目录pages.json
与mainifest.json
文件,探究对应配置项eazycom
全局注册组件,条件编译多端代码uni-app
与web
开发的区别
HbuildērX
使用用uni-app
开发跨端项目,必不可少的一个开发工具就是使用HbuilderX,官方提供了两种方式创建uni-app
- 可视化界面,这种方式是官方推荐的首选,使用官方插件时非常方便
- 命令行
vue-cli
,对于喜欢命令行的,可以用这个,但个人认为使用可视化界面要高效得多
开始一个基础项目
打开HBuilderX
,文件>新建>项目
选择一个uni-app
最简单的默认模版
新建一个02-uni-demo
大概结构就下下面这样
我们可以看到初始化的目录结构与我们普通项目没什么太大的区别,但还是有些区别,因为我们看到项目里有uniCloud
在uni-Cloud
下主要有两个目录,一个是database
,另一个是cloudfunctions
,这两个目录是云开发的关键,在开始云开发前,你必须关联一个服务空间。注意在使用之前,我们必须用邮箱注册登陆HbuilderX
,然后用账号登陆uni-Cloud
创建一个空间,不过此空间是免费,你只能创建一个免费空间,且云函数读取次数只有500次/天
,这量太不够用了,相信我你一定会花钱的,但是不得不说也非常便宜。
database
这个目录是xx.scheme.json
文件,当我们在该目录下新建db schema
时,我们在前端页面可以直接使用云函数连接对应的表cloudfunctions
这个目录是存放云函数
与云对象
关于云函数
,云对象
,还有db schema
我会在后续的云开发
中陆续揭开
当我们使用HBuilderX
创建一个基础项目后,我们是怎么运行的呢?
当我们运行到浏览器时,我们就可以打开页面了
这个默认的页面路由就是pages/index/index.vue
,同时也是在pages.json
中注册的第一个页面
pages.json
我们在普通的web开发中,我们的路由是会自己去手动注册,然后必须挂载在根实例上。但是uni-app
你创建的每一个页面会注册在pages.json
的pages
中
pages.json
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
router
跳转
在pages
中,我们主要看到有path
,这个path
就是我们的路由地址,但是pages
的第一个就是我们程序默认启动的首页,关于pages的配置我们会在后续中逐一讲解,我们也可以去官网看到更多的配置信息
我们尝试在pages
中新建一个页面,我们在pages
右键点击新建页面
此时我们在新建的页面中尝试加点自己的写的内容
pages/about/about.vue
<template>
<view>
我是关于页面
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {}
}
</script>
<style>
</style>
看到这个文件我们是不是非常的熟悉,是不是vue
的味道?
是的,除了模版根标签是view
,在script
上所有的钩子函数都是与vue
没有任何区别
在开头
我们就知道uni-app
就是使用了vuejs
开发跨端应用的,同时又新增了小程序API
与条件编译
,所以你会看到在使用uni-app
开发小程序时,你会看到小程序的API
当我们在浏览器输入地址http://localhost:8080/#/pages/about/about
时就可以打开刚才你新建的一个页面了
关于uni-app
中的路由跳转主要有以下三种
uni.navigateTo({url: 'xxx?id=123'})
; 保留当前页面,前往另一个非tabBar
页面,可以携带参数,当前页面不会被销毁,使用这个api
跳转另一个页面时,使用uni.navigateBack
返回上一个页面,只能打开非tabBar
页面
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view @click="goToAbout">前往关于页面</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
}
},
onLoad() {
},
methods: {
goToAbout() {
uni.navigateTo({
url:"/pages/about/about"
})
}
}
}
</script>
<style>
</style>
uni.redirectTo
关闭当前页面,前往另一个页面,与navigateTo
的区别是,跳转的新页面不会有返回操作,只能打开非tabBar
页面uni.reLaunch
关闭所有页面,前往指定页面,可以打开任意页面uni.switchTab
切换tabBar
,只能打开tabBar
的路由页面
关于这几个路由跳转的api
触发页面钩子也会有所不同
当我们使用uni.navigateTo
跳转about
页面时,此时about
页面的两个钩子会被触发onLoad
,onShow
。因为navigateTo
不会销毁当前页面,所以在about
页面返回上一个页面时会直接从页面栈中获取,此时只会触发onShow
不会触发onLoad
钩子
所以此时你会遇到一个场景,A
页面onLoad
钩子请求数据,在A
页面列表也编辑进入详情页保存然后返回,你会发现此时页面不会更新,因为此时A
页面不会触发onLoad
钩子,所以此时请求放在onLoad
钩子估计不太合适,所以要么你把请求放在onShow
中,要么就想办法重新触发onLoad
而重新触发onLoad
你可以使用uni.reLaunch
关于路由跳转钩子在不同场景都会有不同的选择,更多细节参考官方文档router
globalStyle
我们看到基础配置就有这个,主要是全局设置默认页面窗口的基本公用样式,比如title
、导航
、不同平台的默认首页样式,一般是pages
的第一项为默认页
tabBar
这是我们切换底部tabBar
的页面切换,最关键的就是list
项的配置,当我们配置底部tabBar
后,我们的页面底部就会出现三个切换项,这里的配置是同小程序是一样的
{
...
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"list": [{
"pagePath": "pages/index/index",
"text": "Web技术",
"value": "1"
},
{
"pagePath": "pages/engineer/engineer",
"text": "工程化",
"value": "0"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"value": "2"
}
]
}
}
subPackages
这个选项能减少小程序主包
的大小,算是优化小程序体积的一种有效手段,因为小程序主包限制1.5M
,总体积不能超过2M
,所以我们非常有必要将非tabBar
页面尽可能的分包出去,从而会减少主包的大小easycom
在官方文档上,HBuilderX 2.5.5
支持eazycom
自动引入组件模式,本质上就是按照官方规范
,组件就可以自动注册,并全局使用,在打包后eazycom
会剔除未使用的组件
关于规范
引入官方一段原话
只要组件安装在项目根目录或uni_modules的components目录下,并符合components/组件名称/组件名称.vue或uni_modules/插件ID/components/组件名称/组件名称.vue目录结构,就可以不用引用、注册,直接在页面中使用
这段话翻译的简版就是在根目录,假设我创建一个全局组件,在components
目录下创建一个custEditor
的组件
components/custEditor/custEditor.vue
这个组件就只要符合这种文件结构,那么我们就可以在其他页面上不用局部注册,就可以使用
<template>
<view class="container">
<custEditor></custEditor>
</view>
</template>
<script>
// 这里不用import引入,也不需要在components内注册custEditor组件。template里就可以直接用
export default {
data() {
return {
}
}
}
</script>
另外一个就是在uni_modules
中的符合这样的文件目录也会自动被注册
uni_modules/uni-badge/components/uni-badge/uni-badge.vue
我们注意到所有官方插件都是这种目录结构,如果你想安装插件,就直接去官方插件市场搜索导入就可
直接导入你的HBuilderX
即可
正常情况如果使用官方插件市场导入,那么会默认支持eazycom
自动导入组件全局注册,而且eazycom
是自动开启的,官方提供了可支持自定义配置
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@/components/uni-$1.vue", // 匹配components目录内的vue文件
"^vue-file-(.*)": "packageName/path/to/vue-file-$1.vue" // 匹配node_modules内的vue文件
}
}
mainifest.json
这是一个配置文件,如果是小程序,那么需要配置对应的appid
以及对应其他跨端的相关配置,目前只配置了小程序
与web配置
,没有太多复杂东西,小程序只需要将微信公众号新注册的小程序appid
填入即可
uni-app与web
如果没有开发过小程序,貌似这东西很高大上,但其实并没有太多新颖,微信小程序开发是有微信自己的一套语法API,有自己的标签,页面生命周期钩子
,非常贴近vue
语法。
掌握了vueJS
与最基础的web
开发,完全是很容易的上手小程序,而uni-app
就是用vuejs
语法开发小程序与跨端应用的。
在uni-app
页面布局就是用view
标签,在uni-app
中,这是一个内置组件,类似web
中的div
,是一个视图容器,在uni-app
中根组件必须使用view
标签包裹。
当然uni-app
也提供了其他标签,比如scroll-view
,swiper
等,这些都是uni-app
内置的组件,在web
开发中,我们会使用div
,span
,img
等标签,但是uni-app
最基础的组件就是view
,这个相当div
,我们使用的uni-app
内置组件非常有限,一般都是view
与text
,而在布局样式上基本没有什么太大的区别
在uni-app
中提供了uni
这样的api访问内置的一些方法,比如设置缓存,获取设备信息以及蓝牙等设备信息,与普通不同的web不同的是,uni-app
在其他小程序是无法访问window
对象,当只有运行h5
时,才是运行在浏览器环境里,此时才可以访问window
,document
对象,否则在其他平台会报错,所以此时你可以使用条件编译
来区分不同的端。
条件编译
在同一个工程项目里使用条件编译
有选择的编译需要的代码
下面这块代码使用条件编译,我们发现是以单行注释的方式定义编译条件的,这块代码只会在H5端有作用
// #ifdef H5
window.location.href = 'xxx';
// #endif
在模版中
的条件编译
<!-- #ifdef H5 -->
<view>只会在H5显示的内容</view>
<!-- #endif -->
在css
中的条件编译
/* #ifdef H5 */
.h5box {
width: 100%;
height: 100rpx;
}
/* #endif */
我们只需要// #ifdef %PLATFORM%
开始,以// #endif
结尾就可以标注这块代码块的条件编译
%PLATFORM%
的取值参考官方文档PLATFORM
条件编译真的是维护多端差异的一种必要手段,因为多端差异在同一个工程中,我使用该技术就可区别化不同端。
最后,最近写了一个个人小程序,前端就是使用uni-app
开发的,后端使用uni-Cloud
,有使用官方的插件uni-ui
也有uView
,登陆注册使用的就是官方的uni-id-pages
,小程序后台使用的是uni-admin
开发,基本实现了首页所有模块的增删查改。
总结
主要使用认识一个最简单的
uni-app
项目,了解项目基本结构,以及对HBuilderX
创建uni-app
的初步认识在
uni-app
关键的pages.json
与mainifest.json
相关配置项,当你新建页面时,会在pages.json
的pages
注册路由,在tabBar
中配置底部切换,mainifest
主要是小程序端
的appid
,其他也没什么太多的配置eazycom
自动注册全局组件,这种方式主要是遵循官方规范即可,全局组件主要有uni_moudles
与components
两种方式,也可在pages.json
中自定义设置eazycom
规则,默认是自动启动eazycom
认识
uni-app
与普通web
开发的一些不同,知道条件编译
可以区分不同端,使用uni-app
几本内置组件布局。小程序
开发并没那么高大上,门槛也没有想象那么大,所以有小程序需求,如果是跨端项目,那么uni-app
是一种比较可靠的技术方案本文示例code example