Files
rxthinkcmf-wiki/RXThinkCMF_ThinkPhp8_EleVue/.vitepress/dist/assets/zh_frontend_layout.md.Dh0nlAcl.lean.js
T
2026-10-25 18:52:36 +08:00

56 lines
15 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{_ as i,o as a,c as n,a2 as l}from"./chunks/framework.B-QBKwc1.js";const c=JSON.parse('{"title":"布局系统","description":"前端布局采用经典的企业后台布局:左侧菜单 + 顶部导航 + 内容区域,支持多标签页导航。","frontmatter":{},"headers":[],"relativePath":"zh/frontend/layout.md","filePath":"zh/frontend/layout.md"}'),t={name:"zh/frontend/layout.md"};function p(e,s,h,k,r,F){return a(),n("div",null,[...s[0]||(s[0]=[l(`<h1 id="_9-15-布局系统" tabindex="-1">9.15 布局系统 <a class="header-anchor" href="#_9-15-布局系统" aria-label="Permalink to &quot;9.15 布局系统&quot;">​</a></h1><div class="tip custom-block"><p class="custom-block-title">概述</p><p>前端布局采用经典的企业后台布局:左侧菜单 + 顶部导航 + 内容区域,支持多标签页导航。</p></div><h2 id="布局结构" tabindex="-1">布局结构 <a class="header-anchor" href="#布局结构" aria-label="Permalink to &quot;布局结构&quot;">​</a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>┌─────────────────────────────────────────────────────────────┐</span></span>
<span class="line"><span>│ 顶部导航栏 │</span></span>
<span class="line"><span>│ [Logo] [面包屑] [搜索] [通知] [头像] │</span></span>
<span class="line"><span>├──────────┬──────────────────────────────────────────────────┤</span></span>
<span class="line"><span>│ │ │</span></span>
<span class="line"><span>│ 侧边栏 │ 内容区域 │</span></span>
<span class="line"><span>│ 菜单 │ │</span></span>
<span class="line"><span>│ │ ┌──────────────────────────────────────────┐ │</span></span>
<span class="line"><span>│ ──────── │ │ 标签页导航 │ │</span></span>
<span class="line"><span>│ 系统管理 │ ├──────────────────────────────────────────┤ │</span></span>
<span class="line"><span>│ ├ 用户 │ │ │ │</span></span>
<span class="line"><span>│ ├ 角色 │ │ 页面内容 │ │</span></span>
<span class="line"><span>│ └ 菜单 │ │ │ │</span></span>
<span class="line"><span>│ │ │ │ │</span></span>
<span class="line"><span>│ 内容管理 │ │ │ │</span></span>
<span class="line"><span>│ ├ 文章 │ │ │ │</span></span>
<span class="line"><span>│ └ 分类 │ │ │ │</span></span>
<span class="line"><span>│ │ └──────────────────────────────────────────┘ │</span></span>
<span class="line"><span>└──────────┴──────────────────────────────────────────────────┘</span></span></code></pre></div><h2 id="布局组件" tabindex="-1">布局组件 <a class="header-anchor" href="#布局组件" aria-label="Permalink to &quot;布局组件&quot;">​</a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>ui/src/layout/</span></span>
<span class="line"><span>├── index.vue # 布局入口</span></span>
<span class="line"><span>├── components/</span></span>
<span class="line"><span>│ ├── header/ # 顶部导航(Logo、面包屑、搜索、通知、用户头像)</span></span>
<span class="line"><span>│ ├── sider/ # 侧边栏菜单(动态菜单、折叠、主题)</span></span>
<span class="line"><span>│ ├── content/ # 内容区域(keep-alive 缓存)</span></span>
<span class="line"><span>│ ├── tabs/ # 标签页导航(多标签切换、关闭)</span></span>
<span class="line"><span>│ └── footer/ # 页脚</span></span>
<span class="line"><span>└── hooks/ # 布局相关 hooks</span></span></code></pre></div><h2 id="侧边栏菜单" tabindex="-1">侧边栏菜单 <a class="header-anchor" href="#侧边栏菜单" aria-label="Permalink to &quot;侧边栏菜单&quot;">​</a></h2><p>菜单数据从后端 <code>/index/getMenus</code> 接口获取,由 <code>asyncRouteStore</code> 管理:</p><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 菜单渲染逻辑</span></span>
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> menuList</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> asyncRouteStore</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">getMenus</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 菜单数据结构</span></span>
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">interface</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> MenuItem</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> id</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> number</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> parentId</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> number</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> path</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> component</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> icon</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> sort</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> number</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> hide</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> boolean</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> children</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">?</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> MenuItem</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[];</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><h2 id="标签页导航" tabindex="-1">标签页导航 <a class="header-anchor" href="#标签页导航" aria-label="Permalink to &quot;标签页导航&quot;">​</a></h2><p>标签页自动记录访问过的页面,支持:</p><ul><li>点击切换</li><li>关闭当前/其他/全部</li><li>右键菜单操作</li><li>keep-alive 缓存</li></ul><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 标签页 Store</span></span>
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> tabsViewStore</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> useTabsViewStore</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 添加标签</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">tabsViewStore</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">addTab</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">route</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 关闭标签</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">tabsViewStore</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">removeTab</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">route</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span></code></pre></div><h2 id="响应式布局" tabindex="-1">响应式布局 <a class="header-anchor" href="#响应式布局" aria-label="Permalink to &quot;响应式布局&quot;">​</a></h2><p>布局支持桌面端和平板端:</p><ul><li>桌面端:侧边栏默认展开</li><li>平板端:侧边栏默认折叠</li><li>侧边栏支持手动折叠/展开</li></ul><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 侧边栏折叠状态</span></span>
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> collapsed</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> ref</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;">false</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 响应式检测</span></span>
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> width</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> useWindowSize</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">watchEffect</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(()</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =&gt;</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> collapsed</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">value</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> width</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">value</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> &lt;</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 1024</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">});</span></span></code></pre></div>`,17)])])}const o=i(t,[["render",p]]);export{c as __pageData,o as default};