uniapp官網
uni-app 是一個使用 Vue.js (opens new window)開發所有前端應用的框架,開發者編寫一套代碼,可發布到iOS、Android、Web(響應式)、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應用等多個平台。
HBuilderX:官方IDE下載地址
新建uni-app

運行uni-app

uniapp 初始化相關配置
工程目錄結構
一個uni-app工程,默認包含如下目錄及文件:
┌─uniCloud 雲空間目錄,阿里雲為uniCloud-aliyun,騰訊雲為uniCloud-tcb(詳見uniCloud)
│─components 符合vue組件規范的uni-app組件目錄
│ └─comp-a.vue 可復用的a組件
├─hybrid App端存放本地html文件的目錄,詳見
├─platforms 存放各平台專用頁面的目錄,詳見
├─pages 業務頁面文件存放的目錄
│ ├─index
│ │ └─index.vue index頁面
│ └─list
│ └─list.vue list頁面
├─static 存放應用引用的本地靜態資源(如圖片、視頻等)的目錄,注意:靜態資源只能存放於此
├─uni_modules 存放[uni_module](/uni_modules)規范的插件。
├─wxcomponents 存放小程序組件的目錄,詳見
├─main.js Vue初始化入口文件
├─App.vue 應用配置,用來配置App全局樣式以及監聽 應用生命周期
├─manifest.json 配置應用名稱、appid、logo、版本等打包信息,詳見
├─pages.json 配置頁面路由、導航條、選項卡等頁面類信息,詳見
└─uni.scss 這里是uni-app內置的常用樣式變量
Tips
- 編譯到任意平台時,static 目錄下的文件均會被完整打包進去,且不會編譯。非 static 目錄下的文件(vue、js、css 等)只有被引用到才會被打包編譯進去。
- static 目錄下的 js 文件不會被編譯,如果里面有 es6 的代碼,不經過轉換直接運行,在手機設備上會報錯。
- css、less/scss 等資源不要放在 static 目錄下,建議這些公用的資源放在自建的 common 目錄下。
- HbuilderX 1.9.0+ 支持在根目錄創建 ext.json、sitemap.json 等小程序需要的文件。
manifest.json 應用配置
是應用的配置文件,用於指定應用的名稱、圖標、權限等。也可以在這里為Vue,為H5設置跨域攔截處理器
vue.config.js 編譯配置地址
vue.config.js 是一個可選的配置文件,如果項目的 (和 package.json 同級的) 根目錄中存在這個文件,那么它會被 @vue/cli-service 自動加載。你也可以使用 package.json 中的 vue 字段,但是注意這種寫法需要你嚴格遵照 JSON 的格式來寫。
這個文件應該導出一個包含了選項的對象:
// vue.config.js
/**
* @type {import('@vue/cli-service').ProjectOptions}
*/
module.exports = {
// 選項...
}
或者,你也可以使用 @vue/cli-service 提供的 defineConfig 幫手函數,以獲得更好的類型提示:
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
// 選項
})
package.json 全局配置
用來對uni-app進行全局配置,決定頁面文件的路徑、窗口樣式、原生的導航欄、底部的原生tabbar等。它類似微信小程序中app.json的頁面管理部分
{
/**
* package.json其它原有配置
* 拷貝代碼后請去掉注釋!
*/
"uni-app": {// 擴展配置
"scripts": {
"custom-platform": { //自定義編譯平台配置,可通過cli方式調用
"title":"自定義擴展名稱", // 在HBuilderX中會顯示在 運行/發行 菜單中
"browser":"", //運行到的目標瀏覽器,僅當UNI_PLATFORM為h5時有效
"env": {//環境變量
"UNI_PLATFORM": "", //基准平台
"MY_TEST": "", // ... 其他自定義環境變量
},
"define": { //自定義條件編譯
"CUSTOM-CONST": true //自定義條件編譯常量,建議為大寫
}
}
}
}
}
App.vue
是uni-app的主組件,所有頁面都是在App.vue下進行切換的,是頁面入口文件。但App.vue本身不是頁面,這里不能編寫視圖元素。
這個文件的作用包括:調用應用生命周期函數、配置全局樣式、配置全局的存儲globalData
應用生命周期僅可在App.vue中監聽,在頁面監聽無效
應用生命周期
uni-app 支持如下應用生命周期函數:
| 函數名 | 說明 |
|---|---|
| onLaunch | 當uni-app 初始化完成時觸發(全局只觸發一次) |
| onShow | 當 uni-app 啟動,或從后台進入前台顯示 |
| onHide | 當 uni-app 從前台進入后台 |
| onError | 當 uni-app 報錯時觸發 |
| onUniNViewMessage | 對 nvue 頁面發送的數據進行監聽,可參考 nvue 向 vue 通訊(opens new window) |
| onUnhandledRejection | 對未處理的 Promise 拒絕事件監聽函數(2.8.1+) |
| onPageNotFound | 頁面不存在監聽函數 |
| onThemeChange | 監聽系統主題變化 |
<script>
// 只能在App.vue里監聽應用的生命周期
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
onPageNotFound() {
uni.navigateTo({
url:'/pages/404/404'
})
}
}
</script>
uni.scss 官方地址
文件的用途是為了方便整體控制應用的風格。比如按鈕顏色、邊框風格,uni.scss文件里預置了一批scss變量預置。
main.js 入口文件官方地址
main.js是 uni-app 的入口文件,主要作用是初始化vue實例、定義全局組件、使用需要的插件如 vuex。
***************************vue2
import Vue from 'vue'
import App from './App'
import pageHead from './components/page-head.vue' //全局引用 page-head 組件
Vue.config.productionTip = false
Vue.component('page-head', pageHead) //全局注冊 page-head 組件,每個頁面將可以直接使用該組件
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount() //掛載 Vue 實例
**************************vue3
import App from './App'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
uniapp 開發規范及資源路徑
為了實現多端兼容,綜合考慮編譯速度、運行性能等因素,uni-app 約定了如下開發規范:
- 頁面文件遵循 Vue 單文件組件 (SFC) 規范
- 組件標簽靠近小程序規范,詳見uni-app 組件規范
- 接口能力(JS API)靠近微信小程序規范,但需將前綴 wx 替換為 uni,詳見uni-app接口規范
- 數據綁定及事件處理同 Vue.js 規范,同時補充了App及頁面的生命周期
- 為兼容多端運行,建議使用flex布局進行開發
資源路徑說明
- 在 uni-app 項目中,頁面引用組件和組件引用組件的方式都是一樣的(可以理解為:頁面是一種特殊的組件),均支持通過 easycom 方式直接引用。
easycom 規范詳細介紹,參考:easycom

- js 文件引入
js文件或script標簽內(包括 renderjs 等)引入js文件時,可以使用相對路徑和絕對路徑,形式如下
// 絕對路徑,@指向項目根目錄,在cli項目中@指向src目錄
import add from '@/common/add.js';
// 相對路徑
import add from '../../common/add.js';
// Tips
// js 文件不支持使用/開頭的方式引入
- NPM支持
uni-app支持使用npm安裝第三方包。
- css 文件引入
使用@import語句可以導入外聯樣式表,@import后跟需要導入的外聯樣式表的相對路徑,用;表示語句結束。
<style>
@import "../../common/uni.css";
.uni-card {
box-shadow: none;
}
</style>
- 模板內引入靜態資源
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>
Tips:
- @開頭的絕對路徑以及相對路徑會經過 base64 轉換規則校驗
- 引入的靜態資源在非 h5 平台,均不轉為 base64。
- H5 平台,小於 4kb 的資源會被轉換成 base64,其余不轉。
- 自HBuilderX 2.6.6起template內支持@開頭路徑引入靜態資源,舊版本不支持此方式
- App 平台自HBuilderX 2.6.9起template節點中引用靜態資源文件時(如:圖片),調整查找策略為【基於當前文件的路徑搜索】,與其他平台保持一致
- 支付寶小程序組件內 image 標簽不可使用相對路徑
uniapp 生命周期
應用生命周期
uni-app 支持如下頁面生命周期函數:
| 函數名 | 說明 | 平台差異說明 | 最低版本 |
|---|---|---|---|
| onInit | 監聽頁面初始化,其參數同 onLoad 參數,為上個頁面傳遞的數據,參數類型為 Object(用於頁面傳參),觸發時機早於 onLoad | 百度小程序 | 3.1.0+ |
| onLoad | 監聽頁面加載,其參數為上個頁面傳遞的數據,參數類型為 Object(用於頁面傳參),參考示例 | ||
| onShow | 監聽頁面顯示。頁面每次出現在屏幕上都觸發,包括從下級頁面點返回露出當前頁面 | ||
| onReady | 監聽頁面初次渲染完成。注意如果渲染速度快,會在頁面進入動畫完成前觸發 | ||
| onHide | 監聽頁面隱藏 | ||
| onUnload | 監聽頁面卸載 | ||
| onResize | 監聽窗口尺寸變化 | App、微信小程序、快手小程序 | |
| onPullDownRefresh | 監聽用戶下拉動作,一般用於下拉刷新,參考示例 | ||
| onReachBottom | 頁面滾動到底部的事件(不是scroll-view滾到底),常用於下拉下一頁數據。具體見下方注意事項 | ||
| onTabItemTap | 點擊 tab 時觸發,參數為Object,具體見下方注意事項 | 微信小程序、QQ小程序、支付寶小程序、百度小程序、H5、App、快手小程序、京東小程序 | |
| onShareAppMessage | 用戶點擊右上角分享 | 微信小程序、QQ小程序、支付寶小程序、字節小程序、飛書小程序、快手小程序、京東小程序 | |
| onPageScroll | 監聽頁面滾動,參數為Object | nvue暫不支持 | |
| onNavigationBarButtonTap | 監聽原生標題欄按鈕點擊事件,參數為Object | App、H5 | |
| onBackPress | 監聽頁面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示來源是左上角返回按鈕或 android 返回鍵;navigateBack表示來源是 uni.navigateBack ;詳細說明及使用:onBackPress 詳解 (opens new window)。支付寶小程序只有真機能觸發,只能監聽非navigateBack引起的返回,不可阻止默認行為。 | app、H5、支付寶小程序 | |
| onNavigationBarSearchInputChanged | 監聽原生標題欄搜索輸入框輸入內容變化事件 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputConfirmed | 監聽原生標題欄搜索輸入框搜索事件,用戶點擊軟鍵盤上的“搜索”按鈕時觸發。 | App、H5 | 1.6.0 |
| onNavigationBarSearchInputClicked | 監聽原生標題欄搜索輸入框點擊事件(pages.json 中的 searchInput 配置 disabled 為 true 時才會觸發) | App、H5 | 1.6.0 |
| onShareTimeline | 監聽用戶點擊右上角轉發到朋友圈 | 微信小程序 | 2.8.1+ |
| onAddToFavorites | 監聽用戶點擊右上角收藏 | 微信小程序 | 2.8.1+ |
組件生命周期
uni-app 組件支持的生命周期,與vue標准組件的生命周期相同。這里沒有頁面級的onLoad等生命周期:
// APP.vue 中 添加頁面找不到
onPageNotFound() {
uni.navigateTo({
url:'/pages/404/404'
})
}
// 404 頁面中
onLoad() {
let timer = setTimeout(()=>{
clearTimeout(timer);
uni.navigateTo({
url:'/pages/index/index'
})
},2000);
}
通過HBuilderX開發 uni-app 項目時,在 uni-app 項目上右鍵“新建頁面”,HBuilderX會自動在pages.json中完成頁面注冊,開發更方便。
同時,HBuilderX 還內置了常用的頁面模板(如圖文列表、商品列表等),選擇這些模板,可以大幅提升你的開發效率。
uniapp 路由配置及頁面跳轉
路由配置
uni-app頁面路由為框架統一管理,開發者需要在pages.json里配置每個路由頁面的路徑及頁面樣式。類似小程序在 app.json 中配置頁面路由一樣。所以 uni-app 的路由用法與 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市場搜索 Vue-Router
配置項列表
| 屬性 | 類型 | 必填 | 描述 | 平台兼容 |
|---|---|---|---|---|
| globalStyle | Object | 否 | 設置默認頁面的窗口表現 | |
| pages | Object Array | 是 | 設置頁面路徑及窗口表現 | |
| easycom | Object | 否 | 組件自動引入規則 | 2.5.5+ |
| tabBar | Object | 否 | 設置底部 tab 的表現 | |
| condition | Object | 否 | 啟動模式配置 | |
| subPackages | Object Array | 否 | 分包加載配置 | |
| preloadRule | Object | 否 | 分包預下載規則 | 微信小程序 |
| workers(opens new window) | String | 否 | Worker 代碼放置的目錄 | 微信小程序 |
| leftWindow | Object | 否 | 大屏左側窗口 | H5 |
| topWindow | Object | 否 | 大屏頂部窗口 | H5 |
| rightWindow | Object | 否 | 大屏右側窗口 | H5 |
///包含了所有配置選項的 pages.json :
{
"pages": [{
"path": "pages/component/index",
"style": {
"navigationBarTitleText": "組件"
}
}, {
"path": "pages/API/index",
"style": {
"navigationBarTitleText": "接口"
}
}, {
"path": "pages/component/view/index",
"style": {
"navigationBarTitleText": "view"
}
}],
"condition": { //模式配置,僅開發期間生效
"current": 0, //當前激活的模式(list 的索引項)
"list": [{
"name": "test", //模式名稱
"path": "pages/component/view/index" //啟動頁面,必選
}]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"usingComponents":{
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 僅微信小程序,webrtc 無法正常時嘗試強制關閉同層渲染
"pageOrientation": "portrait", //橫屏配置,全局屏幕旋轉設置(僅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"iconfontSrc":"static/iconfont.ttf", // app tabbar 字體.ttf文件路徑 app 3.4.4+
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "組件",
"iconfont": { // 優先級高於 iconPath,該屬性依賴 tabbar 根節點的 iconfontSrc
"text": "\ue102",
"selectedText": "\ue103",
"fontSize": "17px",
"color": "#000000",
"selectedColor": "#0000ff"
}
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}],
"midButton": {
"width": "80px",
"height": "50px",
"text": "文字",
"iconPath": "static/image/midButton_iconPath.png",
"iconWidth": "24px",
"backgroundImage": "static/image/midButton_backgroundImage.png"
}
},
"easycom": {
"autoscan": true, //是否自動掃描組件
"custom": {//自定義掃描規則
"^uni-(.*)": "@/components/uni-$1.vue"
}
},
"topWindow": {
"path": "responsive/top-window.vue",
"style": {
"height": "44px"
}
},
"leftWindow": {
"path": "responsive/left-window.vue",
"style": {
"width": "300px"
}
},
"rightWindow": {
"path": "responsive/right-window.vue",
"style": {
"width": "300px"
},
"matchMedia": {
"minWidth": 768
}
}
}
路由跳轉
uni-app 有兩種頁面路由跳轉方式:使用navigator組件跳轉、調用API跳轉
頁面棧
框架以棧的形式管理當前所有頁面, 當發生路由切換的時候,頁面棧的表現如下:
| 路由方式 | 頁面棧表現 | 觸發時機 |
|---|---|---|
| 初始化 | 新頁面入棧 | uni-app 打開的第一個頁面 |
| 打開新頁面 | 新頁面入棧 | 調用 API uni.navigateTo 、使用組件
|
| 頁面重定向 | 當前頁面出棧,新頁面入棧 | 調用 API uni.redirectTo 、使用組件
|
| 頁面返回 | 頁面不斷出棧,直到目標返回頁 | 調用 API uni.navigateBack 、使用組件
|
| Tab 切換 | 頁面全部出棧,只留下新的 Tab 頁面 | 調用 API uni.switchTab 、使用組件
|
| 重加載 | 頁面全部出棧,只留下新的頁面 | 調用 API uni.reLaunch 、使用組件
|
getCurrentPages()
getCurrentPages() 函數用於獲取當前頁面棧的實例,以數組形式按棧的順序給出,第一個元素為首頁,最后一個元素為當前頁面。
注意: getCurrentPages()僅用於展示頁面棧的情況,請勿修改頁面棧,以免造成頁面狀態錯誤。
Tips:
- navigateTo, redirectTo 只能打開非 tabBar 頁面。
- switchTab 只能打開 tabBar 頁面。
- reLaunch 可以打開任意頁面。
- 頁面底部的 tabBar 由頁面決定,即只要是定義為 tabBar 的頁面,底部都有 tabBar。
- 不能在 App.vue 里面進行頁面跳轉。
subPackages
分包加載配置,此配置為小程序的分包加載機制。
因小程序有體積和資源加載限制,各家小程序平台提供了分包方式,優化小程序的下載和啟動速度。
所謂的主包,即放置默認啟動頁面/TabBar 頁面,以及一些所有分包都需用到公共資源/JS 腳本;而分包則是根據pages.json的配置進行划分。
在小程序啟動時,默認會下載主包並啟動主包內頁面,當用戶進入分包內某個頁面時,會把對應分包自動下載下來,下載完成后再進行展示。此時終端界面會有等待提示。
App默認為整包。從uni-app 2.7.12+ 開始,也兼容了小程序的分包配置。其目的不用於下載提速,而用於首頁是vue時的啟動提速。App下開啟分包,除在pages.json中配置分包規則外,還需要在manifest中設置在app端開啟分包設置,詳見:https://uniapp.dcloud.io/collocation/manifest?id=app-vue-optimization
subPackages 節點接收一個數組,數組每一項都是應用的子包,其屬性值如下:
| 屬性 | 類型 | 是否必填 | 描述 |
|---|---|---|---|
| root | String | 是 | 子包的根目錄 |
| pages | Array | 是 | 子包由哪些頁面組成,參數同 pages |
{
"pages": [{
"path": "pages/index/index",
"style": { ...}
}, {
"path": "pages/login/login",
"style": { ...}
}],
"subPackages": [{
"root": "pagesA",
"pages": [{
"path": "list/list",
"style": { ...}
}]
}, {
"root": "pagesB",
"pages": [{
"path": "detail/detail",
"style": { ...}
}]
}],
"preloadRule": {
"pagesA/list/list": {
"network": "all",
"packages": ["__APP__"]
},
"pagesB/detail/detail": {
"network": "all",
"packages": ["pagesA"]
}
}
}
組件(官方文檔)
-
組件是視圖層的基本組成單元。
-
組件是一個單獨且可復用的功能模塊的封裝。
-
每個組件,包括如下幾個部分:以組件名稱為標記的開始標簽和結束標簽、組件內容、組件屬性、組件屬性值。
-
組件名稱由尖括號包裹,稱為標簽,它有開始標簽和結束標簽。結束標簽的<后面用/來表示結束。結束標簽也稱為閉合標簽。如下面示例的
是開始標簽, 是結束標簽。 -
在開始標簽和結束標簽之間,稱為組件內容。如下面示例的content
-
開始標簽上可以寫屬性,屬性可以有多個,多個屬性之間用空格分割。如下面示例的property1和property2。注意閉合標簽上不能寫屬性。
-
每個屬性通過=賦值。如下面的示例中,屬性property1的值被設為字符串value。
注意:所有組件與屬性名都是小寫,單詞之間以連字符-連接。
<template>
<view>
<button size="mini">按鈕</button>
</view>
</template>



