目錄
框架介紹
開發規範
爲了實現多端兼容,綜合考慮編譯速度、運行性能等因素,uni-app
約定了如下開發規範:
- 頁面文件遵循 Vue 單文件組件 (SFC) 規範
- 組件標籤靠近小程序規範,詳見uni-app 組件規範
- 接口能力(JS API)靠近微信小程序規範,但需將前綴
wx
替換爲uni
,詳見uni-app接口規範 - 數據綁定及事件處理同
Vue.js
規範,同時補充了App及頁面的生命週期 - 爲兼容多端運行,建議使用flex佈局進行開發
目錄結構
一個uni-app工程,默認包含如下目錄及文件:
┌─components 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 配置頁面路由、導航條、選項卡等頁面類信息,詳見
提示:
static
目錄下的js
文件不會被編譯,如果裏面有es6
的代碼,不經過轉換直接運行,在手機設備上會報錯。css
、less/scss
等資源同樣不要放在static
目錄下,建議這些公用的資源放在common
目錄下。- HbuilderX 1.9.0+ 支持在根目錄創建
ext.json
、sitemap.json
文件。
生命週期
應用生命週期
注意因爲表格顯示有問題,這裏我就直接截的圖,表格中的鏈接請看官方文檔:uni-app官方文檔
uni-app
支持如下應用生命週期函數:
注意
- 應用生命週期僅可在App.vue中監聽,在其他頁面監聽無效
- onlaunch裏進行頁面跳轉,如遇白屏報錯,請參考https://ask.dcloud.net.cn/article/35942
頁面生命週期
uni-app 支持如下頁面生命週期函數
onPageScroll 參數說明:
onTabItemTap
參數說明:
注意
- onTabItemTap常用於點擊當前tabitem,滾動或刷新當前頁面。如果是點擊不同的tabitem,一定會觸發頁面切換。
- 如果想在App端實現點擊某個tabitem不跳轉頁面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一個區塊蓋住原先的tabitem,並攔截點擊事件。
- onTabItemTap在App端,從HBuilderX 1.9 的自定義組件編譯模式開始支持。
onNavigationBarButtonTap
參數說明:
onBackPress
回調參數對象的說明
路由
uni-app
路由全部交給框架統一管理,開發者需要在pages.json裏配置每個路由頁面的路徑及頁面樣式,不支持 Vue Router
。
路由跳轉
uni-app
有兩種路由跳轉方式:使用navigator組件跳轉、調用API跳轉。
頁面棧
框架以棧的形式管理當前所有頁面, 當發生路由切換的時候,頁面棧的表現如下:
文檔:頁面棧
運行環境判斷
開發環境和生產環境
uni-app
可通過 process.env.NODE_ENV
判斷當前環境是開發環境還是生產環境。一般用於連接測試服務器或生產服務器的動態切換。
- 在HBuilderX 中,點擊“運行”編譯出來的代碼是開發環境,點擊“發行”編譯出來的代碼是生產環境
- cli模式下,是通行的編譯環境處理方式
if(process.env.NODE_ENV === 'development'){
console.log('開發環境')
}else{
console.log('生產環境')
}
快捷代碼塊
HBuilderX 中敲入代碼塊 uEnvDev
、uEnvProd
可以快速生成對應 development
、production
的運行環境判定代碼。
// uEnvDev
if (process.env.NODE_ENV === 'development') {
// TODO
}
// uEnvProd
if (process.env.NODE_ENV === 'production') {
// TODO
}
判斷平臺
平臺判斷有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實際顯示效果會等比放大
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。注意此時不支持px
nvue中,uni-app 模式(nvue 不同編譯模式介紹)可以使用 px 、rpx,表現與 vue 中一致。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 * 元素在設計稿中的寬度 / 設計稿基準寬度
舉例來說:
- 若設計稿寬度爲 750px,元素 A 在設計稿上的寬度爲 100px,那麼元素 A 在 uni-app 裏面的寬度應該設爲:750 * 100 / 750,結果爲:100rpx。
- 若設計稿寬度爲 640px,元素 A 在設計稿上的寬度爲 100px,那麼元素 A 在 uni-app 裏面的寬度應該設爲:750 * 100 / 640,結果爲:117rpx。
- 若設計稿寬度爲 375px,元素 B 在設計稿上的寬度爲 200px,那麼元素 B 在 uni-app 裏面的寬度應該設爲:750 * 200 / 375,結果爲:400rpx。
Tips
- 注意 rpx 是和寬度相關的單位,屏幕越寬,該值實際像素越大。如不想根據屏幕寬度縮放,則應該使用 px 單位。
- 如果開發者在字體或高度中也使用了 rpx ,那麼需注意這樣的寫法意味着隨着屏幕變寬,字體會變大、高度會變大。如果你需要固定高度,則應該使用 px 。
- rpx不支持動態橫豎屏切換計算,使用rpx建議鎖定屏幕方向
- 設計師可以用 iPhone6 作爲視覺稿的標準。
- 如果設計稿不是750px,HBuilderX提供了自動換算的工具,詳見:https://ask.dcloud.net.cn/article/35445。
- App端,在 pages.json 裏的 titleNView 或頁面裏寫的 plus api 中涉及的單位,只支持 px,不支持 rpx。
- 早期 uni-app 提供了 upx ,目前已經推薦統一改爲 rpx 了,詳見
樣式導入
使用@import
語句可以導入外聯樣式表,@import
後跟需要導入的外聯樣式表的相對路徑,用;
表示語句結束。
示例代碼:
<style>
@import "../../common/uni.css";
.uni-card {
box-shadow: none;
}
</style>
內聯樣式
框架組件上支持使用style、class屬性來控制組件的樣式
- style:靜態的樣式統一寫到class中。style接收動態的樣式,在運行時會進行解析,請儘量避免將靜態的樣式寫進style中,以免影響渲染速度。
<view :style="{color:color}" />
- class:用於指定樣式規則,其屬性值是樣式規則中類選擇器名(樣式類名)的集合,樣式類名不需要帶上,樣式類名之間用空格分隔
<view class="normal_view" />
選擇器
目前支持的選擇器有:
注意:
- 在uni-app中不能使用 * 選擇器。
- page 相當於 body 節點,例如:
<!-- 設置頁面背景顏色 -->
page {
background-color:#ccc;
}
全局樣式與局部樣式
定義在App.vue中的樣式爲全局樣式,作用與每個頁面。在pages目錄下的vue文件中定義的樣式爲局部樣式,只作用在對應的頁面,並會覆蓋App.vue中相同的選擇器。
注意:App.vue中通過@import語句可以導入外聯樣式,一樣作用於每一個頁面
CSS變量
uni-app提供內置CSS變量
注意:
- var(--status-bar-height)此變量在微信小程序環境爲固定 25px ,在5+App裏爲手機實際狀態欄高度
- 當設置 "navigationStyle":"custom" 取消原生導航欄後,由於窗體爲沉浸式,佔據了狀態欄位置,此時可以使用一個高度爲 var(--status-bar-height) 的view放在頁面頂部,避免頁面內容出現在狀態欄
- 由於在H5端,不存在原生導航欄和tabbar,也是前端div模擬。如果設置了一個固定位置的居底view,在小程序和App端是在tabbar上方,但在H5端會與tabbar重疊。此時可使用--window-bottom,不管在哪個端,都是固定在tabbar上方。
- 目前nvue還不支持css變量
代碼塊
快速書寫css變量的方法是:在css中敲hei,在候選助手中即可看到3個css變量。(HBuilderX 1.9.6以上支持)
示例:
<template>
<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>
固定值
uni-app 中以下組件的高度是固定的,不可修改:
Flex佈局
爲支持跨平臺,框架建議使用Flex佈局,關於Flex佈局可以參考外部文檔A Complete Guide to Flexbox、阮一峯的flex教程等。
背景圖片
uni-app
支持使用在 css 裏設置背景圖片,使用方式與普通 web
項目相同,需要注意以下幾點:
- 支持 base64 格式圖片。
- 支持網絡路徑圖片。
- 使用本地路徑背景圖片需注意:
- 圖片小於 40kb,
uni-app
會自動將其轉化爲 base64 格式; - 圖片大於等於 40kb, 需開發者自己將其轉換爲base64格式使用,或將其挪到服務器上,從網絡地址引用。
- 本地背景圖片的引用路徑僅支持以 ~@ 開頭的絕對路徑(不支持相對路徑)。
.test2 {
background-image: url('~@/static/logo.png');
}
字體圖標
uni-app
支持使用字體圖標,使用方式與普通 web
項目相同,需要注意以下幾點:
- 支持 base64 格式字體圖標。
- 支持網絡路徑字體圖標。
- 網絡路徑必須加協議頭
https
。 - 從 http://www.iconfont.cn 上拷貝的代碼,默認是沒加協議頭的。
uni-app
本地路徑圖標字體支持情況:
- 字體文件小於 40kb,
uni-app
會自動將其轉化爲 base64 格式; - 字體文件大於等於 40kb, 需開發者自己轉換,否則使用將不生效;
- 字體文件的引用路徑僅支持以 ~@ 開頭的絕對路徑(不支持相對路徑)。
@font-face {
font-family: test1-icon;
src: url('~@/static/iconfont.ttf');
}
示例:
<template>
<view>
<view>
<text class="test"></text>
<text class="test"></text>
<text class="test"></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>
<template/>和</block>
uni-app
支持在 template 模板中嵌套 <template/>
和 <block/>
,用來進行 列表渲染 和 條件渲染。
<template/>
和 <block/>
並不是一個組件,它們僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。
代碼示例
<template>
<view>
<template v-if="test">
<view>test 爲 true 時顯示</view>
</template>
<template v-else>
<view>test 爲 false 時顯示</view>
</template>
</view>
</template>
<template>
<view>
<block v-for="(item,index) in list" :key="index">
<view>{{item}} - {{index}}</view>
</block>
</view>
</template>
小程序組件支持
uni-app
支持在 5+App 和小程序中使用小程序組件。
平臺差異說明
此文檔要求開發者對各端小程序的自定義組件有一定了解,沒接觸過小程序自定義組件的可以參考:
目錄結構
使用方式
在 pages.json
對應頁面的 style -> usingComponents 引入組件:
{
"pages": [
{
"path": "index/index",
"style": {
"usingComponents": {
// #ifdef APP-PLUS || MP-WEIXIN
"custom": "/wxcomponents/custom/index"
// #endif
// #ifdef MP-BAIDU
"custom": "/swancomponents/custom/index"
// #endif
// #ifdef MP-ALIPAY
"custom": "/mycomponents/custom/index"
// #endif
}
}
}
]
}
在頁面中使用
<!-- 頁面模板 (index.vue) -->
<view>
<!-- 在頁面中對自定義組件進行引用 -->
<custom name="uni-app"></custom>
</view>
注意事項
- 小程序組件需要放在項目特殊文件夾
wxcomponents
(或 mycomponents、swancomponents)。 - HBuilderX 建立的工程
wxcomponents
文件夾在 項目根目錄下。 - vue-cli 建立的工程
wxcomponents
文件夾在src
目錄下。 - 注意數據和事件綁定的差異,使用時應按照 vue 的數據和事件綁定方式
- 屬性綁定從 attr="{{ a }}",改爲 :attr="a";從 title="複選框{{ item }}" 改爲 :title="'複選框' + item"
- 事件綁定從 bind:click="toggleActionSheet1" 改爲 @click="toggleActionSheet1"
- 阻止事件冒泡 從 catch:tap="xx" 改爲 @tap.native.stop="xx"
- wx:if 改爲 v-if
- wx:for="{{ list }}" wx:key="{{ index }}" 改爲`v-for="(item,index) in list"
- 原事件命名以短橫線分隔的需要手動修改小程序組件源碼爲駝峯命名,比如:this.$emit('left-click') 修改爲 this.$emit('leftClick')(HBuilderX 1.9.0+ 不再需要修改此項)
詳細的小程序轉uni-app語法差異可參考文檔https://ask.dcloud.net.cn/article/35786。