uni-app 頁面樣式

小陳的筆記發表於2022-06-14

尺寸單位

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 * 元素在設計稿中的寬度 / 設計稿基準寬度

舉例說明:

  1. 若設計稿寬度為 750px,元素 A 在設計稿上的寬度為 100px,那麼元素 A 在 uni-app 裡面的寬度應該設為:750 * 100 / 750,結果為:100rpx。
  2. 若設計稿寬度為 640px,元素 A 在設計稿上的寬度為 100px,那麼元素 A 在 uni-app 裡面的寬度應該設為:750 * 100 / 640,結果為:117rpx。
  3. 若設計稿寬度為 375px,元素 B 在設計稿上的寬度為 200px,那麼元素 B 在 uni-app 裡面的寬度應該設為:750 * 200 / 375,結果為:400rpx。

Tips

  • 注意 rpx 是和寬度相關的單位,螢幕越寬,該值實際畫素越大。如不想根據螢幕寬度縮放,則應該使用 px 單位。
  • 如果開發者在字型或高度中也使用了 rpx ,那麼需注意這樣的寫法意味著隨著螢幕變寬,字型會變大、高度會變大。如果你需要固定高度,則應該使用 px 。
  • rpx不支援動態橫豎屏切換計算,使用rpx建議鎖定螢幕方向
  • 設計師可以用 iPhone6 作為視覺稿的標準。
  • 如果設計稿不是750px,HBuilderX提供了自動換算的工具 。
  • 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 變數

CSS變數 描述 App 小程式 H5
--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, 詳情:
     <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 底部選項卡 HBuilderX 2.3.4之前為56px,2.3.4起和H5調為一致,統一為 50px。但可以自主更改高度) 50px

各小程式平臺,包括同小程式平臺的iOS和Android的高度也不一樣。

Flex佈局

為支援跨平臺,框架建議使用Flex佈局,關於Flex佈局可以參考外部文件 、 阮一峰的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。
  • 從  阿里雲圖示庫 上複製的程式碼,預設是沒加協議頭的。
  • 從  阿里雲圖示庫 上下載的字型檔案,都是同名字型(字型名都叫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(')"
  })

示例:

<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(') 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>


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70018483/viewspace-2900385/,如需轉載,請註明出處,否則將追究法律責任。

相關文章