uni-app

网络模型

前后端分离,通过js api(类似ajax的uni.request)获取json数据,把数据绑定在界面上渲染

文件类型

现在是.vue文件,开发是vue,经过编译后,运行时已经变成了js文件。
现代前端开发,很少直接使用HTML,基本都是开发、编译、运行。所以uni-app有编译器、运行时的概念。

代码架构

现在template是一级节点,用于写tag组件,script和style是并列的一级节点,也就是有3个一级节点。

<template>  
    <view>  
    注意必须有一个view,且只能有一个根view。所有内容写在这个view下面。  
    </view>  
</template>  

<script>  
    export default {  

    }  
</script>  

<style>  

</style>

 

外部文件引用方式

现在是es6的写法,import引入外部的js模块(注意不是文件)或css. 

<script>  
var util = require('../../../common/util.js');  //require这个js模块  
var formatedPlayTime = util.formatTime(playTime); //调用js模块的方法  
</script>

js要require进来,变成了对象。

<style>  
    @import "./common/uni.css";  

    .uni-hello-text{  
        color:#7A7E83;  
    }  
</style>

全局样式,在根目录下的app.vue里写入

 nvue页面暂不支持全局样式

组件引入

传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。easycom将其精简为一步。 只要组件安装在项目的components目录下,并符合components/组件名称/组件名称.vue目录结构。就可以不用引用、注册,直接在页面中使用。 

标签变为组件

下为html标签和uni-app内置组件的映射表:

新增了一批手机端常用的新组件

除了内置组件,还有很多开源的扩展组件,把常用操作都进行封装,详见插件市场

js的变化

js的变化,分为运行环境变化、数据绑定模式变化、api变化3部分。

  • 运行环境从浏览器变成v8引擎

标准js语法和api都支持,比如if、for、settimeout、indexOf等。

但浏览器专用的window、document、navigator、location对象,包括cookie等存储,只有在浏览器中才有,app和小程序都不支持。

可能有些人以为js等于浏览器里的js。其实js是ECMAScript组织管理的,浏览器中的js是w3c组织基于js规范补充了window、document、navigator、location等专用对象。

在uni-app的各个端中,除了h5端,其他端的js都运行在一个独立的v8引擎下,不是在浏览器中,所以浏览器的对象无法使用。如果你做过小程序开发,对此应当很了解。

这意味着依赖document的很多HTML的库,比如jqurey无法使用。

当然app和小程序支持web-view组件,里面可以加载标准HTML,这种页面仍然支持浏览器专用对象window、document、navigator、location。

  • 以前的dom操作,改成vue的MVVM模式
<template>  
    <view>  
        <text>{{textvalue}}</text><!-- 这里演示了组件值的绑定 -->  
        <button :type="buttontype" @click="changetextvalue()">修改为789</button><!-- 这里演示了属性和事件的绑定 -->  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                textvalue:"123",  
                buttontype:"primary"  
            };  
        },  
        onLoad() {  
            this.textvalue="456"//这里修改textvalue的值,其实123都来不及显示就变成了456  
        },  
        methods: {  
            changetextvalue() {  
                this.textvalue="789"//这里修改textvalue的值,页面自动刷新为789  
            }  
        }  
    }  
</script>

要注意:

  • 小程序的数据绑定参考了vue,但自己修改了一些。在uni-app中只支持标准的vue,不支持小程序的数据绑定语法

  • 小程序里的setData在uni-app里并不存在,因为vue是自动双向数据绑定的。直接通过赋值方式修改数据,如果数据绑定到界面上,界面会自动更新渲染

js api的变化

因为uni-app的api是参考小程序的,所以和浏览器的js api有很多不同,如

  1. alert,confirm 改成 uni.showmodel
  2. ajax 改成 uni.request
  3. cookie、session 没有了,local.storage 改成 uni.storage

uni-app的js api还有很多,但基本就是小程序的api,把wx.xxx改为uni.xxx即可。详见

uni-app在不同的端,支持条件编译,无限制的使用各端独有的api,详见条件编译

css的变化

标准的css基本都是支持的。

选择器有2个变化:*选择器不支持;元素选择器里没有body,改为了page。微信小程序即是如此。

单位方面,px无法动态适应不同宽度的屏幕,rem无法用于nvue/weex。如果想使用根据屏幕宽度自适应的单位,推荐使用rpx,全端支持。 尺寸单位文档

uni-app推荐使用flex布局,并默认就是flex布局,这个布局思路和传统流式布局有点区别。但flex的有趣在于,不管是什么技术都支持这种排版,web、小程序/快应用、weex/rn、原生的iOS、Android开发,全都支持flex。

uni-app的vue文件里支持所有web排版方式,不管是流式还是flex。但nvue里,只支持flex,因为它在app端是使用原生排版引擎渲染的。

注意css里背景图和字体文件,尽量不要大于40k,因为会影响性能。在小程序端,如果要大于40k,需放到服务器侧远程引用或base64后引入,不能放到本地作为独立文件引用。

工程结构和页面管理

uni-app的工程结构有单独的要求,详见

每个可显示的页面,都必须在 pages.json 中注册。如果你开发过小程序,那么pages.json类似app.json。如果你熟悉vue,这里没有vue的路由,都是在pages.json里管理。

原来工程的首页一般是index.html或default.html,是在web server里配的。而uni-app的首页,是在pages.json里配的,page节点下第一个页面就是首页。一般在/pages/xx的目录下。

app和小程序中,为了提升体验,页面提供了原生的导航栏和底部tabbar,注意这些配置是在pages.json中做,而不是在vue页面里创建,但点击事件的监听在显示的vue页面中做。

在vue中,以前的js事件监听概念改为了生命周期概念。详见uni-app生命周期

如果你熟悉小程序开发的话,对比变化如下:

  • 原来app.json被一拆为二。页面管理,被挪入了uni-app的pages.json;非页面管理,挪入了manifest.json
  • 原来的app.js和app.wxss被合并到了app.vue中

 

开发规范

uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范
  • 组件标签靠近小程序规范,详见uni-app 组件规范
  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  • 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  • 为兼容多端运行,建议使用flex布局进行开发

一个uni-app工程,默认包含如下目录及文件:

    
┌─cloudfunctions        云函数目录(阿里云为aliyun,腾讯云为tcb,详见uniCloud)
│─components            符合vue组件规范的uni-app组件目录
│  └─comp-a.vue         可复用的a组件
├─hybrid                存放本地网页的目录,详见
├─platforms             存放各平台专用页面的目录,详见
├─pages                 业务页面文件存放的目录
│  ├─index
│  │  └─index.vue       index页面
│  └─list
│     └─list.vue        list页面
├─static                存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─wxcomponents          存放小程序组件的目录,详见
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json         配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json            配置页面路由、导航条、选项卡等页面类信息,详见
    
有效目录说明
app-plus App
h5 H5
mp-weixin 微信小程序
mp-alipay 支付宝小程序
mp-baidu 百度小程序

 

模板内引入静态资源

template内引入静态资源,如imagevideo等标签的src属性时,可以使用相对路径或者绝对路径,形式如下

<!-- 绝对路径,/static指根目录下的static目录,在cli项目中/static指src目录下的static目录 -->
<image class="logo" src="/static/logo.png"></image>
<image class="logo" src="@/static/logo.png"></image>
<!-- 相对路径 -->
<image class="logo" src="../../static/logo.png"></image>
注意
  • @开头的绝对路径以及相对路径会经过base64转换规则校验
  • 引入的静态资源在非h5平台,均不转为base64。
  • H5平台,小于4kb的资源会被转换成base64,其余不转。
  • 支付宝小程序组件内 image 标签不可使用相对路径

js文件引入

 js文件或script标签内(包括renderjs等)引入js文件时,可以使用相对路径和绝对路径,形式如下

// 绝对路径,@指向项目根目录,在cli项目中@指向src目录
import add from '@/common/add.js'
// 相对路径
import add from '../../common/add.js'

注意

  • js文件不支持使用/开头的方式引入

css引入静态资源

css文件或style标签内引入css文件时(scss、less文件同理),可以使用相对路径或绝对路径

/* 绝对路径 */
@import url('/common/uni.css');
@import url('@/common/uni.css');
/* 相对路径 */
@import url('../../common/uni.css');

css文件或style标签内引用的图片路径可以使用相对路径也可以使用绝对路径,需要注意的是,有些小程序端css文件不允许引用本地文件

/* 绝对路径 */
background-image: url(/static/logo.png);
background-image: url(@/static/logo.png);
/* 相对路径 */
background-image: url(../../static/logo.png);

Tips

  • 引入字体图标请参考,字体图标
  • @开头的绝对路径以及相对路径会经过base64转换规则校验
  • 不支持本地图片的平台,小于40kb,一定会转base64。(共四个平台mp-weixin, mp-qq, mp-toutiao, app v2)
  • h5平台,小于4kb会转base64,超出4kb时不转。
  • 其余平台不会转base64

 使用本地路径背景图片需注意:

  1. 为方便开发者,在背景图片小于 40kb 时,uni-app 编译到不支持本地背景图的平台时,会自动将其转化为 base64 格式;
  2. 图片大于等于 40kb,会有性能问题,不建议使用太大的背景图,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用。
  3. 本地背景图片的引用路径推荐使用以 ~@ 开头的绝对路径。
  4. 微信小程序不支持相对路径(真机不支持,开发工具支持)
.test2 {
     background-image: url('~@/static/logo.png');
 }

应用生命周期

uni-app 支持如下应用生命周期函数:

函数名说明
onLaunch uni-app 初始化完成时触发(全局只触发一次)
onShow 当 uni-app 启动,或从后台进入前台显示
onHide 当 uni-app 从前台进入后台
onError 当 uni-app 报错时触发
onUniNViewMessage 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯
onUnhandledRejection 对未处理的 Promise 拒绝事件监听函数(2.8.1+)
onPageNotFound 页面不存在监听函数
onThemeChange 监听系统主题变化

注意

 

页面生命周期

路由

uni-app页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在app.json中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router

路由跳转

uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。

页面栈

框架以栈的形式管理当前所有页面, 当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现触发时机
初始化 新页面入栈 uni-app 打开的第一个页面
打开新页面 新页面入栈 调用 API   uni.navigateTo  、使用组件  <navigator open-type="navigate"/>
页面重定向 当前页面出栈,新页面入栈 调用 API   uni.redirectTo  、使用组件  <navigator open-type="redirectTo"/>
页面返回 页面不断出栈,直到目标返回页 调用 API  uni.navigateBack   、使用组件 <navigator open-type="navigateBack"/> 、用户按左上角返回按钮、安卓用户点击物理back按键
Tab 切换 页面全部出栈,只留下新的 Tab 页面 调用 API  uni.switchTab  、使用组件  <navigator open-type="switchTab"/>  、用户切换 Tab
重加载 页面全部出栈,只留下新的页面 调用 API  uni.reLaunch  、使用组件  <navigator open-type="reLaunch"/>

 

运行环境判断

开发环境和生产环境

uni-app 可通过 process.env.NODE_ENV 判断当前环境是开发环境还是生产环境。一般用于连接测试服务器或生产服务器的动态切换。

  • 在HBuilderX 中,点击“运行”编译出来的代码是开发环境,点击“发行”编译出来的代码是生产环境
  • cli模式下,是通行的编译环境处理方式。
if(process.env.NODE_ENV === 'development'){
    console.log('开发环境')
}else{
    console.log('生产环境')
}

判断平台

平台判断有2种场景,一种是在编译期判断,一种是在运行期判断。

  • 编译期判断 编译期判断,即条件编译,不同平台在编译出包后已经是不同的代码。详见:条件编译
// #ifdef H5
    alert("只有h5平台才有alert方法")
// #endif

如上代码只会编译到H5的发行包里,其他平台的包不会包含如上代码。

  • 运行期判断 运行期判断是指代码已经打入包中,仍然需要在运行期判断平台,此时可使用 uni.getSystemInfoSync().platform 判断客户端环境是 Android、iOS 还是小程序开发工具(在百度小程序开发工具、微信小程序开发工具、支付宝小程序开发工具中使用 uni.getSystemInfoSync().platform 返回值均为 devtools)。
switch(uni.getSystemInfoSync().platform){
    case 'android':
       console.log('运行Android上')
       break;
    case 'ios':
       console.log('运行iOS上')
       break;
    default:
       console.log('运行在开发者工具上')
       break;
}

页面样式与布局

尺寸单位

uni-app 支持的通用 css 单位包括 px、rpx

  • px 即屏幕像素
  • rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。

页面元素宽度在 uni-app 中的宽度计算公式:750 * 元素在设计稿中的宽度 / 设计稿基准宽度。

举例说明:若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 640,结果为:117rpx。

vue页面支持普通H5单位,但在nvue里不支持:

  • rem 默认根字体大小为 屏幕宽度/20(微信小程序、字节跳动小程序、App、H5)
  • vh viewpoint height,视窗高度,1vh等于视窗高度的1%
  • vw viewpoint width,视窗宽度,1vw等于视窗宽度的1%

nvue还不支持百分比单位。

App端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px。注意此时不支持 rpx

nvue中,uni-app 模式(nvue 不同编译模式介绍)可以使用 px 、rpx,表现与 vue 中一致。

Tips

  • 注意 rpx 是和宽度相关的单位,屏幕越宽,该值实际像素越大。如不想根据屏幕宽度缩放,则应该使用 px 单位。
  • 如果开发者在字体或高度中也使用了 rpx ,那么需注意这样的写法意味着随着屏幕变宽,字体会变大、高度会变大。如果你需要固定高度,则应该使用 px 。
  • rpx不支持动态横竖屏切换计算,使用rpx建议锁定屏幕方向
  • 如果设计稿不是750px,HBuilderX提供了自动换算的工具,详见:https://ask.dcloud.net.cn/article/35445

选择器

目前支持的选择器有:

选择器样例样例描述
.class .intro 选择所有拥有 class="intro" 的组件
#id #firstname 选择拥有 id="firstname" 的组件
element view 选择所有 view 组件
element, element view, checkbox 选择所有文档的 view 组件和所有的 checkbox 组件
::after view::after 在 view 组件后边插入内容,仅微信小程序和App生效
::before view::before 在 view 组件前边插入内容,仅微信小程序和App生效

注意:

  • 在 uni-app 中不能使用 * 选择器。
  • page 相当于 body 节点,例如:
  • 微信小程序自定义组件中仅支持 class 选择器
     

CSS变量

uni-app 提供内置 CSS 变量

CSS变量描述App小程序H5
--status-bar-height 系统状态栏高度 系统状态栏高度、nvue注意见下 25px 0
--window-top 内容区域距离顶部的距离 0 0 NavigationBar 的高度
--window-bottom 内容区域距离底部的距离 0 0 TabBar 的高度

注意:

  • var(--status-bar-height) 此变量在微信小程序环境为固定 25px,在 App 里为手机实际状态栏高度。
  • 当设置 "navigationStyle":"custom" 取消原生导航栏后,由于窗体为沉浸式,占据了状态栏位置。此时可以使用一个高度为 var(--status-bar-height) 的 view 放在页面顶部,避免页面内容出现在状态栏。
  • 由于在H5端,不存在原生导航栏和tabbar,也是前端div模拟。如果设置了一个固定位置的居底view,在小程序和App端是在tabbar上方,但在H5端会与tabbar重叠。此时可使用--window-bottom,不管在哪个端,都是固定在tabbar上方。
  • 目前 nvue 在App端,还不支持 --status-bar-height变量,替代方案是在页面onLoad时通过uni.getSystemInfoSync().statusBarHeight获取状态栏高度,然后通过style绑定方式给占位view设定高度。下方提供了示例代码

代码块

示例1 - 普通页面使用css变量:

<template>
    <!-- HBuilderX 2.6.3+ 新增 page-meta, 详情:https://uniapp.dcloud.io/component/page-meta -->
    <page-meta>
        <navigation-bar />
    </page-meta>
    <view>
        <view class="status_bar">
            <!-- 这里是状态栏 -->
        </view>
        <view> 状态栏下的文字 </view>
    </view>
</template>    
<style>
    .status_bar {
        height: var(--status-bar-height);
        width: 100%;
    }
</style>
<template>
    <view>
        <view class="toTop">
            <!-- 这里可以放一个向上箭头,它距离底部tabbar上浮10px-->
        </view>
    </view>
</template>    
<style>
    .toTop {
        bottom: calc(var(--window-bottom) + 10px)
    }
</style>

示例2 - nvue页面获取状态栏高度

<template>
    <view class="content">
        <view :style="{ height: iStatusBarHeight + 'px'}"></view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                iStatusBarHeight:0
            }
        },
        onLoad() {
            this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight
        }
    }
</script>

固定值

uni-app 中以下组件的高度是固定的,不可修改:

组件描述AppH5
NavigationBar 导航栏 44px 44px
TabBar 底部选项卡 HBuilderX 2.3.4之前为56px,2.3.4起和H5调为一致,统一为 50px。但可以自主更改高度) 50px

各小程序平台,包括同小程序平台的iOS和Android的高度也不一样。

字体图标

uni-app 支持使用字体图标,使用方式与普通 web 项目相同,需要注意以下几点:

  • 支持 base64 格式字体图标。
  • 支持网络路径字体图标。
  • 小程序不支持在css中使用本地文件,包括本地的背景图和字体文件。需以base64方式方可使用。
  • 网络路径必须加协议头 https
  • 从 http://www.iconfont.cn 上拷贝的代码,默认是没加协议头的。
  • 从 http://www.iconfont.cn 上下载的字体文件,都是同名字体(字体名都叫iconfont,安装字体文件时可以看到),在nvue内使用时需要注意,此字体名重复可能会显示不正常,可以使用工具修改。
  • 使用本地路径图标字体需注意:
    1. 为方便开发者,在字体文件小于 40kb 时,uni-app 会自动将其转化为 base64 格式;
    2. 字体文件大于等于 40kb,仍转换为 base64 方式使用的话可能有性能问题,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用;
    3. 字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
@font-face {
     font-family: test1-icon;
     src: url('~@/static/iconfont.ttf');
 }

<template/> 和 <block/> 并不是一个组件,它们仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

<block/> 在不同的平台表现存在一定差异,推荐统一使用 <template/>

原文地址:https://www.cnblogs.com/yetsen/p/13674376.html