Skip to content

PageGrid 页面栅格

用于承接 PC 页面级栅格规则。底层仍是 24 列;PageGrid 只负责区分后台管理和门户页两种页面场景,避免把侧边栏、门户边距和业务内容区混在一起算。

ts
import { createApp } from 'vue'
import { PageGrid, PageGridItem, PageLayout } from '@szhn/dh-design-pc'

const app = createApp({})
app.use(PageGrid)
app.use(PageGridItem)
app.use(PageLayout)

PageGrid 通常放在页面最外层,先决定页面属于后台管理还是门户页;业务区域内部再使用 PageGridItem、PageLayout 或 Row / Col 承接具体内容。

页面最外层布局

<template>
  <div ref="hostRef" class="page-shell-demo" :style="hostStyle">
    <div ref="canvasRef" class="page-shell-demo__canvas" :style="canvasStyle">
      <PageGrid scene="admin" sidebar="expanded" class="page-shell-demo__page">
        <template #sidebar>
          <nav class="page-shell-demo__sidebar">
            <div class="page-shell-demo__sidebar-title">导航区</div>
            <div v-for="item in menuItems" :key="item" class="page-shell-demo__menu-item">
              {{ item }}
            </div>
          </nav>
        </template>

        <PageGridItem :span="24">
          <header class="page-shell-demo__header">
            <strong>任务管理</strong>
            <span>页面标题区</span>
          </header>
        </PageGridItem>

        <PageGridItem :span="24">
          <section class="page-shell-demo__filter">筛选查询区</section>
        </PageGridItem>

        <PageGridItem :span="16">
          <main class="page-shell-demo__main">任务列表区</main>
        </PageGridItem>

        <PageGridItem :span="8">
          <aside class="page-shell-demo__aside">指标看板</aside>
        </PageGridItem>
      </PageGrid>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PageGrid, PageGridItem } from '@szhn/dh-design-pc'
import { useScaledCanvas } from './useScaledCanvas'

const menuItems = ['工作台', '数据管理', '系统配置']
const { canvasRef, canvasStyle, hostRef, hostStyle } = useScaledCanvas()
</script>

<style scoped>
.page-shell-demo {
  overflow: hidden;
  position: relative;
  width: 100%;
}

.page-shell-demo__canvas {
  left: 0;
  position: absolute;
  top: 0;
  transform-origin: left top;
}

.page-shell-demo__page {
  background: var(--el-fill-color-lighter);
  min-height: 420px;
  padding-block: 16px;
}

.page-shell-demo__sidebar,
.page-shell-demo__header,
.page-shell-demo__filter,
.page-shell-demo__main,
.page-shell-demo__aside {
  border: 1px solid var(--el-border-color-light);
}

.page-shell-demo__sidebar {
  background: #e8ebef;
  display: grid;
  gap: 12px;
  height: 388px;
  padding: 16px;
}

.page-shell-demo__sidebar-title {
  color: var(--el-text-color-secondary);
  font-size: 13px;
  font-weight: 600;
}

.page-shell-demo__menu-item {
  align-items: center;
  background: var(--el-bg-color);
  color: var(--el-text-color-primary);
  display: flex;
  font-size: 13px;
  height: 36px;
  padding-inline: 12px;
}

.page-shell-demo__header {
  align-items: center;
  background: var(--el-bg-color);
  display: flex;
  gap: 12px;
  height: 56px;
  padding-inline: 16px;
}

.page-shell-demo__header span {
  color: var(--el-text-color-secondary);
  font-size: 13px;
}

.page-shell-demo__filter,
.page-shell-demo__main,
.page-shell-demo__aside {
  align-items: center;
  display: flex;
  justify-content: center;
}

.page-shell-demo__filter {
  background: var(--el-bg-color);
  height: 72px;
}

.page-shell-demo__main {
  background: var(--el-fill-color-light);
  min-height: 220px;
}

.page-shell-demo__aside {
  background: #e7eef8;
  min-height: 220px;
}
</style>

后台管理

<template>
  <div ref="hostRef" class="page-grid-demo" :style="hostStyle">
    <div ref="canvasRef" class="page-grid-demo__canvas" :style="canvasStyle">
      <PageGrid scene="admin" sidebar="expanded" class="page-grid-demo__frame">
        <template #sidebar>
          <div class="page-grid-demo__sidebar">224px</div>
        </template>
        <PageGridItem v-for="item in 24" :key="`expanded-${item}`" :span="1">
          <div class="page-grid-demo__col">34px</div>
        </PageGridItem>
      </PageGrid>

      <PageGrid scene="admin" sidebar="collapsed" class="page-grid-demo__frame">
        <template #sidebar>
          <div class="page-grid-demo__sidebar page-grid-demo__sidebar--collapsed">80px</div>
        </template>
        <PageGridItem v-for="item in 24" :key="`collapsed-${item}`" :span="1">
          <div class="page-grid-demo__col">40px</div>
        </PageGridItem>
      </PageGrid>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PageGrid, PageGridItem } from '@szhn/dh-design-pc'
import { useScaledCanvas } from './useScaledCanvas'

const { canvasRef, canvasStyle, hostRef, hostStyle } = useScaledCanvas()
</script>

<style scoped>
.page-grid-demo {
  overflow: hidden;
  position: relative;
  width: 100%;
}

.page-grid-demo__canvas {
  display: grid;
  gap: 24px;
  left: 0;
  position: absolute;
  top: 0;
  transform-origin: left top;
}

.page-grid-demo__frame {
  background: var(--el-fill-color-light);
  min-height: 112px;
  padding-block: 16px;
}

.page-grid-demo__sidebar {
  align-items: center;
  background: #dfe3e8;
  color: var(--el-text-color-secondary);
  display: flex;
  font-size: 12px;
  height: 80px;
  justify-content: center;
}

.page-grid-demo__sidebar--collapsed {
  background: #e8ebef;
}

.page-grid-demo__col {
  align-items: center;
  background: rgb(7 90 237 / 12%);
  color: var(--el-color-primary);
  display: flex;
  font-size: 11px;
  height: 80px;
  justify-content: center;
  overflow: hidden;
  white-space: nowrap;
}
</style>

门户页

<template>
  <div ref="hostRef" class="page-grid-portal-demo-shell" :style="hostStyle">
    <div ref="canvasRef" class="page-grid-portal-demo-shell__canvas" :style="canvasStyle">
      <PageGrid scene="portal" class="page-grid-portal-demo">
        <PageGridItem :span="24">
          <div class="page-grid-portal-demo__hero">1280px 内容区</div>
        </PageGridItem>
        <PageGridItem v-for="item in 4" :key="item" :span="6">
          <div class="page-grid-portal-demo__card">6 列模块</div>
        </PageGridItem>
      </PageGrid>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PageGrid, PageGridItem } from '@szhn/dh-design-pc'
import { useScaledCanvas } from './useScaledCanvas'

const { canvasRef, canvasStyle, hostRef, hostStyle } = useScaledCanvas()
</script>

<style scoped>
.page-grid-portal-demo-shell {
  overflow: hidden;
  position: relative;
  width: 100%;
}

.page-grid-portal-demo-shell__canvas {
  left: 0;
  position: absolute;
  top: 0;
  transform-origin: left top;
}

.page-grid-portal-demo {
  background: var(--el-fill-color-light);
  padding-block: 20px;
}

.page-grid-portal-demo__hero,
.page-grid-portal-demo__card {
  align-items: center;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-light);
  color: var(--el-text-color-primary);
  display: flex;
  justify-content: center;
}

.page-grid-portal-demo__hero {
  height: 96px;
  font-size: 16px;
  font-weight: 600;
}

.page-grid-portal-demo__card {
  height: 72px;
  font-size: 13px;
}
</style>

页面分区

<template>
  <div ref="hostRef" class="page-layout-demo-shell" :style="hostStyle">
    <div ref="canvasRef" class="page-layout-demo" :style="canvasStyle">
      <PageGrid scene="admin" sidebar="none">
        <PageGridItem :span="24">
          <PageLayout variant="t" side-width="180px" aside-width="220px">
            <template #top>
              <div class="page-layout-demo__block page-layout-demo__block--nav">导航栏</div>
            </template>
            <template #side>
              <div class="page-layout-demo__block page-layout-demo__block--side">侧边栏</div>
            </template>
            <div class="page-layout-demo__block page-layout-demo__block--main">任务列表区</div>
            <template #aside>
              <div class="page-layout-demo__block page-layout-demo__block--aside">筛选查询区</div>
            </template>
          </PageLayout>
        </PageGridItem>
      </PageGrid>

      <PageGrid scene="portal">
        <PageGridItem :span="24">
          <PageLayout variant="vertical">
            <template #top>
              <div class="page-layout-demo__block page-layout-demo__block--nav">一级导航栏</div>
            </template>
            <template #subtop>
              <div class="page-layout-demo__block page-layout-demo__block--subnav">二级导航栏</div>
            </template>
            <div class="page-layout-demo__block page-layout-demo__block--main">主要内容区</div>
          </PageLayout>
        </PageGridItem>
      </PageGrid>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PageGrid, PageGridItem, PageLayout } from '@szhn/dh-design-pc'
import { useScaledCanvas } from './useScaledCanvas'

const { canvasRef, canvasStyle, hostRef, hostStyle } = useScaledCanvas()
</script>

<style scoped>
.page-layout-demo-shell {
  overflow: hidden;
  position: relative;
  width: 100%;
}

.page-layout-demo {
  display: grid;
  gap: 20px;
  left: 0;
  position: absolute;
  top: 0;
  transform-origin: left top;
}

.page-layout-demo__block {
  align-items: center;
  border: 1px solid var(--el-border-color-light);
  color: var(--el-text-color-primary);
  display: flex;
  font-size: 13px;
  justify-content: center;
}

.page-layout-demo__block--nav,
.page-layout-demo__block--subnav {
  background: rgb(7 90 237 / 14%);
  height: 48px;
}

.page-layout-demo__block--side,
.page-layout-demo__block--aside {
  background: #e7eef8;
  height: 180px;
}

.page-layout-demo__block--main {
  background: var(--el-fill-color-light);
  min-height: 180px;
}
</style>

规则

场景外侧处理内容区栅格
后台管理侧边栏是布局参数,不纳入栅格右侧内容区流式自适应24 列,默认 16px 水槽
门户页1440px 基准下左右 80px,小屏不低于 24px最大 1280px,居中24 列,默认 16px 水槽

后台页面不要套用门户页的 80px 边距,门户页面也不要使用后台的流式全宽规则。需要普通分栏时仍然可以直接使用 Row / Col

API

PageGrid Props

属性名说明类型默认值
scene页面场景admin / portaladmin
sidebar后台侧栏状态expanded / collapsed / nonenone
columns栅格列数number24
gutter水槽宽度string / numbervar(--dh-grid-gutter, 16px)
row-gutter纵向间距string / numbervar(--dh-grid-gutter, 16px)
admin-edge后台内容区边距string / numbervar(--dh-content-margin, 16px)
admin-sidebar-width后台侧栏展开宽度string / numbervar(--dh-sidebar-width, 224px)
admin-sidebar-collapsed-width后台侧栏收起宽度string / numbervar(--dh-sidebar-collapsed-width, 80px)
portal-content-width门户内容区最大宽度string / number1280px
portal-edge门户基准边距string / number80px
portal-min-edge门户小屏最小边距string / number24px
grid是否把默认插槽作为 24 列栅格轨道booleantrue

PageGrid Slots

插槽名说明
default内容区栅格项
sidebar后台侧栏占位内容

PageGridItem Props

属性名说明类型默认值
span占据列数number24
offset左侧偏移列数number0
columns当前总列数number24

PageLayout Props

属性名说明类型默认值
variant内容区分区形态t / verticalvertical
gap分区间距string / numbervar(--dh-content-margin, 16px)
side-widthT 型布局左侧区域宽度string / number224px
aside-widthT 型布局右侧区域宽度string / number280px

PageLayout Slots

插槽名说明
top顶部通栏
subtop二级顶部区域
default主内容区
sideT 型布局左侧区域
asideT 型布局右侧区域
bottom底部区域