"use strict";(self.webpackChunkfes_js=self.webpackChunkfes_js||[]).push([[475],{1783:(n,s,a)=>{a.r(s),a.d(s,{data:()=>e});const e={key:"v-355ee23e",path:"/reference/plugin/plugins/layout.html",title:"@fesjs/plugin-layout",lang:"zh-CN",frontmatter:{},excerpt:"",headers:[{level:2,title:"介绍",slug:"介绍",children:[]},{level:2,title:"启用方式",slug:"启用方式",children:[]},{level:2,title:"布局类型",slug:"布局类型",children:[{level:3,title:"side",slug:"side",children:[]},{level:3,title:"top",slug:"top",children:[]},{level:3,title:"mixin",slug:"mixin",children:[]},{level:3,title:"页面禁用布局",slug:"页面禁用布局",children:[]}]},{level:2,title:"keep-alive",slug:"keep-alive",children:[]},{level:2,title:"编译时配置",slug:"编译时配置",children:[{level:3,title:"footer",slug:"footer",children:[]},{level:3,title:"theme",slug:"theme",children:[]},{level:3,title:"navigation",slug:"navigation",children:[]},{level:3,title:"fixedHeader",slug:"fixedheader",children:[]},{level:3,title:"fixedSideBar",slug:"fixedsidebar",children:[]},{level:3,title:"title",slug:"title",children:[]},{level:3,title:"logo",slug:"logo",children:[]},{level:3,title:"multiTabs",slug:"multitabs",children:[]},{level:3,title:"menus",slug:"menus",children:[]},{level:3,title:"menusConfig",slug:"menusconfig",children:[]}]},{level:2,title:"运行时配置",slug:"运行时配置",children:[{level:3,title:"menus",slug:"menus-1",children:[]},{level:3,title:"header",slug:"header",children:[]},{level:3,title:"sidebar",slug:"sidebar",children:[]},{level:3,title:"logo",slug:"logo-1",children:[]},{level:3,title:"customHeader",slug:"customheader",children:[]},{level:3,title:"unAccessHandler",slug:"unaccesshandler",children:[]},{level:3,title:"noFoundHandler",slug:"nofoundhandler",children:[]},{level:3,title:"logoUrl",slug:"logourl",children:[]},{level:3,title:"其他运行时配置 (> 4.1.0)",slug:"其他运行时配置-4-1-0",children:[]}]}],filePathRelative:"reference/plugin/plugins/layout.md",git:{updatedTime:1653450562e3,contributors:[{name:"wanchun",email:"445436867@qq.com",commits:1}]}}},2891:(n,s,a)=>{a.r(s),a.d(s,{default:()=>wn});var e=a(6252);const p=(0,e._)("h1",{id:"fesjs-plugin-layout",tabindex:"-1"},[(0,e._)("a",{class:"header-anchor",href:"#fesjs-plugin-layout","aria-hidden":"true"},"#"),(0,e.Uk)(" @fesjs/plugin-layout")],-1),t=(0,e._)("h2",{id:"介绍",tabindex:"-1"},[(0,e._)("a",{class:"header-anchor",href:"#介绍","aria-hidden":"true"},"#"),(0,e.Uk)(" 介绍")],-1),l=(0,e._)("p",null,"为了进一步降低研发成本,我们尝试将布局通过 fes 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。",-1),o=(0,e.uE)("
  • 侧边栏菜单数据根据路由中的配置自动生成。

  • 布局,提供 sidetopmixin 三种布局。

  • 主题,提供 lightdark 两种主题。

  • 默认实现对路由的 404、403 处理。

  • ",4),c=(0,e.Uk)("搭配 "),r=(0,e.Uk)("@fesjs/plugin-access"),i=(0,e.Uk)(" 插件使用,可以完成对路由的权限控制。"),u=(0,e.Uk)("搭配 "),d=(0,e.Uk)("@fesjs/plugin-locale"),k=(0,e.Uk)(" 插件使用,提供切换语言的能力。"),g=(0,e._)("li",null,[(0,e._)("p",null,"支持自定义头部区域。")],-1),b=(0,e._)("li",null,[(0,e._)("p",null,"菜单支持配置icon")],-1),m=(0,e._)("li",null,[(0,e._)("p",null,"菜单标题支持国际化")],-1),h=(0,e._)("li",null,[(0,e._)("p",null,"可配置页面是否需要 layout。")],-1),f=(0,e.uE)('

    启用方式

    package.json 中引入依赖:

    {\n    "dependencies": {\n        "@fesjs/fes": "^2.0.0",\n        "@fesjs/plugin-layout": "^4.0.0"\n    },\n}\n
    1
    2
    3
    4
    5
    6

    布局类型

    配置参数是 navigation, 布局有三种类型 sidemixintop, 默认是 side

    export default {\n    layout: {\n        navigation: 'side'\n    }\n}\n
    1
    2
    3
    4
    5

    side

    ',7),v=["src"],y=(0,e._)("h3",{id:"top",tabindex:"-1"},[(0,e._)("a",{class:"header-anchor",href:"#top","aria-hidden":"true"},"#"),(0,e.Uk)(" top")],-1),x=["src"],_=(0,e._)("h3",{id:"mixin",tabindex:"-1"},[(0,e._)("a",{class:"header-anchor",href:"#mixin","aria-hidden":"true"},"#"),(0,e.Uk)(" mixin")],-1),j=["src"],U=(0,e.uE)('

    页面禁用布局

    布局是默认开启的,但是可能某些页面不需要展示布局样式,比如登录页面。我们只需要在页面的.vue中添加如下配置:

    <config lang="json">\n{\n    "layout": false\n}\n</config>\n
    1
    2
    3
    4
    5

    如果只是不想展示sidebar,则:

    <config lang="json">\n{\n    "layout": {\n        "sidebar": false\n    }\n}\n</config>\n
    1
    2
    3
    4
    5
    6
    7

    layout的可选配置有:

    keep-alive

    从 4.0.7 开始支持配置路由页面缓存:

    <config lang="json">\n{\n    "keep-alive": true\n}\n</config>\n
    1
    2
    3
    4
    5

    编译时配置

    .fes.js 中配置:

    export default {\n    layout: {\n        // 标题\n        title: "Fes.js",\n        // 底部文字\n        footer: 'Created by MumbleFE',\n        // 主题light\n        theme: 'dark'\n        // 是否开启 tabs\n        multiTabs: false,\n        // 布局类型\n        navigation: 'side',\n        // 是否固定头部\n        fixedHeader: false,\n        // 是否固定sidebar\n        fixedSideBar: true,\n        // sidebar的宽度\n        sideWidth: 200,\n        menus: [{\n            name: 'index'\n        }, {\n            name: 'onepiece'\n        }, {\n            name: 'store'\n        }, {\n            name: 'simpleList'\n        }],\n        menuConfig: {\n            defaultExpandAll: false,\n            expandedKeys: [],\n            accordion: false\n        }\n    },\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    theme

    fixedHeader

    fixedSideBar

    title

    multiTabs

    ',30),w=(0,e._)("li",null,[(0,e._)("p",null,[(0,e._)("strong",null,"类型"),(0,e.Uk)(":"),(0,e._)("code",null,"Array")])],-1),E=(0,e._)("li",null,[(0,e._)("p",null,[(0,e._)("strong",null,"默认值"),(0,e.Uk)(":"),(0,e._)("code",null,"[]")])],-1),A=(0,e._)("p",null,[(0,e._)("strong",null,"详情"),(0,e.Uk)(":菜单配置,子项具体配置如下:")],-1),q=(0,e._)("strong",null,"name",-1),C=(0,e.Uk)(":菜单的名称。通过匹配 "),B=(0,e._)("code",null,"name",-1),F=(0,e.Uk)(" 和路由元信息 "),H=(0,e.Uk)("meta"),S=(0,e.Uk)(" 中的 "),R=(0,e._)("code",null,"name",-1),L=(0,e.Uk)(",把菜单和路由关联起来,\b然后使用路由元信息补充菜单配置,比如 "),W=(0,e._)("code",null,"title",-1),I=(0,e.Uk)("、"),O=(0,e._)("code",null,"path",-1),$=(0,e.Uk)(" \b等。"),z=(0,e._)("li",null,[(0,e._)("p",null,[(0,e._)("strong",null,"path"),(0,e.Uk)(":菜单的路径,可配置第三方地址。")])],-1),M=(0,e._)("li",null,[(0,e._)("p",null,[(0,e._)("strong",null,"match"),(0,e.Uk)(":额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。 (v4.0.0+)")])],-1),T=(0,e.uE)('
    {\n    path: '/product',\n    match: ['/product/*', '/product/create']\n}\n
    1
    2
    3
    4
    ',1),D=(0,e._)("strong",null,"title",-1),K=(0,e.Uk)(":菜单的标题,如果同时使用"),N=(0,e.Uk)("国际化插件"),Z=(0,e.Uk)(",而且"),P=(0,e._)("code",null,"title",-1),V=(0,e.Uk)("的值以"),Y=(0,e._)("code",null,"$",-1),G=(0,e.Uk)("开头,则使用"),J=(0,e._)("code",null,"$",-1),Q=(0,e.Uk)("后面的内容去匹配语言设置。"),X=(0,e._)("p",null,[(0,e._)("strong",null,"icon"),(0,e.Uk)(": 菜单的图标,只有一级标题展示图标。")],-1),nn=(0,e.Uk)("图标使用"),sn={href:"https://fes-design-4gvn317r3b6bfe17-1254145788.ap-shanghai.app.tcloudbase.com/zh/components/icon.html",target:"_blank",rel:"noopener noreferrer"},an=(0,e.Uk)("fes-design icon"),en=(0,e.Uk)(",在这里使用组件名称。"),pn=(0,e.uE)('
    {\n    icon: "AppstoreOutlined"\n}\n
    1
    2
    3
    - 图标使用本地或者远程svg图片。\n
    {\n    icon: "/wine-outline.svg"\n}\n
    1
    2
    3

    运行时配置

    app.js 中配置:

    import UserCenter from '@/components/UserCenter';\nexport const layout = {\n    customHeader: <UserCenter />\n};\n\n
    1
    2
    3
    4
    5
    import { ClusterOutlined } from '@fesjs/fes-design/icon'\nexport const layout = layoutConfig => ({\n    ...layoutConfig,\n    customHeader: <UserCenter />,\n    menus: (defaultMenuData) => {\n        const menusRef = ref(defaultMenuData);\n        watch(() => layoutConfig.initialState.userName, () => {\n            menusRef.value = [{\n                name: 'store',\n                icon: <ClusterOutlined />\n            }];\n        });\n        return menusRef;\n    }\n});\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    layoutConfig.initialStatebeforeRender.action执行后创建的应用初始状态数据。

    如果菜单需要根据某些状态动态改变,则返回Ref,否则只需要返回数组。

    提示

    在运行时配置菜单中的icon,需要传组件本身,而不是组件的名称。

    logo

    customHeader

    unAccessHandler

    ',24),tn=(0,e.uE)("
  • 类型Function

  • 默认值null

  • 详情

    当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 unAccessHandler 函数。

  • ",3),ln=(0,e._)("p",null,[(0,e._)("strong",null,"参数")],-1),on=(0,e._)("li",null,"router:createRouter 创建的路由实例",-1),cn=(0,e._)("li",null,"to: 准备进入的路由",-1),rn=(0,e._)("li",null,"from:离开的路由",-1),un=(0,e.Uk)("next: "),dn={href:"https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%8F%AF%E9%80%89%E7%9A%84%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0-next",target:"_blank",rel:"noopener noreferrer"},kn=(0,e.Uk)("next函数"),gn=(0,e.uE)('

    比如:

    export const access = {\n    unAccessHandler({ to, next }) {\n        const accesssIds = accessApi.getAccess();\n        if (to.path === '/404') {\n            accessApi.setAccess(accesssIds.concat(['/404']));\n            return next('/404');\n        }\n        if (!accesssIds.includes('/403')) {\n            accessApi.setAccess(accesssIds.concat(['/403']));\n        }\n        next('/403');\n    }\n};\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    noFoundHandler

    ',3),bn=(0,e.uE)("
  • 类型:函数

  • 默认值:null

  • 详情

    当进入某个路由时,如果路由对应的页面不存在,则会调用 noFoundHandler 函数。

  • ",3),mn=(0,e._)("p",null,[(0,e._)("strong",null,"参数")],-1),hn=(0,e._)("li",null,"router:createRouter 创建的路由实例",-1),fn=(0,e._)("li",null,"to: 准备进入的路由",-1),vn=(0,e._)("li",null,"from:离开的路由",-1),yn=(0,e.Uk)("next: "),xn={href:"https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%8F%AF%E9%80%89%E7%9A%84%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0-next",target:"_blank",rel:"noopener noreferrer"},_n=(0,e.Uk)("next函数"),jn=(0,e.uE)('

    比如:

    export const access = {\n    noFoundHandler({ next }) {\n        const accesssIds = accessApi.getAccess();\n        if (!accesssIds.includes('/404')) {\n            accessApi.setAccess(accesssIds.concat(['/404']));\n        }\n        next('/404');\n    }\n};\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    logoUrl

    其他运行时配置 (> 4.1.0)

    编译时配置的内容同样支持在运行时配置,但是logo除外,用logoUrl替代。

    ',6),Un={},wn=(0,a(3744).Z)(Un,[["render",function(n,s){const a=(0,e.up)("RouterLink"),Un=(0,e.up)("OutboundLink");return(0,e.wg)(),(0,e.iD)(e.HY,null,[p,t,l,(0,e._)("ul",null,[o,(0,e._)("li",null,[(0,e._)("p",null,[c,(0,e.Wm)(a,{to:"/reference/plugin/plugins/access.html"},{default:(0,e.w5)((()=>[r])),_:1}),i])]),(0,e._)("li",null,[(0,e._)("p",null,[u,(0,e.Wm)(a,{to:"/reference/plugin/plugins/locale.html"},{default:(0,e.w5)((()=>[d])),_:1}),k])]),g,b,m,h]),f,(0,e._)("img",{src:n.$withBase("side.png"),alt:"side"},null,8,v),y,(0,e._)("img",{src:n.$withBase("top.png"),alt:"top"},null,8,x),_,(0,e._)("img",{src:n.$withBase("mixin.png"),alt:"mixin"},null,8,j),U,(0,e._)("ul",null,[w,E,(0,e._)("li",null,[A,(0,e._)("ul",null,[(0,e._)("li",null,[(0,e._)("p",null,[q,C,B,F,(0,e.Wm)(a,{to:"/guide/route.html#%E6%89%A9%E5%B1%95%E8%B7%AF%E7%94%B1%E5%85%83%E4%BF%A1%E6%81%AF"},{default:(0,e.w5)((()=>[H])),_:1}),S,R,L,W,I,O,$])]),z,M])])]),T,(0,e._)("ul",null,[(0,e._)("li",null,[(0,e._)("p",null,[D,K,(0,e.Wm)(a,{to:"/reference/plugin/plugins/locale.html"},{default:(0,e.w5)((()=>[N])),_:1}),Z,P,V,Y,G,J,Q])]),(0,e._)("li",null,[X,(0,e._)("ul",null,[(0,e._)("li",null,[nn,(0,e._)("a",sn,[an,(0,e.Wm)(Un)]),en])])])]),pn,(0,e._)("ul",null,[tn,(0,e._)("li",null,[ln,(0,e._)("ul",null,[on,cn,rn,(0,e._)("li",null,[un,(0,e._)("a",dn,[kn,(0,e.Wm)(Un)])])])])]),gn,(0,e._)("ul",null,[bn,(0,e._)("li",null,[mn,(0,e._)("ul",null,[hn,fn,vn,(0,e._)("li",null,[yn,(0,e._)("a",xn,[_n,(0,e.Wm)(Un)])])])])]),jn],64)}]])},3744:(n,s)=>{s.Z=(n,s)=>{const a=n.__vccOpts||n;for(const[n,e]of s)a[n]=e;return a}}}]);