uni-app页面布局

2021-06-21  本文已影响0人  Jagtu

单页面程序

uni-app 约定页面文件遵循 Vue 单文件组件 (SFC) 规范,采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统

<template>
    <view class="container">
        {{message}}
    </view>
</template>

<script>
    export default {
        data() {
            return {
                message: 'Hello World',
            }
        }
    }
</script>
<style>
  .container{
    background-color: #FFF;
  }
</style>

模版语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

模板语法,包含插值、指令

插值

文本,使用双大括号:<span>Message: {{ msg }}</span>

原始HTML,使用v-html指令:<p>Using v-html directive: <span v-html="rawHtml"></span></p>

使用 JavaScript 表达式,支持JavaScript 表达式:{{ number + 1 }}

指令

v-on与v-bind是常用的指令,用于绑定属性设置事件

Attribute,使用v-bind 指令(缩写可以直接省略v-bind):<button v-bind:disabled="isButtonDisabled">Button</button>

事件,使用 v-on 指令(缩写@):<a @click="doSomething">...</a>

条件与循环v-if v-else-if v-else v-for

计算属性与侦听器

计算属性

计算属性是基于它们的响应式依赖进行缓存的

computed: {
  msg: function () {
    return this.message
  }
}

侦听属性

当你有一些数据需要随着其它数据变动而变动时,用 watch

watch: {
    // 如果 `question` 发生改变,这个函数就会运行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  }

class与style绑定

通过动态绑定 style、class 属性来控制组件的样式。

关于选择器注意:

生命周期

应用生命周期

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 支持如下页面生命周期函数:

函数名 说明 平台差异说明 最低版本
onInit 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad 百度小程序 3.1.0+
onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide 监听页面隐藏
onUnload 监听页面卸载
onResize 监听窗口尺寸变化 App、微信小程序
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新,参考示例
onReachBottom 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项
onTabItemTap 点击 tab 时触发,参数为Object,具体见下方注意事项 微信小程序、支付宝小程序、百度小程序、H5、App(自定义组件模式)
onShareAppMessage 用户点击右上角分享 微信小程序、百度小程序、字节跳动小程序、支付宝小程序
onPageScroll 监听页面滚动,参数为Object nvue暂不支持
onNavigationBarButtonTap 监听原生标题栏按钮点击事件,参数为Object App、H5
onBackPress 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解。支付宝小程序只有真机能触发,只能监听非navigateBack引起的返回,不可阻止默认行为。 app、H5、支付宝小程序
onNavigationBarSearchInputChanged 监听原生标题栏搜索输入框输入内容变化事件 App、H5 1.6.0
onNavigationBarSearchInputConfirmed 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 App、H5 1.6.0
onNavigationBarSearchInputClicked 监听原生标题栏搜索输入框点击事件 App、H5 1.6.0
onShareTimeline 监听用户点击右上角转发到朋友圈 微信小程序 2.8.1+
onAddToFavorites 监听用户点击右上角收藏 微信小程序 2.8.1+

页面样式与布局

uni-app的css与web的css基本一致。

uni-app有vue页面和nvue页面。vue页面是webview渲染的、app端的nvue页面是原生渲染的

尺寸单位

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

nvue还不支持百分比单位

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

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

nvue中,uni-app 模式(nvue 不同编译模式介绍)可以使用 px 、rpx,表现与 vue 中一致。weex 模式目前遵循weex的单位,它的单位比较特殊:

下面对 rpx 详细说明:

设计师在只提供一个分辨率的图,严格按设计图标注的 px 做开发,在不同宽度的手机上界面的宽度很容易变形。

rpx 动态宽度单位,就是为了解决这个问题。uni-app 在 App 端、H5 端都支持了 rpx

在Pages.json的globalStyle中可以配置不同屏幕宽度的计算方式,具体参考:

属性 默认值 描述 平台兼容
rpxCalcMaxDeviceWidth 960 rpx 计算所支持的最大设备宽度,单位 px App、H5
rpxCalcBaseDeviceWidth 375 rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px App、H5
rpxCalcIncludeWidth 750 rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx App、H5
maxWidth 1190 单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选) H5

rpx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。uni-app 规定屏幕基准宽度 750rpx,页面元素宽度在 uni-app 中的宽度计算公式:

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

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

Tips

样式导入

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

示例代码:

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

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

全局样式与局部样式

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

注意:

CSS变量

uni-app 提供内置 CSS 变量

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

注意:

代码块

快速书写css变量的方法是:在css中敲hei,在候选助手中即可看到3个css变量。(HBuilderX 1.9.6以上支持)

示例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 中以下组件的高度是固定的,不可修改:

组件 描述 App H5
NavigationBar 导航栏 44px 44px
TabBar 底部选项卡 50px(可以自主更改高度) 50px

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

Flex布局

为支持跨平台,框架建议使用Flex布局,关于Flex布局可以参考外部文档阮一峰的flex教程等。

背景图片

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

注意

字体图标

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

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>

nvue页面的样式注意事项

  1. nvue 页面控制显隐只可以使用v-if不可以使用v-show
  2. nvue 页面只能使用flex布局,不支持其他布局方式。页面开发前,首先想清楚这个页面的纵向内容有什么,哪些是要滚动的,然后每个纵向内容的横轴排布有什么,按 flex 布局设计好界面。
  3. nvue 页面的布局排列方向默认为竖排(column),如需改变布局方向,可以在 manifest.json -> app-plus -> nvue -> flex-direction 节点下修改,仅在 uni-app 模式下生效。详情
  4. nvue页面编译为H5、小程序时,会做一件css默认值对齐的工作。因为weex渲染引擎只支持flex,并且默认flex方向是垂直。而H5和小程序端,使用web渲染,默认不是flex,并且设置display:flex后,它的flex方向默认是水平而不是垂直的。所以nvue编译为H5、小程序时,会自动把页面默认布局设为flex、方向为垂直。当然开发者手动设置后会覆盖默认设置。
  5. 文字内容,必须、只能在<text>组件下。不能在<div><view>text区域里直接写文字。否则即使渲染了,也无法绑定js里的变量。
  6. 只有text标签可以设置字体大小,字体颜色。
  7. 布局不能使用百分比、没有媒体查询。
  8. nvue 切换横竖屏时可能导致样式出现问题,建议有 nvue 的页面锁定手机方向。
  9. 支持的css有限,不过并不影响布局出你需要的界面,flex还是非常强大的。详见
  10. 不支持背景图。但可以使用image组件和层级来实现类似web中的背景效果。因为原生开发本身也没有web这种背景图概念
  11. css选择器支持的比较少,只能使用 class 选择器。详见
  12. nvue 的各组件在安卓端默认是透明的,如果不设置background-color,可能会导致出现重影的问题。
  13. class 进行绑定时只支持数组语法。
  14. Android端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。
  15. nvue页面没有bounce回弹效果,只有几个列表组件有bounce效果,包括 listrecycle-listwaterfall
  16. 原生开发没有页面滚动的概念,页面内容高过屏幕高度并不会自动滚动,只有部分组件可滚动(listwaterfallscroll-view/scroller),要滚得内容需要套在可滚动组件下。这不符合前端开发的习惯,所以在 nvue 编译为 uni-app模式时,给页面外层自动套了一个 scroller,页面内容过高会自动滚动。(组件不会套,页面有recycle-list时也不会套)。后续会提供配置,可以设置不自动套。
  17. 在 App.vue 中定义的全局js变量不会在 nvue 页面生效。globalDatavuex是生效的。
  18. App.vue 中定义的全局css,对nvue和vue页面同时生效。如果全局css中有些css在nvue下不支持,编译时控制台会报警,建议把这些不支持的css包裹在条件编译里,APP-PLUS-NVUE
  19. 不能在 style 中引入字体文件,nvue 中字体图标的使用参考:加载自定义字体。如果是本地字体,可以用plus.io的API转换路径。
  20. 目前不支持在 nvue 页面使用 typescript/ts
  21. nvue 页面关闭原生导航栏时,想要模拟状态栏,可以参考文章。但是,仍然强烈建议在nvue页面使用原生导航栏。nvue的渲染速度再快,也没有原生导航栏快。原生排版引擎解析json绘制原生导航栏耗时很少,而解析nvue的js绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。
上一篇 下一篇

猜你喜欢

热点阅读