網(wǎng)站建設(shè)方案標準模板網(wǎng)站流量查詢網(wǎng)站統(tǒng)計查詢
uniapp頁面樣式和布局和nvue教程
尺寸單位
uni-app
支持的通用 css
單位包括 px
、rpx
px
即屏幕像素。rpx
即響應(yīng)式px
,一種根據(jù)屏幕寬度自適應(yīng)的動態(tài)單位。以750
寬的屏幕為基準,750rpx
恰好為屏幕寬度。屏幕變寬,rpx
實際顯示效果會等比放大。但在App
端和H5
端屏幕寬度達到960px
時,默認將按照375px
的,屏幕寬度進行計算,具體配置參考:rpx計算配置
rpx
詳細說明:
設(shè)計師在提供設(shè)計圖時,一般只提供一個分辨率的圖。嚴格按設(shè)計圖標注的 px
做開發(fā),在不同寬度的手機上界面很容易變形。而且主要是寬度變形。高度一般因為有滾動條,不容易出問題。由此,引發(fā)了較強的動態(tài)寬度單位需求。微信小程序設(shè)計了 rpx
解決這個問題。 uni-app
在 App
端、H5
端都支持了 rpx
,并且可以配置不同屏幕寬度的計算方式,具體參考:rpx計算配置。
rpx
是相對于基準寬度的單位,可以根據(jù)屏幕寬度進行自適應(yīng)。uni-app
規(guī)定屏幕基準寬度 750rpx
。
開發(fā)者可以通過設(shè)計稿基準寬度計算頁面元素 rpx
值,設(shè)計稿 1px
與框架樣式 1rpx
轉(zhuǎn)換公式如: 設(shè)計稿 1px / 設(shè)計稿基準寬度 = 框架樣式 1rpx / 750rpx
。
換言之,頁面元素寬度在 uni-app
中的寬度計算公式:750 * 元素在設(shè)計稿中的寬度 / 設(shè)計稿基準寬度
頁面元素寬度在 uni-app
中的寬度計算舉例說明:
- 若設(shè)計稿寬度為 750px,元素 A 在設(shè)計稿上的寬度為 100px,那么元素 A 在 uni-app 里面的寬度應(yīng)該設(shè) 為: 750 * 100 / 750 ,結(jié)果為:100rpx。
- 若設(shè)計稿寬度為 640px,元素 A 在設(shè)計稿上的寬度為 100px,那么元素 A 在 uni-app 里面的寬度應(yīng)該設(shè) 為: 750 * 100 / 640 ,結(jié)果為:117rpx。
- 若設(shè)計稿寬度為 375px,元素 B 在設(shè)計稿上的寬度為 200px,那么元素 B 在 uni-app 里面的寬度應(yīng)該設(shè) 為: 750 * 200 / 375 ,結(jié)果為:400rpx。
注意 :
rpx
是和寬度相關(guān)的單位,屏幕越寬,該值實際像素越大。如不想根據(jù)屏幕寬度縮放,則應(yīng)該使用 px
單位。如果開發(fā)者在字體或高度中也使用了 rpx
,那么需注意這樣的寫法意味著隨著屏幕變寬,字體會變大、高度會變大。如果你需要固定高度,則應(yīng)該使用px
,rpx
不支持動態(tài)橫豎屏切換計算,使用rpx
建議鎖定屏幕方向。
全局樣式與局部樣式
定義在 App.vue
中的樣式為全局樣式,作用于每一個頁面。在 pages
目錄下 的 vue
文件中定義的樣式為局部樣式,只作用在對應(yīng)的頁面,并會覆蓋 App.vue
中相同的選擇器。
注意:
App.vue
中通過 @import
語句可以導入外聯(lián)樣式文件,一樣作用于每一個頁面。
<style>/*每個頁面公共css */@import url("../../common/css/common.css");
</style>
效果:
APP
和小程序中子組件會使用父組件的樣式,H5
端不會使用父組件的樣式。
CSS變量
uni-app
提供內(nèi)置 CSS
變量
CSS 變量 | 描述 | App | 小程序 | H5 |
---|---|---|---|---|
–status-bar-height | 系統(tǒng)狀態(tài)欄高度 | 系統(tǒng)狀態(tài)欄高度 | 25 | 0 |
–window-top | 內(nèi)容區(qū)域距離頂部的距離 | 0 | 0 | NavigationBar 的高度 |
–window-bottom | 內(nèi)容區(qū)域距離底部的距離 | 0 | 0 | TabBar 的高度 |
注意:
var(--status-bar-height)
此變量在微信小程序環(huán)境為固定25px
,在App
里為手機實際狀態(tài)欄高度。- 當設(shè)置
"navigationStyle":"custom"
取消原生導航欄后,由于窗體為沉浸式,占據(jù)了狀態(tài)欄位置。此時可以使用一個高度為var(--status-bar-height)
的view
放在頁面頂部,避免頁面內(nèi)容出現(xiàn)在狀態(tài)欄。 - 由于在
H5
端,不存在原生導航欄和tabbar
,也是前端div
模擬。如果設(shè)置了一個固定位置的居底view
,在小程序和App
端是在tabbar
上方,但在H5
端會與tabbar
重疊。此時可使用--window-bottom
,不管在哪個端,都是固定在tabbar
上方。 - 目前
nvue
在App
端,還不支持--status-bar-height
變量,替代方案是在頁面onLoad
時通過uni.getSystemInfoSync().statusBarHeight
獲取狀態(tài)欄高度,然后通過style
綁定方式給占位view
設(shè)定高度。
示例:
<template><view><view class="status_bar"><!-- 這里是狀態(tài)欄 --></view><view> 狀態(tài)欄下的文字 </view></view>
</template>
<style>.status_bar {height: var(--status-bar-height);width: 100%;background: red;}
</style>
效果:
<template/>
和 <block/>
uni-app
支持在 template
模板中嵌套 <template/>
和 <block/>
,用來進行 列表渲染
和 條件渲染
。
<template/>
和 <block/>
并不是一個組件,它們僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。
<block/>
在不同的平臺表現(xiàn)存在一定差異,推薦統(tǒng)一使用 <template/>
。
<template><view><view class="box"><template v-if="test"><view>test為true,</view><view>test為true</view></template><template v-else><view>test為false,</view><view>test為false</view></template></view></view>
</template>
<script>export default {data() {return {test: false,}}}
</script><style>.box {display: flex;}
</style>
效果:
Flex
布局
為兼容多端跨平臺運行,建議使用flex布局進行開發(fā)
阮一峰的flex教程:flex教程
{
display: flex;
flex-direction: row;
}
flex-direction
決定主軸的方向(即項目的排列方向)
flex-wrap
默認情況下,項目都排在一條線(又稱"軸線")上。
flex-wrap
屬性定義,如果一條軸線排不下,如何換 行。
flex-flow
是flex-direction
屬性和flex-wrap屬性的簡寫形式,默認值為row nowrap
。
justify-content
定義了項目在主軸上的對齊方式。
align-items
定義項目在交叉軸上如何對齊。
align-content
定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
nvue 教程
????????uni-app App
端內(nèi)置了一個基于 weex
改進的原生渲染引擎,提供了原生渲染能力。在 App
端,如果使用 vue
頁面,則使用 webview
渲染;如果使用 nvue
頁面(native vue
的縮寫),則使用原生渲染。一個 App
中可以同時使用兩種頁面,比如首頁使用 nvue
,二級頁使用 vue
頁面,hello uni-app
示例就是如此。
????????雖然 nvue
也可以多端編譯,輸出 H5
和小程序,但 nvue
的 css
寫法受限,所以如果你不開發(fā) App
,那么不需要使用 nvue
。
????????以往的 weex
,有個很大的問題是它只是一個高性能的渲染器,沒有足夠的 API
能力(比如各種 push sdk
集成、藍牙等能力調(diào)用),使得開發(fā)時非常依賴原生工程師協(xié)作,開發(fā)者本來想節(jié)約成本,結(jié)果需要前端
、iOS
、Android
3 撥人開發(fā),適得其反。 nvue
解決了這個問題,讓前端工程師可以直接開發(fā)完整 App
,并提供豐富的插件生態(tài)和云打包。這些組合方案,幫助開發(fā)者切實的提高效率、降低成本。
????????如果一個頁面路由下同時有vue
頁面和nvue
頁面,即出現(xiàn)同名的vue
和nvue
文件。那么在App
端,會僅使用nvue
頁面,同名的vue
文件將不會被編譯到App
端。而在非App
端,會優(yōu)先使用vue
頁面。
nvue
開發(fā)與vue
開發(fā)的常見區(qū)別
基于原生引擎的渲染,雖然還是前端技術(shù)棧,但和web開發(fā)肯定是有區(qū)別的。
nvue
頁面控制顯隱只可以使用v-if
不可以使用v-show
nvue
頁面只能使用flex
布局,不支持其他布局方式。頁面開發(fā)前,首先想清楚這個頁面的縱向內(nèi)容有什么,哪些是要滾動的,然后每個縱向內(nèi)容的橫軸排布有什么,按flex
布局設(shè)計好界面。nvue
頁面的布局排列方向默認為豎排(column
),如需改變布局方向,可以在manifest.json
->app-plus
->nvue
->flex-direction
節(jié)點下修改,僅在uni-app
模式下生效。nvue
頁面編譯為H5
、小程序
時,會做一件css
默認值對齊的工作。因為weex
渲染引擎只支持flex
,并且默認flex
方向是垂直。而H5
和小程序
端,使用web
渲染,默認不是flex
,并且設(shè)置display:flex
后,它的flex
方向默認是水平而不是垂直的。所以nvue
編譯為H5
、小程序
時,會自動把頁面默認布局設(shè)為flex
、方向為垂直
。當然開發(fā)者手動設(shè)置后會覆蓋默認設(shè)置。- 文字內(nèi)容,必須、只能在
<text>
組件下。不能在<div>
、<view>
的text
區(qū)域里直接寫文字。否則即使渲染了,也無法綁定js
里的變量。 - 只有
text
標簽可以設(shè)置字體大小,字體顏色。 - 布局不能使用百分比、沒有媒體查詢。
nvue
切換橫豎屏時可能導致樣式出現(xiàn)問題,建議有nvue
的頁面鎖定手機方向。- 支持的
css
有限,不過并不影響布局出你需要的界面,flex
還是非常強大的。 - 不支持背景圖。但可以使用
image
組件和層級來實現(xiàn)類似web
中的背景效果。因為原生開發(fā)本身也沒有web
這種背景圖概念 css
選擇器支持的比較少,只能使用class
選擇器。nvue
的各組件在安卓端默認是透明的,如果不設(shè)置background-color
,可能會導致出現(xiàn)重影的問題。class
進行綁定時只支持數(shù)組語法。Android
端在一個頁面內(nèi)使用大量圓角邊框會造成性能問題,尤其是多個角的樣式還不一樣的話更耗費性能。應(yīng)避免這類使用。nvue
頁面沒有bounce
回彈效果,只有幾個列表組件有bounce
效果,包括list
、recycle-list
、waterfall
。- 原生開發(fā)沒有頁面滾動的概念,頁面內(nèi)容高過屏幕高度并不會自動滾動,只有部分組件可滾動(
list
、waterfall
、scroll-view/scroller
),要滾得內(nèi)容需要套在可滾動組件下。這不符合前端開發(fā)的習慣,所以在nvue
編譯為uni-app
模式時,給頁面外層自動套了一個scroller
,頁面內(nèi)容過高會自動滾動。(組件不會套,頁面有recycle-list
時也不會套)。 - 在
App.vue
中定義的全局js
變量不會在nvue
頁面生效。globalData
和vuex
是生效的。 App.vue
中定義的全局css
,對nvue
和vue
頁面同時生效。如果全局css
中有些css
在nvue
下不支持,編譯時控制臺會報警,建議把這些不支持的css
包裹在條件編譯里,APP-PLUS-NVUE
- 不能在
style
中引入字體文件,nvue
中字體圖標的使用參考:加載自定義字體。如果是本地字體,可以用plus.io
的API
轉(zhuǎn)換路徑。 - 目前不支持在
nvue
頁面使用typescript/ts
。 nvue
頁面關(guān)閉原生導航欄時,想要模擬狀態(tài)欄,可以參考文章。但是,仍然強烈建議在nvue
頁面使用原生導航欄。nvue
的渲染速度再快,也沒有原生導航欄快。原生排版引擎解析json
繪制原生導航欄耗時少,而解析nvue
的js
繪制整個頁面的耗時要大的多,尤其在新頁面進入動畫期間,對于復雜頁面,沒有原生導航欄會在動畫期間產(chǎn)生整個屏幕的白屏或閃屏。
樣式
nvue
的css
僅支持flex
布局,是webview
的css
語法的子集。這是因為操作系統(tǒng)原生排版不支持非flex
之外的web
布局。當然flex
足以排布出各種頁面,只是寫法需要適應(yīng)。- 在選擇器方面支持的較少,只支持簡單的
class="classA"
。class
進行綁定時只支持數(shù)組語法。- 不支持媒體查詢。
- 不支持復合樣式,不支持簡寫。
- 不能在
style
中引入字體文件。- 布局不能使用百分比,如
width:100%;
。- 有些
web
的css
屬性在nvue
里無法支持,比如背景圖。但可以使用image
組件和層級來實現(xiàn)類似web
中的背景效果。因為原生開發(fā)本身也沒有web
這種背景圖概念。nvue
的各組件在安卓端默認是透明的,如果不設(shè)置background-color
,可能會導致出現(xiàn)重影的問題。- 文字內(nèi)容,必須只能在
text
組件下,text
組件不能換行寫內(nèi)容,否則會出現(xiàn)無法去除的周邊空白。- 只有
text
標簽可以設(shè)置字體大小,字體顏色。
nvue
和 vue
相互通訊
uni.$emit(eventName,OBJECT)
觸發(fā)全局的自定事件。附加參數(shù)都會傳給監(jiān)聽器回調(diào)。
eventName
類型String
事件名,OBJECT Object
觸發(fā)事件攜帶的附加參數(shù)。
代碼示例
uni.$emit('update',{msg:'頁面更新'})
uni.$on(eventName,callback)
監(jiān)聽全局的自定義事件。事件可以由 uni.$emit 觸發(fā),回調(diào)函數(shù)會接收所有傳入事件觸發(fā)函數(shù)的額外參數(shù)。
示例:vue
對nvue
的傳值通訊
index.vue
頁面代碼
<template><view><button @click="sendMessage">點擊修改數(shù)據(jù)</button></view>
</template><script>export default {data() {return {message: 'Hello from nVue'};},methods: {sendMessage() {uni.navigateTo({url: '../test/test',success: () => {// 確保目標頁面已經(jīng)加載uni.$emit('ceshi', {title: '測試標題',content: '測試內(nèi)容'});}});}}};
</script>
test.nvue
頁面代碼
<template><view><text>Test Page</text></view>
</template><script>
export default {onLoad() {// 注冊事件監(jiān)聽器uni.$on('ceshi', (data) => {console.log('標題:' + data.title);console.log('內(nèi)容:' + data.content);});},onUnload() {// 頁面卸載時移除事件監(jiān)聽器uni.$off('ceshi');},methods: {}
};
</script><style scoped>
/* 可以在這里添加樣式 */
</style>
效果:
uni.$once(eventName,callback)
監(jiān)聽全局的自定義事件。事件可以由uni.$emit
觸發(fā),但是只觸發(fā)一次,在第一次觸發(fā)之后移除監(jiān)聽器。
屬性 | 類型 | 描述 |
---|---|---|
eventName | String | 事件名 |
callback | Function | 事件回調(diào)函數(shù) |
示例代碼: |
onLoad() {uni.$once('update',function(data){console.log('監(jiān)聽到事件來自 update ,攜帶參數(shù) msg 為:' + data.msg);})
}
示例:
<template><view><text>Test Page</text></view>
</template><script>export default {onLoad() {uni.$once('ceshi', function(data) {console.log('監(jiān)聽到事件來自 update ,攜帶參數(shù) msg 為:' + data);})},onUnload() {// 頁面卸載時移除事件監(jiān)聽器uni.$off('ceshi');},methods: {}};
</script><style scoped>/* 可以在這里添加樣式 */
</style>
效果:
uni.$off([eventName, callback])
移除全局自定義事件監(jiān)聽器。
屬性 | 類型 | 描述 |
---|---|---|
eventName | Array[String] | 事件名 |
callback | Function | 事件回調(diào)函數(shù) |
示例代碼 |
onUnload() {
// 移除 update 監(jiān)聽器
uni.$off('update')
}
上面中已經(jīng)用到了uni.$off
的使用,在每次onUnload
頁面卸載的時候移除事件監(jiān)聽。
Tips
- 如果沒有提供參數(shù),則移除所有的事件監(jiān)聽器;
- 如果只提供了事件,則移除該事件所有的監(jiān)聽器;
- 如果同時提供了事件與回調(diào),則只移除這個回調(diào)的監(jiān)聽器;
- 提供的回調(diào)必須跟
$on
的回調(diào)為同一個才能移除這個回調(diào)的監(jiān)聽器;
階段完結(jié)~