Layout 布局 - Vant 4
Layout 布局
📐 介紹
Layout 布局元件就像一位經驗豐富的建築師,為你的頁面搭建起堅實而靈活的骨架 🏗️!透過 van-row 和 van-col 這對黃金搭檔,你可以輕鬆構建出各種複雜的頁面布局。Row 就像是房屋的橫樑,負責水平方向的整體規劃;而 Col 則像是精心設計的房間,可以自由調整大小和位置。24列柵格系統讓你擁有精確到毫釐的布局控制力,無論是簡單的兩欄布局還是複雜的多欄結構,都能信手拈來 ✨。
📦 引入
透過以下方式來全域註冊元件,更多註冊方式請參考元件註冊。
js
import { createApp } from'vue'; import { Col, Row } from'vant'; const app = createApp(); app.use(Col); app.use(Row);🎯 程式碼演示
基礎用法
24列柵格系統就像一把精密的尺子,為你的布局提供了無限可能 📏!透過在 Col 上設定 span 屬性,你可以精確控制每一列的寬度佔比,就像在畫布上自由分配空間一樣。而 offset 屬性則像是一個貼心的間隔器,讓你可以輕鬆創造出留白和錯位效果,讓布局更有層次感和呼吸感!
html
設定列元素間距
空間的藝術在於恰到好處的留白 🎨!gutter 屬性就像是布局中的呼吸空間,透過設定合適的間距,讓各個列元素之間保持優雅的距離。就像音樂中的休止符一樣,這些間距讓整個布局更加和諧悅目,避免了元素之間的擁擠感!
html
垂直間距
有時候,水平間距還不夠,你還需要垂直方向的呼吸空間 🌬️!透過陣列形式的 gutter 設定,你可以同時控制水平和垂直兩個維度的間距。這就像是為你的布局增加了立體感,讓頁面不再是平面的排列,而是有了空間的層次!
html
對齊方式
對齊是布局美學的精髓所在 ✨!justify 屬性就像是一位專業的排版師,幫你精確控制內容在主軸上的分佈方式。無論是左對齊的嚴謹、居中對齊的平衡,還是兩端對齊的飽滿,都能讓你的布局呈現出不同的視覺效果和情感表達!
html
API
Row Props
| 參數 | 說明 | 類型 | 預設值 |
|---|---|---|---|
| gutter | 列元素之間的間距(單位為 px) | *number | string |
| tag | 自訂元素標籤 | string | div |
| justify | 主軸對齊方式,可選值為 end``center``space-around``space-between | string | start |
| align | 交叉軸對齊方式,可選值為 center``bottom | string | top |
| wrap | 是否自動換行 | boolean | true |
Col Props
| 參數 | 說明 | 類型 | 預設值 |
|---|---|---|---|
| span | 列元素寬度 | *number | string* |
| offset | 列元素偏移距離 | *number | string* |
| tag | 自訂元素標籤 | string | div |
Row Events
| 事件名 | 說明 | 回呼參數 |
|---|---|---|
| click | 點擊時觸發 | event: MouseEvent |
Col Events
| 事件名 | 說明 | 回呼參數 |
|---|---|---|
| click | 點擊時觸發 | event: MouseEvent |
類型定義
元件匯出以下類型定義:
ts
importtype { ColProps, RowProps, RowAlign, RowJustify } from'vant';最佳實踐
柵格系統設計原則
設計響應式布局時,應該遵循以下原則 📐:
html
<!-- ✅ 推薦:合理的柵格分配 -->
<van-row :gutter="20">
<van-col :span="8">主要內容</van-col>
<van-col :span="16">次要內容</van-col>
</van-row>
<!-- ❌ 避免:不合理的柵格分配 -->
<van-row>
<van-col :span="23">內容過寬</van-col>
<van-col :span="1">內容過窄</van-col>
</van-row>響應式布局策略
html
<!-- 行動端優先的響應式設計 -->
<van-row :gutter="[16, 16]">
<van-col
:span="24"
:class="{ 'desktop-half': isDesktop }"
>
<div class="content-block">內容區域</div>
</van-col>
</van-row>
<style>
@media (min-width: 768px) {
.desktop-half {
flex: 0 0 50% !important;
max-width: 50% !important;
}
}
</style>巢狀布局最佳實踐
html
<!-- 複雜布局的巢狀使用 -->
<van-row :gutter="20">
<van-col :span="16">
<van-row :gutter="10">
<van-col :span="12">子內容1</van-col>
<van-col :span="12">子內容2</van-col>
</van-row>
</van-col>
<van-col :span="8">側邊欄</van-col>
</van-row>效能最佳化小貼士
減少不必要的重新渲染
最佳化布局元件的效能表現 🚀:
javascript
// ✅ 推薦:使用計算屬性最佳化響應式布局
const layoutConfig = computed(() => {
if (screenWidth.value < 768) {
return { span: 24, gutter: 16 };
} else if (screenWidth.value < 1200) {
return { span: 12, gutter: 20 };
} else {
return { span: 8, gutter: 24 };
}
});
// 在模板中使用
<van-row :gutter="layoutConfig.gutter">
<van-col :span="layoutConfig.span">
內容
</van-col>
</van-row>避免過深的巢狀
html
<!-- ✅ 推薦:扁平化的布局結構 -->
<van-row :gutter="20">
<van-col :span="8">內容1</van-col>
<van-col :span="8">內容2</van-col>
<van-col :span="8">內容3</van-col>
</van-row>
<!-- ❌ 避免:過深的巢狀層級 -->
<van-row>
<van-col :span="24">
<van-row>
<van-col :span="24">
<van-row>
<van-col :span="24">內容</van-col>
</van-row>
</van-col>
</van-row>
</van-col>
</van-row>設計建議
視覺層次
- 主次分明:使用不同的列寬突出重要內容 📊
- 間距統一:保持一致的間距規範 📏
- 對齊規整:確保元素對齊整齊美觀 📐
- 留白合理:適當的留白讓布局更透氣 🌬️
響應式設計
- 行動優先:從小螢幕開始設計,逐步適配大螢幕 📱
- 斷點合理:選擇合適的響應式斷點 💻
- 內容適配:確保內容在不同螢幕下都能良好展示 🖥️
常見問題解決
Q: 如何實現不等高列的底部對齊?
html
<van-row align="bottom" :gutter="20">
<van-col :span="8">
<div class="content-box">
<p>短內容</p>
</div>
</van-col>
<van-col :span="8">
<div class="content-box">
<p>這是一段比較長的內容</p>
<p>包含多行文字</p>
</div>
</van-col>
<van-col :span="8">
<div class="content-box">
<p>中等長度的內容</p>
</div>
</van-col>
</van-row>
<style>
.content-box {
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
</style>Q: 如何實現響應式的柵格布局?
javascript
// 使用組合式 API 實現響應式布局
import { ref, computed, onMounted, onUnmounted } from 'vue';
export default {
setup() {
const screenWidth = ref(window.innerWidth);
const updateScreenWidth = () => {
screenWidth.value = window.innerWidth;
};
const colSpan = computed(() => {
if (screenWidth.value < 576) return 24; // 手機
if (screenWidth.value < 768) return 12; // 平板豎屏
if (screenWidth.value < 992) return 8; // 平板橫屏
if (screenWidth.value < 1200) return 6; // 小桌面
return 4; // 大桌面
});
onMounted(() => {
window.addEventListener('resize', updateScreenWidth);
});
onUnmounted(() => {
window.removeEventListener('resize', updateScreenWidth);
});
return { colSpan };
}
};Q: 如何實現動態的柵格間距?
html
<template>
<div>
<van-slider
v-model="gutterValue"
:min="0"
:max="40"
@change="handleGutterChange"
/>
<van-row :gutter="dynamicGutter">
<van-col :span="8">內容1</van-col>
<van-col :span="8">內容2</van-col>
<van-col :span="8">內容3</van-col>
</van-row>
</div>
</template>
<script>
const gutterValue = ref(20);
const dynamicGutter = computed(() => [gutterValue.value, gutterValue.value]);
const handleGutterChange = (value) => {
console.log('間距變更為:', value);
};
</script>進階用法範例
卡片式布局
html
<template>
<van-row :gutter="[16, 16]">
<van-col
v-for="card in cardList"
:key="card.id"
:span="cardSpan"
>
<div class="card-container">
<div class="card-header">{{ card.title }}</div>
<div class="card-content">{{ card.content }}</div>
<div class="card-footer">{{ card.date }}</div>
</div>
</van-col>
</van-row>
</template>
<style>
.card-container {
background: #fff;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
height: 100%;
display: flex;
flex-direction: column;
}
.card-header {
font-weight: bold;
margin-bottom: 12px;
}
.card-content {
flex: 1;
color: #666;
line-height: 1.5;
}
.card-footer {
margin-top: 12px;
font-size: 12px;
color: #999;
}
</style>儀表板布局
html
<template>
<div class="dashboard">
<!-- 頂部統計區域 -->
<van-row :gutter="20" class="stats-row">
<van-col :span="6" v-for="stat in stats" :key="stat.id">
<div class="stat-card">
<div class="stat-value">{{ stat.value }}</div>
<div class="stat-label">{{ stat.label }}</div>
</div>
</van-col>
</van-row>
<!-- 主要內容區域 -->
<van-row :gutter="20" class="content-row">
<van-col :span="16">
<div class="chart-container">
<!-- 圖表元件 -->
</div>
</van-col>
<van-col :span="8">
<div class="sidebar-container">
<!-- 側邊欄內容 -->
</div>
</van-col>
</van-row>
</div>
</template>相關元件
- Space 間距 - 設定元件之間的間距
- Divider 分割線 - 區分內容的分割線
- Grid 宮格 - 宮格布局元件
- Sticky 粘性布局 - 粘性定位布局