uni-app 使用vue的语法+小程序的标签和API。
?
開發規范
為了實現多端兼容,綜合考慮編譯速度、運行性能等因素,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 配置頁面路由、導航條、選項卡等頁面類信息,詳見Tips
- static?目錄下的?js?文件不會被編譯,如果里面有?es6?的代碼,不經過轉換直接運行,在手機設備上會報錯。
- css、less/scss?等資源同樣不要放在?static?目錄下,建議這些公用的資源放在?common?目錄下。
- HbuilderX 1.9.0+ 支持在根目錄創建?ext.json?sitemap.json?文件。
| app-plus | App |
| h5 | H5 |
| mp-weixin | 微信小程序 |
| mp-alipay | 支付寶小程序 |
| mp-baidu | 百度小程序 |
資源路徑說明
模板內引入靜態資源
template內引入靜態資源,如image、video等標簽的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,其余不轉。
- 自HBuilderX 2.6.6-alpha起template內支持@開頭路徑引入靜態資源,舊版本不支持此方式
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');注意
- 自HBuilderX 2.6.6-alpha起支持絕對路徑引入靜態資源,舊版本不支持此方式
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
生命周期
應用生命周期
uni-app?支持如下應用生命周期函數:
| onLaunch | 當uni-app?初始化完成時觸發(全局只觸發一次) |
| onShow | 當?uni-app?啟動,或從后臺進入前臺顯示 |
| onHide | 當?uni-app?從前臺進入后臺 |
| onError | 當?uni-app?報錯時觸發 |
| onUniNViewMessage | 對?nvue?頁面發送的數據進行監聽,可參考?nvue 向 vue 通訊 |
注意
- 應用生命周期僅可在App.vue中監聽,在其它頁面監聽無效。
- onlaunch里進行頁面跳轉,如遇白屏報錯,請參考https://ask.dcloud.net.cn/article/35942
頁面生命周期
uni-app?支持如下頁面生命周期函數:
| onLoad | 監聽頁面加載,其參數為上個頁面傳遞的數據,參數類型為Object(用于頁面傳參),參考示例 | ? | ? |
| onShow | 監聽頁面顯示。頁面每次出現在屏幕上都觸發,包括從下級頁面點返回露出當前頁面 | ? | ? |
| onReady | 監聽頁面初次渲染完成。注意如果渲染速度快,會在頁面進入動畫完成前觸發 | ? | ? |
| onHide | 監聽頁面隱藏 | ? | ? |
| onUnload | 監聽頁面卸載 | ? | ? |
| onResize | 監聽窗口尺寸變化 | App、微信小程序 | ? |
| onPullDownRefresh | 監聽用戶下拉動作,一般用于下拉刷新,參考示例 | ? | ? |
| onReachBottom | 頁面上拉觸底事件的處理函數 | ? | ? |
| onTabItemTap | 點擊 tab 時觸發,參數為Object,具體見下方注意事項 | 微信小程序、百度小程序、H5、App(自定義組件模式) | ? |
| onShareAppMessage | 用戶點擊右上角分享 | 微信小程序、百度小程序、字節跳動小程序、支付寶小程序 | ? |
| onPageScroll | 監聽頁面滾動,參數為Object | ? | ? |
| onNavigationBarButtonTap | 監聽原生標題欄按鈕點擊事件,參數為Object | 5+ App、H5 | ? |
| onBackPress | 監聽頁面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示來源是左上角返回按鈕或 android 返回鍵;navigateBack表示來源是 uni.navigateBack ;詳細說明及使用:onBackPress 詳解 | App、H5 | ? |
| onNavigationBarSearchInputChanged | 監聽原生標題欄搜索輸入框輸入內容變化事件 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputConfirmed | 監聽原生標題欄搜索輸入框搜索事件,用戶點擊軟鍵盤上的“搜索”按鈕時觸發。 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputClicked | 監聽原生標題欄搜索輸入框點擊事件 | App、H5 | 1.6.0 |
onPageScroll?參數說明:
| scrollTop | Number | 頁面在垂直方向已滾動的距離(單位px) |
onTabItemTap?參數說明:
| index | String | 被點擊tabItem的序號,從0開始 |
| pagePath | String | 被點擊tabItem的頁面路徑 |
| text | String | 被點擊tabItem的按鈕文字 |
注意
- onTabItemTap常用于點擊當前tabitem,滾動或刷新當前頁面。如果是點擊不同的tabitem,一定會觸發頁面切換。
- 如果想在App端實現點擊某個tabitem不跳轉頁面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一個區塊蓋住原先的tabitem,并攔截點擊事件。
- onTabItemTap在App端,從HBuilderX 1.9 的自定義組件編譯模式開始支持。
onNavigationBarButtonTap?參數說明:
| index | Number | 原生標題欄按鈕數組的下標 |
onBackPress?回調參數對象說明:
| from | String | 觸發返回行為的來源:'backbutton'——左上角導航欄按鈕及安卓返回鍵;'navigateBack'——uni.navigateBack() 方法。 |
注意
- nvue 頁面支持的生命周期參考:nvue 生命周期介紹。
路由
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模式下,是通行的編譯環境處理方式。
如果你需要自定義更多環境,比如測試環境:
- 假設只需要對單一平臺配置,可以 package.json 中配置,在HBuilderX的運行和發行菜單里會多一個出來。https://uniapp.dcloud.io/collocation/package
- 如果是針對所有平臺配置,可以在 vue-config.js 中配置。https://uniapp.dcloud.io/collocation/vue-config
快捷代碼塊
HBuilderX 中敲入代碼塊?uEnvDev、uEnvProd?可以快速生成對應?development、production?的運行環境判定代碼。
// uEnvDev if (process.env.NODE_ENV === 'development') {// TODO } // uEnvProd if (process.env.NODE_ENV === 'production') {// TODO }判斷平臺
平臺判斷有2種場景,一種是在編譯期判斷,一種是在運行期判斷。
- 編譯期判斷 編譯期判斷,即條件編譯,不同平臺在編譯出包后已經是不同的代碼。詳見:條件編譯
如上代碼只會編譯到H5的發行包里,其他平臺的包不會包含如上代碼。
- 運行期判斷 運行期判斷是指代碼已經打入包中,仍然需要在運行期判斷平臺,此時可使用?uni.getSystemInfoSync().platform?判斷客戶端環境是 Android、iOS 還是小程序開發工具(在百度小程序開發工具、微信小程序開發工具、支付寶小程序開發工具中使用?uni.getSystemInfoSync().platform?返回值均為 devtools)。
如有必要,也可以在條件編譯里自己定義一個變量,賦不同值。在后續運行代碼中動態判斷環境。
頁面樣式與布局
尺寸單位
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。注意此時不支持 rpx
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 * 元素在設計稿中的寬度 / 設計稿基準寬度
舉例說明:
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" />
選擇器
目前支持的選擇器有:
| .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?節點,例如: <!-- 設置頁面背景顏色 --> page {background-color:#ccc; }
全局樣式與局部樣式
定義在 App.vue 中的樣式為全局樣式,作用于每一個頁面。在 pages 目錄下 的 vue 文件中定義的樣式為局部樣式,只作用在對應的頁面,并會覆蓋 App.vue 中相同的選擇器。
注意:
- App.vue 中通過?@import?語句可以導入外聯樣式,一樣作用于每一個頁面。
- nvue頁面暫不支持全局樣式
CSS變量
uni-app 提供內置 CSS 變量
| --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變量。(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?中以下組件的高度是固定的,不可修改:
| NavigationBar | 導航欄 | 44px | 44px |
| TabBar | 底部選項卡 | HBuilderX 2.3.4之前為56px,2.3.4起和H5調為一致,統一為 50px。但可以自主更改高度) | 50px |
各小程序平臺,包括同小程序平臺的iOS和Android的高度也不一樣。
Flex布局
為支持跨平臺,框架建議使用Flex布局,關于Flex布局可以參考外部文檔A Complete Guide to Flexbox、阮一峰的flex教程等。
背景圖片
uni-app?支持使用在 css 里設置背景圖片,使用方式與普通?web?項目大體相同,但需要注意以下幾點:
- 支持 base64 格式圖片。
- 支持網絡路徑圖片。
- 小程序不支持在css中使用本地文件,包括本地的背景圖和字體文件。需以base64方式方可使用。App端在v3模式以前,也有相同限制。v3編譯模式起支持直接使用本地背景圖和字體。
- 使用本地路徑背景圖片需注意:
- 為方便開發者,在背景圖片小于 40kb 時,uni-app?編譯到不支持本地背景圖的平臺時,會自動將其轉化為 base64 格式;
- 圖片大于等于 40kb,會有性能問題,不建議使用太大的背景圖,如開發者必須使用,則需自己將其轉換為 base64 格式使用,或將其挪到服務器上,從網絡地址引用。
- 本地背景圖片的引用路徑推薦使用以 ~@ 開頭的絕對路徑。 .test2 {background-image: url('~@/static/logo.png');}
注意
- 微信小程序不支持相對路徑(真機不支持,開發工具支持)
字體圖標
uni-app?支持使用字體圖標,使用方式與普通?web?項目相同,需要注意以下幾點:
- 支持 base64 格式字體圖標。
- 支持網絡路徑字體圖標。
- 小程序不支持在css中使用本地文件,包括本地的背景圖和字體文件。需以base64方式方可使用。App端在v3模式以前,也有相同限制。v3編譯模式起支持直接使用本地背景圖和字體。
- 網絡路徑必須加協議頭?https。
- 從?http://www.iconfont.cn?上拷貝的代碼,默認是沒加協議頭的。
- 從?http://www.iconfont.cn?上下載的字體文件,都是同名字體(字體名都叫iconfont,安裝字體文件時可以看到),在nvue內使用時需要注意,此字體名重復可能會顯示不正常,可以使用工具修改。
- 使用本地路徑圖標字體需注意:
- 為方便開發者,在字體文件小于 40kb 時,uni-app?會自動將其轉化為 base64 格式;
- 字體文件大于等于 40kb,仍轉換為 base64 方式使用的話可能有性能問題,如開發者必須使用,則需自己將其轉換為 base64 格式使用,或將其挪到服務器上,從網絡地址引用;
- 字體文件的引用路徑推薦使用以 ~@ 開頭的絕對路徑。 @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"></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>ES6 支持
uni-app 在支持絕大部分 ES6 API 的同時,也支持了 ES7 的 await/async。
ES6 API 的支持,詳見如下表格部分(x?表示不支持,無特殊說明則表示支持):
- 因為iOS上不允許三方js引擎,所以iOS上不區分App、小程序、H5,各端均僅依賴iOS版本。
- 各端Android版本有差異:
- App端的數據見下表;
- H5端數據見caniuse;
- 微信小程序詳見
- 阿里小程序詳見
- 百度小程序詳見
- 字節跳動小程序詳見
- QQ小程序詳見
| codePointAt | ? | ? | ? | ? |
| normalize | x | x | ? | 僅支持 NFD/NFC |
| includes | ? | ? | ? | ? |
| startsWith | ? | ? | ? | ? |
| endsWith | ? | ? | ? | ? |
| repeat | ? | ? | ? | ? |
| String.fromCodePoint | ? | ? | ? | ? |
| copyWithin | ? | ? | ? | ? |
| find | ? | ? | ? | ? |
| findIndex | ? | ? | ? | ? |
| fill | ? | ? | ? | ? |
| entries | ? | ? | ? | ? |
| keys | ? | ? | ? | ? |
| values | x | ? | ? | x |
| includes | x | ? | ? | ? |
| Array.from | ? | ? | ? | ? |
| Array.of | ? | ? | ? | ? |
| isFinite | ? | ? | ? | ? |
| isNaN | ? | ? | ? | ? |
| parseInt | ? | ? | ? | ? |
| parseFloat | ? | ? | ? | ? |
| isInteger | ? | ? | ? | ? |
| EPSILON | ? | ? | ? | ? |
| isSafeInteger | ? | ? | ? | ? |
| trunc | ? | ? | ? | ? |
| sign | ? | ? | ? | ? |
| cbrt | ? | ? | ? | ? |
| clz32 | ? | ? | ? | ? |
| imul | ? | ? | ? | ? |
| fround | ? | ? | ? | ? |
| hypot | ? | ? | ? | ? |
| expm1 | ? | ? | ? | ? |
| log1p | ? | ? | ? | ? |
| log10 | ? | ? | ? | ? |
| log2 | ? | ? | ? | ? |
| sinh | ? | ? | ? | ? |
| cosh | ? | ? | ? | ? |
| tanh | ? | ? | ? | ? |
| asinh | ? | ? | ? | ? |
| acosh | ? | ? | ? | ? |
| atanh | ? | ? | ? | ? |
| is | ? | ? | ? | ? |
| assign | ? | ? | ? | ? |
| getOwnPropertyDescriptor | ? | ? | ? | ? |
| keys | ? | ? | ? | ? |
| getOwnPropertyNames | ? | ? | ? | ? |
| getOwnPropertySymbols | ? | ? | ? | ? |
| Symbol | ? | ? | ? | ? |
| Set | ? | ? | ? | ? |
| Map | ? | ? | ? | ? |
| Proxy | x | x | ? | x |
| Reflect | ? | ? | ? | ? |
| Promise | ? | ? | ? | ? |
注意
- App端Android支持不依賴Android版本號,即便是Android4.4也是上表數據。因為uni-app的js代碼運行在自帶的獨立jscore中,沒有js的瀏覽器兼容性問題。uni-app的vue頁面在Android低端機上只有css瀏覽器兼容性問題,因為vue頁面仍然渲染在webview中,受Android版本影響,太新的css語法在低版本不支持。
- 默認不需要在微信工具里繼續開啟es6轉換。但如果用了微信的wxml自定義組件(wxcomponents目錄下),uni-app編譯器并不會處理這些文件中的es6代碼,需要去微信工具里開啟轉換。從HBuilderX調起微信工具時,如果發現工程下有wxcomponents目錄會自動配置微信工程打開es6轉換。
NPM支持
uni-app支持使用npm安裝第三方包。
此文檔要求開發者們對npm有一定的了解,因此不會再去介紹npm的基本功能。如若之前未接觸過npm,請翻閱NPM官方文檔進行學習。
初始化npm工程
若項目之前未使用npm管理依賴(項目根目錄下無package.json文件),先在項目根目錄執行命令初始化npm工程:
npm init -ycli項目默認已經有package.json了。HBuilderX創建的項目默認沒有,需要通過初始化命令來創建。
安裝依賴
在項目根目錄執行命令安裝npm包:
npm install packageName --save使用
安裝完即可使用npm包,js中引入npm包:
import package from 'packageName' const package = require('packageName')注意
- 為多端兼容考慮,建議優先從?uni-app插件市場?獲取插件。直接從 npm 下載庫很容易只兼容H5端。
- 非 H5 端不支持使用含有 dom、window 等操作的 vue 組件和 js 模塊,安裝的模塊及其依賴的模塊使用的 API 必須是 uni-app 已有的?API(兼容小程序 API),比如:支持高德地圖微信小程序 SDK。類似jQuery?等庫只能用于H5端。
- node_modules 目錄必須在項目根目錄下。不管是cli項目還是HBuilderX創建的項目。
- 支持安裝 mpvue 組件,但npm方式不支持小程序自定義組件(如 wxml格式的vant-weapp),使用小程序自定義組件請參考:小程序組件支持。
- 關于ui庫的獲取,詳見多端UI庫
TypeScript 支持
在 uni-app 中使用 ts 開發,請參考?Vue.js TypeScript 支持?說明。
注意事項
在 uni-app 中使用 ts 需要注意以下事項。
在 vue 文件的 script 節點聲明 lang="ts"
聲明?lang="ts"?后,該 vue 文件 import 進來的所有 vue 組件,均需要使用 ts 編寫。
示例代碼
改造 uni-badge.vue
<script lang="ts">// 僅展示需要修改的核心代碼,完整代碼請參考原來的組件。import Vue from 'vue';export default Vue.extend({props: {type: {type: String,default: 'default'},inverted: {type: Boolean,default: false},text: {type: [String, Number],default: ''},size: {type: String,default: 'normal'}},computed: {setClass(): string {const classList: string[] = ['uni-badge-' + this.type, 'uni-badge-size-' + this.size];if (this.inverted === true) {classList.push('uni-badge-inverted')}return classList.join(" ")}},methods: {onClick() {this.$emit('click')}}}) </script>在 index.vue 中引用 uni-badge 組件
<script lang="ts">import Vue from 'vue';import uniBadge from '../../components/uni-badge.vue';export default Vue.extend({data() {return {title: 'Hello'}},components:{uniBadge}}); </script>小程序組件支持
uni-app?支持在 App 和 小程序 中使用小程序自定義組件,從HBuilderX2.4.7起,H5端也可以運行微信小程序組件。
平臺差異說明
| H5 | 支持微信小程序組件(2.4.7+) | wxcomponents |
| App(不含nvue) | 支持微信小程序組件 | wxcomponents |
| 微信小程序 | 支持微信小程序組件 | wxcomponents |
| 支付寶小程序 | 支持支付寶小程序組件 | mycomponents |
| 百度小程序 | 支持百度小程序組件 | swancomponents |
| 字節跳動小程序 | 支持字節跳動小程序組件 | ttcomponents |
| QQ小程序 | 支持QQ小程序組件 | wxcomponents |
此文檔要求開發者對各端小程序的自定義組件有一定了解,沒接觸過小程序自定義組件的可以參考:
- 微信小程序自定義組件
- 百度小程序自定義組件
- 支付寶小程序自定義組件
- 字節跳動小程序自定義組件
- QQ小程序自定義組件
目錄結構
┌─wxcomponents 微信小程序自定義組件存放目錄 │ └──custom 微信小程序自定義組件 │ ├─index.js │ ├─index.wxml │ ├─index.json │ └─index.wxss ├─mycomponents 支付寶小程序自定義組件存放目錄 │ └──custom 支付寶小程序自定義組件 │ ├─index.js │ ├─index.axml │ ├─index.json │ └─index.wxss ├─swancomponents 百度小程序自定義組件存放目錄 │ └──custom 百度小程序自定義組件 │ ├─index.js │ ├─index.swan │ ├─index.json │ └─index.wxss ├─pages │ └─index │ └─index.vue │ ├─static ├─main.js ├─App.vue ├─manifest.json └─pages.json使用方式
在?pages.json?對應頁面的 style -> usingComponents 引入組件:
{"pages": [{"path": "index/index","style": {"usingComponents": {// #ifdef APP-PLUS || MP-WEIXIN || MP-QQ"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>代碼示例
下面以微信小程序官方自定義組件示例?miniprogram-slide-view?為例演示小程序自定義組件的使用方式。 其他組件使用示例見GitHub:wxcomponents-template。 插件市場有一個完整的vant weapp?引用好的示例工程,詳見https://ext.dcloud.net.cn/plugin?id=302。
目錄結構
?
┌─components ├─wxcomponents │ └──miniprogram-slide-view │ ├─index.js │ ├─index.wxml │ ├─index.json │ └─index.wxss │ ├─pages │ └─slide-view │ └─slide-view.vue │ ├─static ├─main.js ├─App.vue ├─manifest.json └─pages.jsonpages.json
?
{"pages": [{"path": "slide-view/slide-view","style": {"navigationBarTitleText": "slide-view","usingComponents": {"slide-view": "/wxcomponents/miniprogram-slide-view/index"}}}] }slide-view.vue
<template><view class='slide'><slide-view width="750" height="110" slide-width="500"><view slot="left" class="l"><image src="/static/file_transfer.jpg" class="img"></image><view class='text'><view class='title'>文件傳輸助手</view><view class='time'>7:00 PM</view></view></view><view slot="right" class="r"><view class='read'>標為已讀</view><view class='delete'>刪除</view></view></slide-view></view> </template> <script>export default {} </script> <style>.slide {border-bottom: 1px solid #DEDEDE;}.l {background-color: white;height: 110rpx;width: 750rpx;display: flex;flex-direction: row;}.r {height: 110rpx;display: flex;direction: row;text-align: center;vertical-align: middle;line-height: 110rpx;}.read {background-color: #ccc;color: #fff;width: 350rpx;}.delete {background-color: red;color: #fff;width: 150rpx;}.img {width: 90rpx;height: 90rpx;border-radius: 10rpx;margin: 10rpx 15rpx;}.text {display: flex;flex-direction: row;}.title {margin-top: 15rpx;font-size: 33rpx;}.time {margin-top: 15rpx;color: #ccc;font-size: 25rpx;margin-left: 330rpx;} </style>注意事項
- 小程序組件需要放在項目特殊文件夾?wxcomponents(或 mycomponents、swancomponents)。HBuilderX 建立的工程?wxcomponents?文件夾在 項目根目錄下。vue-cli 建立的工程?wxcomponents?文件夾在?src?目錄下??梢栽?vue.config.js 中自定義其他目錄
- 小程序組件的性能,不如vue組件。使用小程序組件,需要自己手動setData,很難自動管理差量數據更新。而使用vue組件會自動diff更新差量數據。所以如無明顯必要,建議使用vue組件而不是小程序組件。比如某些小程序ui組件,完全可以用更高性能的uni ui替代。
- 當需要在?vue?組件中使用小程序組件時,注意在?pages.json?的?globalStyle?中配置?usingComponents,而不是頁面級配置。
- 注意數據和事件綁定的差異,使用時應按照?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。
WXS
WXS是一套運行在視圖層的腳本語言,微信端的規范詳見。
它的特點是運行在視圖層。當需要避免邏輯層和渲染層交互通信折損時,可采用wxs。
uni-app可以將wxs代碼編譯到微信小程序、QQ小程序、app-vue、H5上(uni-app 2.2.5及以上版本)
與wxs類似,百度小程序提供了Filter、阿里小程序提供了SJS,uni-app也支持使用這些功能,并將它們編譯到百度和阿里的小程序端。不過它們的功能還不如wxs強大。此外頭條系小程序自身不支持類似功能。
平臺差異說明
| √(不支持nvue) | √ | √ | SJS | Filter | x | √ |
App端nvue解決此類需求,不應該使用wxs,而是使用bindingx。
wxs示例
以下是一些使用 WXS 的簡單示例,要完整了解 WXS 語法,請參考WXS 語法參考。本示例使用wxs響應touchmove事件,減少視圖層與邏輯層通信,使滑動更加絲滑。
<template><view><view class="area"><view @touchstart="test.touchstart" @touchmove="test.touchmove" class="movable">{{test.msg}}</view></view></view> </template> <script module="test" lang="wxs">var startX = 0var startY = 0var lastLeft = 50; var lastTop = 50function touchstart(event, ins) {console.log("touchstart")var touch = event.touches[0] || event.changedTouches[0]startX = touch.pageXstartY = touch.pageY}function touchmove(event, ins) {var touch = event.touches[0] || event.changedTouches[0]var pageX = touch.pageXvar pageY = touch.pageYvar left = pageX - startX + lastLeftvar top = pageY - startY + lastTopstartX = pageXstartY = pageYlastLeft = leftlastTop = topins.selectComponent('.movable').setStyle({left: left + 'px',top: top + 'px'})return false}module.exports = {msg: 'Hello',touchstart: touchstart,touchmove: touchmove} </script><script>export default {data() {return {}},methods: {}} </script><style> .area{position: absolute;width: 100%;height: 100%; } .movable{position: absolute;width: 100px;height: 100px;left: 50px;top: 50px;color: white;text-align: center;line-height: 100px;background-color: red; } </style>支付寶小程序,百度小程序官方暫未支持事件響應,不過也可以使用對應的SJS、Filter過濾器實現一些數據處理的操作,以下代碼展示了一個時間格式化的小功能
index.vue
<template><view><view>{{timestr}} 是</view><view>{{utils.friendlyDate(timestamp)}}</view></view> </template> <script module="utils" lang="filter" src="./utils.filter.js"></script> <script module="utils" lang="sjs" src="./utils.sjs"></script><script>export default {data() {return {timestr: '2019/08/22 10:10:10',timestamp: 0}},created() {this.timestamp = new Date(this.timestr).getTime()},methods: {}} </script>utils.sjs?與?utils.filter.js?內容一致
export default {friendlyDate: (timestamp) => {var formats = {'year': '%n% 年前','month': '%n% 月前','day': '%n% 天前','hour': '%n% 小時前','minute': '%n% 分鐘前','second': '%n% 秒前',};var now = Date.now();var seconds = Math.floor((now - parseInt(timestamp)) / 1000);var minutes = Math.floor(seconds / 60);var hours = Math.floor(minutes / 60);var days = Math.floor(hours / 24);var months = Math.floor(days / 30);var years = Math.floor(months / 12);var diffType = '';var diffValue = 0;if (years > 0) {diffType = 'year';diffValue = years;} else {if (months > 0) {diffType = 'month';diffValue = months;} else {if (days > 0) {diffType = 'day';diffValue = days;} else {if (hours > 0) {diffType = 'hour';diffValue = hours;} else {if (minutes > 0) {diffType = 'minute';diffValue = minutes;} else {diffType = 'second';diffValue = seconds === 0 ? (seconds = 1) : seconds;}}}}}return formats[diffType].replace('%n%', diffValue);} }注意
引入方式
<!-- 內聯 --> <script module="test" lang="wxs">//...code </script> <script module="utils" lang="filter">//...code </script><!-- 外部引入 --> <script module="utils" lang="wxs" src="./utils.wxs"></script> <script module="utils" lang="filter" src="./utils.filter.js"></script> <script module="utils" lang="sjs" src="./utils.sjs"></script>- 【重要】?編寫wxs、sjs、filter.js 內容時必須遵循相應語法規范
- 【重要】?module所指定的模塊名不可與data、methods、computed內的屬性重名
- 目前各個小程序正在完善相關規范,可能會有較大改動,請務必仔細閱讀相應平臺的文檔
- 支付寶小程序請使用sjs規范,詳見
- 支付寶小程序sjs只能定義在.sjs 文件中,然后使用<script>標簽引入
- 支付寶小程序script的標簽屬性name、from被統一為了module、src以便后續實現多平臺統一寫法
- 百度小程序中請使用Filter規范,詳見
- 百度小程序Filter只能導出function函數
- 暫不支持在 wxs、sjs、filter.js 中調用其他同類型文件
- wxs、filter.js既能內聯使用又可以外部引入,sjs只能外部引入
- QQ小程序目前對內聯的 wxs 支持不好,部分寫法可能會導致編譯出錯,盡量使用外部引入的方式
- 在微信自定義組件中wxcomponents也可以使用wxs
- nvue頁面暫不支持wxs、sjs、filter.js
- 各個script標簽會分別被打包至對應支持平臺,不需要額外寫條件編譯
- 自HBuilderX 2.2.5開始,不推薦使用各個小程序自有的引入方式,推薦使用script標簽引入
- App和H5端,提供了wxs的升級版,更加強大,見下面的?renderjs?章節
renderjs
renderjs是一個運行在視圖層的js。它比WXS更加強大。它只支持app-vue和h5。
renderjs的主要作用有2個:
- 大幅降低邏輯層和視圖層的通訊損耗,提供高性能視圖交互能力
- 在視圖層操作dom,運行for web的js庫
平臺差異說明
| √(2.5.5+,僅支持vue,并要求v3編譯器) | √ | x | x | x | x | x |
renderjs,以 vue 組件的寫法運行在 view 層。
使用方式
設置 script 節點的 lang 為 renderjs
<script module="test" lang="renderjs">export default {mounted() {// ...},methods: {// ...}} </script>示例
- 通過renderjs,在app和h5端使用完整的?echarts
功能詳解
- 大幅降低邏輯層和視圖層的通訊損耗,提供高性能視圖交互能力
邏輯層和視圖層分離有很多好處,但也有一個副作用是在造成了兩層之間通信阻塞。尤其是小程序和App的Android端阻塞問題影響了高性能應用的制作。
renderjs運行在視圖層,可以直接操作視圖層的元素,避免通信折損。
在hello uni-app的canvas示例中,App端使用了renderjs,由運行在視圖層的renderjs直接操作視圖層的canvas,實現了遠超微信小程序的流暢canvas動畫示例。具體在hello uni-app示例中體驗,對比App端和小程序端的性能差異。
- 在視圖層操作dom,運行for web的js庫 官方不建議在uni-app里操作dom,但如果你不開發小程序,想使用一些操作了dom、window的庫,其實可以使用renderjs來解決。
在app-vue環境下,視圖層由webview渲染,而renderjs運行在視圖層,自然可以操作dom和window。
這是一個基于renderjs運行echart完整版的示例:renderjs版echart
同理,f2、threejs等庫都可以這么用。
注意事項
- 可以使用 dom、bom API 不可直接訪問邏輯層數據
- 視圖層和邏輯層通訊方式與?WXS?一致
- 觀測更新的數據在 view 層可以直接訪問到
- 不要直接引用大型類庫,推薦通過動態創建 script 方式引用
- view 層的頁面引用資源的路徑相對于根目錄計算,例如:./static/test.js
- 目前僅支持內聯使用
總結
以上是生活随笔為你收集整理的uni-app 使用vue的语法+小程序的标签和API。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue中的变量绑定
- 下一篇: uni-app开发所有前端应用的框架