uni-app(4):js语法、css语法

发布于:2025-05-24 ⋅ 阅读:(19) ⋅ 点赞:(0)

1 js语法

   uni-app的js API由标准ECMAScript的js API 和 uni 扩展 API 这两部分组成。标准ECMAScript的js仅是最基础的js。浏览器基于它扩展了window、document、navigator等对象。小程序也基于标准js扩展了各种wx.xx、my.xx、swan.xx的API。node也扩展了fs等模块。uni-app基于ECMAScript扩展了uni对象,并且API命名与小程序保持兼容。

1.1 标准js和浏览器js的区别

   uni-app的js代码,h5端运行于浏览器中。非h5端(包含小程序和App),Android平台运行在v8引擎中,iOS平台运行在iOS自带的jscore引擎中,都没有运行在浏览器或webview里。非H5端,虽然不支持window、document、navigator等浏览器的js API,但也支持标准ECMAScript。请注意不要把浏览器里的js扩展对象等价于标准js。

        所以uni-app的非H5端,一样支持标准js,支持if、for等语法,支持字符串、数字、时间、布尔值、数组、自定义对象等变量类型及各种处理方法。仅仅是不支持window、document、navigator等浏览器专用对象。

1.2 ES6 支持

        uni-app 在支持绝大部分 ES6 API 的同时,也支持了 ES7 的 await/async。ES6 API 的支持,详见如下表格部分(x 表示不支持,无特殊说明则表示支持):

String iOS8 iOS9 iOS10 Android
codePointAt
normalize x x 仅支持 NFD/NFC
includes
startsWith
endsWith
repeat
String.fromCodePoint
Array iOS8 iOS9 iOS10 Android
copyWithin
find
findIndex
fill
entries
keys
values x x
includes x
Array.from
Array.of
Number iOS8 iOS9 iOS10 Android
isFinite
isNaN
parseInt
parseFloat
isInteger
EPSILON
isSafeInteger
Math iOS8 iOS9 iOS10 Android
trunc
sign
cbrt
clz32
imul
fround
hypot
expm1
log1p
log10
log2
sinh
cosh
tanh
asinh
acosh
atanh
Object iOS8 iOS9 iOS10 Android
is
assign
getOwnPropertyDescriptor
keys
getOwnPropertyNames
getOwnPropertySymbols
Other iOS8 iOS9 iOS10 Android<5
Symbol
Set
Map
Proxy x x x
Reflect
Promise

        默认不需要在微信工具里继续开启es6转换。但如果用了微信的wxml自定义组件(wxcomponents目录下),uni-app编译器并不会处理这些文件中的es6代码,需要去微信工具里开启转换。从HBuilderX调起微信工具时,如果发现工程下有wxcomponents目录会自动配置微信工程打开es6转换。

1.3 App端

        在App端JS脚本运行在独立的JS引擎中,vue页面使用系统webview渲染,nvue页面使用系统原生View渲染。

        Android平台

  • JS脚本运行在独立Google V8引擎中,版本与Chrome83一致,因此支持的语法与Android系统版本无关,即便是Android4.4也与Chrome83支持的语法一样。
  • vue页面渲染在系统Webview中,受Android系统版本影响,在Android低端机上存在css浏览器兼容性问题,太新的css语法在低版本不支持。当然也可以使用x5等三方webview来拉齐实现。

        iOS平台

  • JS脚本运行在iOS操作系统提供的JavaScriptCore 引擎,因此支持的语法与iOS系统有关,跟iOS系统的Safari浏览器一致。 
  • vue页面渲染在系统WKWebview中,受iOS系统版本影响,兼容性与iOS系统的Safari浏览器一致。

2 css语法

        uni-app 有 vue 页面、nvue 页面、uvue页面。 uni-app 的 css 与 web 的 css 基本一致。

  • vue 页面是 webview 渲染的
  • app-nvue 页面是原生渲染的,其样式比 web 会限制更多
  • app-uvue 页面是原生渲染的,是 web 的css子集

2.1 css预处理器支持

        uni-app 支持less、sass、scss、stylus等预处理器。sass的预处理器,早年使用node-sass,也就是vue2最初默认的编译器。sass官方推出了dart-sass来替代。node-sass已经停维很久了。vue3默认使用的是dart-sass。DCloud推荐开发者尽快升级到vue3,改用dart-sass。

2.2 尺寸单位

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

  • px 即屏幕像素
  • rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,750rpx 恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App(vue2 不含 nvue) 端和 H5(vue2) 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算

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

  • rem 根字体大小可以通过 page-meta 配置抖音小程序和飞书小程序:屏幕宽度/20、百度小程序:16px、支付宝小程序:50px
  • vh viewpoint height,视窗高度,1vh 等于视窗高度的 1%
  • vw viewpoint width,视窗宽度,1vw 等于视窗宽度的 1%

        nvue 还不支持百分比单位。App 端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px。nvue 中,uni-app 模式可以使用 px 、rpx,表现与 vue 中基本一致,另外启用 dynamicRpx 后可以适配屏幕大小动态变化。weex 模式目前遵循 weex 的单位,它的单位比较特殊:

  • px:,以 750 宽的屏幕为基准动态计算的长度单位,与 vue 页面中的 rpx 理念相同。(一定要注意 weex 模式的 px,和 vue 里的 px 逻辑不一样。)
  • wx:与设备屏幕宽度无关的长度单位,与 vue 页面中的 px 理念相同

        rpx 详细说明:设计师在提供设计图时,一般只提供一个分辨率的图。严格按设计图标注的 px 做开发,在不同宽度的手机上界面很容易变形。而且主要是宽度变形。高度一般因为有滚动条,不容易出问题。由此,引发了较强的动态宽度单位需求。

        微信小程序设计了 rpx 解决这个问题。uni-app 在 App 端、H5 端都支持了 rpx,并且可以配置不同屏幕宽度的计算方式rpx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。uni-app 规定屏幕基准宽度 750rpx。开发者可以通过设计稿基准宽度计算页面元素 rpx 值,设计稿 1px 与框架样式 1rpx 转换公式如下:

设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx / 750rpx

        换言之,页面元素宽度在 uni-app 中的宽度计算公式:

750 * 元素在设计稿中的宽度 / 设计稿基准宽度

举例说明:

  1. 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 750,结果为:100rpx。
  2. 若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 640,结果为:117rpx。
  3. 若设计稿宽度为 375px,元素 B 在设计稿上的宽度为 200px,那么元素 B 在 uni-app 里面的宽度应该设为: 750 * 200 / 375,结果为:400rpx。
  • 注意 rpx 是和宽度相关的单位,屏幕越宽,该值实际像素越大。如不想根据屏幕宽度缩放,则应该使用 px 单位。
  • 如果开发者在字体或高度中也使用了 rpx ,那么需注意这样的写法意味着随着屏幕变宽,字体会变大、高度会变大。如果你需要固定高度,则应该使用 px 。
  • rpx 不支持动态横竖屏切换计算,使用 rpx 建议锁定屏幕方向
  • 设计师可以用 iPhone6 作为视觉稿的标准。
  • App 端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px,不支持 rpx。
  • 早期 uni-app 提供了 upx ,目前已经推荐统一改为 rpx 了

2.3 样式导入

        使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。

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

    .uni-card {
        box-shadow: none;
    }
</style>

2.4 内联样式

        框架组件上支持使用 style、class 属性来控制组件的样式。

  • style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
<view :style="{color:color}" />
  • class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。
<view class="normal_view" />

2.5 选择器

选择器 样例 样例描述
.class .intro 选择所有拥有 class="intro" 的组件
#id #firstname 选择拥有 id="firstname" 的组件
element view 选择所有 view 组件
element, element view, checkbox 选择所有文档的 view 组件和所有的 checkbox 组件
::after view::after 在 view 组件后边插入内容,仅 vue 页面生效
::before view::before 在 view 组件前边插入内容,仅 vue 页面生效
  • 在 uni-app 中不能使用 * 选择器。
  • 微信小程序自定义组件中仅支持 class 选择器
  • page 相当于 body 节点,例如:
<!-- 设置页面背景颜色,使用 scoped 会导致失效 -- >
page {
  background-color: #ccc;
}
  • web端可以使用htmlbody:root等选择器。由于页面的css样式隔离,且html节点并未添加data-xxx属性,html:root写在页面style内无效,只能写在App.vue内。

2.6 全局样式与局部样式

        定义在 App.vue 中的样式为全局样式,作用于每一个页面。在 pages 目录下 的 vue 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 App.vue 中相同的选择器。

  • App.vue 中通过 @import 语句可以导入外联样式,一样作用于每一个页面。
  • nvue 页面暂不支持全局样式

2.7 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 设定高度。下方提供了示例代码

        快速书写 css 变量的方法是:在 css 中敲 hei,在候选助手中即可看到 3 个 css 变量。

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

<template>
	<!-- HBuilderX 2.6.3+ 新增 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>

2.8 固定值

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

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

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

2.9 Flex 布局

        为支持跨平台,框架建议使用 Flex 布局。

2.10 背景图片

   uni-app 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:

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

2.11 字体图标

   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');
}

   nvue中不可直接使用 css 的方式引入字体文件,需要使用以下方式在 js 内引入。nvue 内不支持本地路径引入字体,请使用网络链接或者base64形式。src字段的url的括号内一定要使用单引号。

var domModule = weex.requireModule('dom');
domModule.addRule('fontFace', {
	fontFamily: 'fontFamilyName',
	src: "url('https://...')",
});
<template>
	<view>
		<view>
			<text class="test">&#xe600;</text>
			<text class="test">&#xe687;</text>
			<text class="test">&#xe60b;</text>
		</view>
	</view>
</template>
<style>
	@font-face {
		font-family: 'iconfont';
		src: url('https://at.alicdn.com/t/font_865816_17gjspmmrkti.ttf') format('truetype');
	}
	.test {
		font-family: iconfont;
		margin-left: 20rpx;
	}
</style>

网站公告

今日签到

点亮在社区的每一天
去签到