From 76e380fbe4120f7632bb1ad426663b3a9060e92e Mon Sep 17 00:00:00 2001 From: wangjue666 Date: Wed, 18 Oct 2023 01:30:11 +0000 Subject: [PATCH] deploy: 705543dd7e21b278dd6c2cf049889a829acd9299 --- .nojekyll | 0 CNAME | 1 + README.html | 39 ++ assets/Home.00e49e13.js | 1 + assets/README.md.b7eec73c.js | 1 + assets/README.md.b7eec73c.lean.js | 1 + assets/app.8cddb23b.js | 15 + assets/components_auth.md.7bb93906.js | 1 + assets/components_auth.md.7bb93906.lean.js | 1 + assets/components_basic.md.28757feb.js | 1 + assets/components_basic.md.28757feb.lean.js | 1 + .../components_click-out-side.md.218c4280.js | 1 + ...ponents_click-out-side.md.218c4280.lean.js | 1 + assets/components_code-editor.md.a00c679f.js | 1 + ...components_code-editor.md.a00c679f.lean.js | 1 + ...mponents_collapse-container.md.d3614750.js | 1 + ...nts_collapse-container.md.d3614750.lean.js | 1 + assets/components_count-down.md.9adb65a3.js | 1 + .../components_count-down.md.9adb65a3.lean.js | 1 + assets/components_count-to.md.e7a76610.js | 1 + .../components_count-to.md.e7a76610.lean.js | 1 + assets/components_cropper.md.a5f71a93.js | 1 + assets/components_cropper.md.a5f71a93.lean.js | 1 + assets/components_desc.md.c82924aa.js | 1 + assets/components_desc.md.c82924aa.lean.js | 1 + assets/components_drawer.md.6f60c980.js | 1 + assets/components_drawer.md.6f60c980.lean.js | 1 + assets/components_excel.md.b9baf91f.js | 1 + assets/components_excel.md.b9baf91f.lean.js | 1 + assets/components_flow-chart.md.387f4a76.js | 1 + .../components_flow-chart.md.387f4a76.lean.js | 1 + assets/components_form.md.3e11ed4d.js | 1 + assets/components_form.md.3e11ed4d.lean.js | 1 + ...nts_functional_context-menu.md.3bd48599.js | 1 + ...unctional_context-menu.md.3bd48599.lean.js | 1 + ...mponents_functional_loading.md.8cd1f253.js | 1 + ...nts_functional_loading.md.8cd1f253.lean.js | 1 + ...mponents_functional_preview.md.6a63f787.js | 1 + ...nts_functional_preview.md.6a63f787.lean.js | 1 + assets/components_glob_button.md.30d4499c.js | 1 + ...components_glob_button.md.30d4499c.lean.js | 1 + assets/components_icon.md.59ee5f53.js | 1 + assets/components_icon.md.59ee5f53.lean.js | 1 + assets/components_introduction.md.d908af44.js | 1 + ...omponents_introduction.md.d908af44.lean.js | 1 + assets/components_json-preview.md.ca86822d.js | 1 + ...omponents_json-preview.md.ca86822d.lean.js | 1 + .../components_lazy-container.md.7fe04b3b.js | 1 + ...ponents_lazy-container.md.7fe04b3b.lean.js | 1 + assets/components_loading.md.9345e82a.js | 1 + assets/components_loading.md.9345e82a.lean.js | 1 + assets/components_markdown.md.12502c77.js | 1 + .../components_markdown.md.12502c77.lean.js | 1 + assets/components_modal.md.ab172b28.js | 1 + assets/components_modal.md.ab172b28.lean.js | 1 + assets/components_page.md.f76be211.js | 1 + assets/components_page.md.f76be211.lean.js | 1 + ...mponents_pop-confirm-button.md.e437f662.js | 1 + ...nts_pop-confirm-button.md.e437f662.lean.js | 1 + assets/components_qrcode.md.5d95ff15.js | 1 + assets/components_qrcode.md.5d95ff15.lean.js | 1 + ...components_scroll-container.md.cb595324.js | 1 + ...nents_scroll-container.md.cb595324.lean.js | 1 + .../components_strength-meter.md.709cd846.js | 1 + ...ponents_strength-meter.md.709cd846.lean.js | 1 + assets/components_table.md.3c62f0f9.js | 1 + assets/components_table.md.3c62f0f9.lean.js | 1 + assets/components_time.md.059df4f7.js | 1 + assets/components_time.md.059df4f7.lean.js | 1 + assets/components_tinymce.md.bb6dd194.js | 1 + assets/components_tinymce.md.bb6dd194.lean.js | 1 + assets/components_transition.md.3cc0f9ff.js | 1 + .../components_transition.md.3cc0f9ff.lean.js | 1 + assets/components_tree.md.8773eb7b.js | 1 + assets/components_tree.md.8773eb7b.lean.js | 1 + assets/components_upload.md.6a85a24f.js | 1 + assets/components_upload.md.6a85a24f.lean.js | 1 + assets/components_verify.md.688b0bf0.js | 1 + assets/components_verify.md.688b0bf0.lean.js | 1 + .../components_virtual-scroll.md.65256e7b.js | 1 + ...ponents_virtual-scroll.md.65256e7b.lean.js | 1 + assets/dep_cors.md.37a05889.js | 1 + assets/dep_cors.md.37a05889.lean.js | 1 + assets/dep_dark.md.37147652.js | 1 + assets/dep_dark.md.37147652.lean.js | 1 + assets/dep_i18n.md.a96f197a.js | 1 + assets/dep_i18n.md.a96f197a.lean.js | 1 + assets/dep_icon.md.360e0f2b.js | 1 + assets/dep_icon.md.360e0f2b.lean.js | 1 + assets/dep_lint.md.ebbe5471.js | 1 + assets/dep_lint.md.ebbe5471.lean.js | 1 + assets/guide_auth.md.912002be.js | 1 + assets/guide_auth.md.912002be.lean.js | 1 + assets/guide_component.md.ad92b1a7.js | 1 + assets/guide_component.md.ad92b1a7.lean.js | 1 + assets/guide_deploy.md.d904a197.js | 1 + assets/guide_deploy.md.d904a197.lean.js | 1 + assets/guide_design.md.eae80806.js | 1 + assets/guide_design.md.eae80806.lean.js | 1 + assets/guide_electron.md.1fc6b47b.js | 1 + assets/guide_electron.md.1fc6b47b.lean.js | 1 + assets/guide_index.md.bb37fa1c.js | 1 + assets/guide_index.md.bb37fa1c.lean.js | 1 + assets/guide_introduction.md.e458436d.js | 1 + assets/guide_introduction.md.e458436d.lean.js | 1 + assets/guide_lib.md.9e42530e.js | 1 + assets/guide_lib.md.9e42530e.lean.js | 1 + assets/guide_menu.md.3fefed66.js | 1 + assets/guide_menu.md.3fefed66.lean.js | 1 + assets/guide_mock.md.4205a506.js | 1 + assets/guide_mock.md.4205a506.lean.js | 1 + assets/guide_router.md.31ce5cd8.js | 1 + assets/guide_router.md.31ce5cd8.lean.js | 1 + assets/guide_settings.md.560c3ce7.js | 1 + assets/guide_settings.md.560c3ce7.lean.js | 1 + assets/index.md.4d6d00ec.js | 1 + assets/index.md.4d6d00ec.lean.js | 1 + assets/other_donate.md.36952460.js | 1 + assets/other_donate.md.36952460.lean.js | 1 + assets/other_doubt.md.d791cebd.js | 1 + assets/other_doubt.md.d791cebd.lean.js | 1 + assets/other_faq.md.f27f546c.js | 1 + assets/other_faq.md.f27f546c.lean.js | 1 + assets/other_project.md.dbd0bef8.js | 1 + assets/other_project.md.dbd0bef8.lean.js | 1 + assets/other_server.md.0ae59f36.js | 1 + assets/other_server.md.0ae59f36.lean.js | 1 + assets/style.84beecbd.css | 1 + components/auth.html | 45 ++ components/basic.html | 69 +++ components/click-out-side.html | 53 ++ components/code-editor.html | 44 ++ components/collapse-container.html | 46 ++ components/count-down.html | 53 ++ components/count-to.html | 44 ++ components/cropper.html | 97 ++++ components/desc.html | 96 ++++ components/drawer.html | 96 ++++ components/excel.html | 106 ++++ components/flow-chart.html | 47 ++ components/form.html | 463 ++++++++++++++++++ components/functional/context-menu.html | 71 +++ components/functional/loading.html | 84 ++++ components/functional/preview.html | 78 +++ components/glob/button.html | 36 ++ components/icon.html | 66 +++ components/introduction.html | 45 ++ components/json-preview.html | 47 ++ components/lazy-container.html | 73 +++ components/loading.html | 74 +++ components/markdown.html | 64 +++ components/modal.html | 114 +++++ components/page.html | 67 +++ components/pop-confirm-button.html | 42 ++ components/qrcode.html | 122 +++++ components/scroll-container.html | 89 ++++ components/strength-meter.html | 58 +++ components/table.html | 342 +++++++++++++ components/time.html | 52 ++ components/tinymce.html | 50 ++ components/transition.html | 125 +++++ components/tree.html | 104 ++++ components/upload.html | 65 +++ components/verify.html | 76 +++ components/virtual-scroll.html | 90 ++++ dep/cors.html | 31 ++ dep/dark.html | 56 +++ dep/i18n.html | 150 ++++++ dep/icon.html | 193 ++++++++ dep/lint.html | 51 ++ guide/auth.html | 260 ++++++++++ guide/component.html | 145 ++++++ guide/deploy.html | 139 ++++++ guide/design.html | 107 ++++ guide/electron.html | 37 ++ guide/index.html | 130 +++++ guide/introduction.html | 39 ++ guide/lib.html | 52 ++ guide/menu.html | 91 ++++ guide/mock.html | 443 +++++++++++++++++ guide/router.html | 291 +++++++++++ guide/settings.html | 405 +++++++++++++++ images/genIcon.png | Bin 0 -> 17473 bytes images/i18n.png | Bin 0 -> 97630 bytes images/outDir.png | Bin 0 -> 21843 bytes images/report.png | Bin 0 -> 473612 bytes images/selectIconSet.png | Bin 0 -> 29413 bytes index.html | 31 ++ logo.png | Bin 0 -> 4042 bytes other/donate.html | 31 ++ other/doubt.html | 53 ++ other/faq.html | 87 ++++ other/project.html | 31 ++ other/server.html | 40 ++ 194 files changed, 6365 insertions(+) create mode 100644 .nojekyll create mode 100644 CNAME create mode 100644 README.html create mode 100644 assets/Home.00e49e13.js create mode 100644 assets/README.md.b7eec73c.js create mode 100644 assets/README.md.b7eec73c.lean.js create mode 100644 assets/app.8cddb23b.js create mode 100644 assets/components_auth.md.7bb93906.js create mode 100644 assets/components_auth.md.7bb93906.lean.js create mode 100644 assets/components_basic.md.28757feb.js create mode 100644 assets/components_basic.md.28757feb.lean.js create mode 100644 assets/components_click-out-side.md.218c4280.js create mode 100644 assets/components_click-out-side.md.218c4280.lean.js create mode 100644 assets/components_code-editor.md.a00c679f.js create mode 100644 assets/components_code-editor.md.a00c679f.lean.js create mode 100644 assets/components_collapse-container.md.d3614750.js create mode 100644 assets/components_collapse-container.md.d3614750.lean.js create mode 100644 assets/components_count-down.md.9adb65a3.js create mode 100644 assets/components_count-down.md.9adb65a3.lean.js create mode 100644 assets/components_count-to.md.e7a76610.js create mode 100644 assets/components_count-to.md.e7a76610.lean.js create mode 100644 assets/components_cropper.md.a5f71a93.js create mode 100644 assets/components_cropper.md.a5f71a93.lean.js create mode 100644 assets/components_desc.md.c82924aa.js create mode 100644 assets/components_desc.md.c82924aa.lean.js create mode 100644 assets/components_drawer.md.6f60c980.js create mode 100644 assets/components_drawer.md.6f60c980.lean.js create mode 100644 assets/components_excel.md.b9baf91f.js create mode 100644 assets/components_excel.md.b9baf91f.lean.js create mode 100644 assets/components_flow-chart.md.387f4a76.js create mode 100644 assets/components_flow-chart.md.387f4a76.lean.js create mode 100644 assets/components_form.md.3e11ed4d.js create mode 100644 assets/components_form.md.3e11ed4d.lean.js create mode 100644 assets/components_functional_context-menu.md.3bd48599.js create mode 100644 assets/components_functional_context-menu.md.3bd48599.lean.js create mode 100644 assets/components_functional_loading.md.8cd1f253.js create mode 100644 assets/components_functional_loading.md.8cd1f253.lean.js create mode 100644 assets/components_functional_preview.md.6a63f787.js create mode 100644 assets/components_functional_preview.md.6a63f787.lean.js create mode 100644 assets/components_glob_button.md.30d4499c.js create mode 100644 assets/components_glob_button.md.30d4499c.lean.js create mode 100644 assets/components_icon.md.59ee5f53.js create mode 100644 assets/components_icon.md.59ee5f53.lean.js create mode 100644 assets/components_introduction.md.d908af44.js create mode 100644 assets/components_introduction.md.d908af44.lean.js create mode 100644 assets/components_json-preview.md.ca86822d.js create mode 100644 assets/components_json-preview.md.ca86822d.lean.js create mode 100644 assets/components_lazy-container.md.7fe04b3b.js create mode 100644 assets/components_lazy-container.md.7fe04b3b.lean.js create mode 100644 assets/components_loading.md.9345e82a.js create mode 100644 assets/components_loading.md.9345e82a.lean.js create mode 100644 assets/components_markdown.md.12502c77.js create mode 100644 assets/components_markdown.md.12502c77.lean.js create mode 100644 assets/components_modal.md.ab172b28.js create mode 100644 assets/components_modal.md.ab172b28.lean.js create mode 100644 assets/components_page.md.f76be211.js create mode 100644 assets/components_page.md.f76be211.lean.js create mode 100644 assets/components_pop-confirm-button.md.e437f662.js create mode 100644 assets/components_pop-confirm-button.md.e437f662.lean.js create mode 100644 assets/components_qrcode.md.5d95ff15.js create mode 100644 assets/components_qrcode.md.5d95ff15.lean.js create mode 100644 assets/components_scroll-container.md.cb595324.js create mode 100644 assets/components_scroll-container.md.cb595324.lean.js create mode 100644 assets/components_strength-meter.md.709cd846.js create mode 100644 assets/components_strength-meter.md.709cd846.lean.js create mode 100644 assets/components_table.md.3c62f0f9.js create mode 100644 assets/components_table.md.3c62f0f9.lean.js create mode 100644 assets/components_time.md.059df4f7.js create mode 100644 assets/components_time.md.059df4f7.lean.js create mode 100644 assets/components_tinymce.md.bb6dd194.js create mode 100644 assets/components_tinymce.md.bb6dd194.lean.js create mode 100644 assets/components_transition.md.3cc0f9ff.js create mode 100644 assets/components_transition.md.3cc0f9ff.lean.js create mode 100644 assets/components_tree.md.8773eb7b.js create mode 100644 assets/components_tree.md.8773eb7b.lean.js create mode 100644 assets/components_upload.md.6a85a24f.js create mode 100644 assets/components_upload.md.6a85a24f.lean.js create mode 100644 assets/components_verify.md.688b0bf0.js create mode 100644 assets/components_verify.md.688b0bf0.lean.js create mode 100644 assets/components_virtual-scroll.md.65256e7b.js create mode 100644 assets/components_virtual-scroll.md.65256e7b.lean.js create mode 100644 assets/dep_cors.md.37a05889.js create mode 100644 assets/dep_cors.md.37a05889.lean.js create mode 100644 assets/dep_dark.md.37147652.js create mode 100644 assets/dep_dark.md.37147652.lean.js create mode 100644 assets/dep_i18n.md.a96f197a.js create mode 100644 assets/dep_i18n.md.a96f197a.lean.js create mode 100644 assets/dep_icon.md.360e0f2b.js create mode 100644 assets/dep_icon.md.360e0f2b.lean.js create mode 100644 assets/dep_lint.md.ebbe5471.js create mode 100644 assets/dep_lint.md.ebbe5471.lean.js create mode 100644 assets/guide_auth.md.912002be.js create mode 100644 assets/guide_auth.md.912002be.lean.js create mode 100644 assets/guide_component.md.ad92b1a7.js create mode 100644 assets/guide_component.md.ad92b1a7.lean.js create mode 100644 assets/guide_deploy.md.d904a197.js create mode 100644 assets/guide_deploy.md.d904a197.lean.js create mode 100644 assets/guide_design.md.eae80806.js create mode 100644 assets/guide_design.md.eae80806.lean.js create mode 100644 assets/guide_electron.md.1fc6b47b.js create mode 100644 assets/guide_electron.md.1fc6b47b.lean.js create mode 100644 assets/guide_index.md.bb37fa1c.js create mode 100644 assets/guide_index.md.bb37fa1c.lean.js create mode 100644 assets/guide_introduction.md.e458436d.js create mode 100644 assets/guide_introduction.md.e458436d.lean.js create mode 100644 assets/guide_lib.md.9e42530e.js create mode 100644 assets/guide_lib.md.9e42530e.lean.js create mode 100644 assets/guide_menu.md.3fefed66.js create mode 100644 assets/guide_menu.md.3fefed66.lean.js create mode 100644 assets/guide_mock.md.4205a506.js create mode 100644 assets/guide_mock.md.4205a506.lean.js create mode 100644 assets/guide_router.md.31ce5cd8.js create mode 100644 assets/guide_router.md.31ce5cd8.lean.js create mode 100644 assets/guide_settings.md.560c3ce7.js create mode 100644 assets/guide_settings.md.560c3ce7.lean.js create mode 100644 assets/index.md.4d6d00ec.js create mode 100644 assets/index.md.4d6d00ec.lean.js create mode 100644 assets/other_donate.md.36952460.js create mode 100644 assets/other_donate.md.36952460.lean.js create mode 100644 assets/other_doubt.md.d791cebd.js create mode 100644 assets/other_doubt.md.d791cebd.lean.js create mode 100644 assets/other_faq.md.f27f546c.js create mode 100644 assets/other_faq.md.f27f546c.lean.js create mode 100644 assets/other_project.md.dbd0bef8.js create mode 100644 assets/other_project.md.dbd0bef8.lean.js create mode 100644 assets/other_server.md.0ae59f36.js create mode 100644 assets/other_server.md.0ae59f36.lean.js create mode 100644 assets/style.84beecbd.css create mode 100644 components/auth.html create mode 100644 components/basic.html create mode 100644 components/click-out-side.html create mode 100644 components/code-editor.html create mode 100644 components/collapse-container.html create mode 100644 components/count-down.html create mode 100644 components/count-to.html create mode 100644 components/cropper.html create mode 100644 components/desc.html create mode 100644 components/drawer.html create mode 100644 components/excel.html create mode 100644 components/flow-chart.html create mode 100644 components/form.html create mode 100644 components/functional/context-menu.html create mode 100644 components/functional/loading.html create mode 100644 components/functional/preview.html create mode 100644 components/glob/button.html create mode 100644 components/icon.html create mode 100644 components/introduction.html create mode 100644 components/json-preview.html create mode 100644 components/lazy-container.html create mode 100644 components/loading.html create mode 100644 components/markdown.html create mode 100644 components/modal.html create mode 100644 components/page.html create mode 100644 components/pop-confirm-button.html create mode 100644 components/qrcode.html create mode 100644 components/scroll-container.html create mode 100644 components/strength-meter.html create mode 100644 components/table.html create mode 100644 components/time.html create mode 100644 components/tinymce.html create mode 100644 components/transition.html create mode 100644 components/tree.html create mode 100644 components/upload.html create mode 100644 components/verify.html create mode 100644 components/virtual-scroll.html create mode 100644 dep/cors.html create mode 100644 dep/dark.html create mode 100644 dep/i18n.html create mode 100644 dep/icon.html create mode 100644 dep/lint.html create mode 100644 guide/auth.html create mode 100644 guide/component.html create mode 100644 guide/deploy.html create mode 100644 guide/design.html create mode 100644 guide/electron.html create mode 100644 guide/index.html create mode 100644 guide/introduction.html create mode 100644 guide/lib.html create mode 100644 guide/menu.html create mode 100644 guide/mock.html create mode 100644 guide/router.html create mode 100644 guide/settings.html create mode 100644 images/genIcon.png create mode 100644 images/i18n.png create mode 100644 images/outDir.png create mode 100644 images/report.png create mode 100644 images/selectIconSet.png create mode 100644 index.html create mode 100644 logo.png create mode 100644 other/donate.html create mode 100644 other/doubt.html create mode 100644 other/faq.html create mode 100644 other/project.html create mode 100644 other/server.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..1ad2fd0e --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +doc.vvbin.cn diff --git a/README.html b/README.html new file mode 100644 index 00000000..1aa07c2d --- /dev/null +++ b/README.html @@ -0,0 +1,39 @@ + + + + + + vue-vben-admin-doc | Vben Admin + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/assets/Home.00e49e13.js b/assets/Home.00e49e13.js new file mode 100644 index 00000000..9069641b --- /dev/null +++ b/assets/Home.00e49e13.js @@ -0,0 +1 @@ +import{e,u as a,f as t,g as s,h as l,o as i,c as o,b as r,i as n,t as c,_ as v,p as u,j as f,F as d,r as m,w as p,k as h,l as k}from"./app.8cddb23b.js";u("data-v-e065f044");const x={key:0,class:"home-hero"},y={key:0,class:"figure"},g={key:1,id:"main-title",class:"title"},$={key:2,class:"description"};f();var _=e({expose:[],setup(e){const u=a(),f=t(),d=s((()=>f.value.heroImage||m.value||h.value||_.value)),m=s((()=>null!==f.value.heroText)),p=s((()=>f.value.heroText||u.value.title)),h=s((()=>null!==f.value.tagline)),k=s((()=>f.value.tagline||u.value.description)),_=s((()=>f.value.actionLink&&f.value.actionText)),I=s((()=>f.value.altActionLink&&f.value.altActionText));return(e,a)=>l(d)?(i(),o("header",x,[e.$frontmatter.heroImage?(i(),o("figure",y,[r("img",{class:"image",src:e.$withBase(e.$frontmatter.heroImage),alt:e.$frontmatter.heroAlt},null,8,["src","alt"])])):n("v-if",!0),l(m)?(i(),o("h1",g,c(l(p)),1)):n("v-if",!0),l(h)?(i(),o("p",$,c(l(k)),1)):n("v-if",!0),l(_)?(i(),o(v,{key:3,item:{link:l(f).actionLink,text:l(f).actionText},class:"action"},null,8,["item"])):n("v-if",!0),l(I)?(i(),o(v,{key:4,item:{link:l(f).altActionLink,text:l(f).altActionText},class:"action alt"},null,8,["item"])):n("v-if",!0)])):n("v-if",!0)}});_.__scopeId="data-v-e065f044",u("data-v-9c9c2344");const I={key:0,class:"home-features"},T={class:"wrapper"},b={class:"container"},A={class:"features"},L={key:0,class:"title"},w={key:1,class:"details"};f();var j=e({expose:[],setup(e){const a=t(),v=s((()=>a.value.features&&a.value.features.length>0)),u=s((()=>a.value.features?a.value.features:[]));return(e,a)=>l(v)?(i(),o("div",I,[r("div",T,[r("div",b,[r("div",A,[(i(!0),o(d,null,m(l(u),((e,a)=>(i(),o("section",{key:a,class:"feature"},[e.title?(i(),o("h2",L,c(e.title),1)):n("v-if",!0),e.details?(i(),o("p",w,c(e.details),1)):n("v-if",!0)])))),128))])])])])):n("v-if",!0)}});j.__scopeId="data-v-9c9c2344";const B={},C=p();u("data-v-44324124");const F={key:0,class:"footer"},q={class:"container"},z={class:"text"};f();const D=C(((e,a)=>e.$frontmatter.footer?(i(),o("footer",F,[r("div",q,[r("p",z,c(e.$frontmatter.footer),1)])])):n("v-if",!0)));B.render=D,B.__scopeId="data-v-44324124",u("data-v-1fd43058");const E={class:"home","aria-labelledby":"main-title"},G={class:"home-content"};f();var H=e({expose:[],setup:e=>(e,a)=>{const t=h("Content");return i(),o("main",E,[r(_),k(e.$slots,"hero",{},void 0,!0),r(j),r("div",G,[r(t)]),k(e.$slots,"features",{},void 0,!0),r(B),k(e.$slots,"footer",{},void 0,!0)])}});H.__scopeId="data-v-1fd43058";export default H; diff --git a/assets/README.md.b7eec73c.js b/assets/README.md.b7eec73c.js new file mode 100644 index 00000000..3a8e4a91 --- /dev/null +++ b/assets/README.md.b7eec73c.js @@ -0,0 +1 @@ +import{o as n,c as a,a as e}from"./app.8cddb23b.js";const s='{"title":"vue-vben-admin-doc","description":"","frontmatter":{},"headers":[{"level":2,"title":"如何本地开发","slug":"如何本地开发"}],"relativePath":"README.md","lastUpdated":1697592578589}',t={},o=e('

vue-vben-admin-doc

如何本地开发

# 克隆本仓库\n$ git clone git@github.com:vbenjs/vue-vben-admin-doc.git\n\n# 或者使用 yarn\n$ yarn install\n\n# 启动开发服务器\n$ yarn dev\n
',3);t.render=function(e,s,t,c,d,i){return n(),a("div",null,[o])};export default t;export{s as __pageData}; diff --git a/assets/README.md.b7eec73c.lean.js b/assets/README.md.b7eec73c.lean.js new file mode 100644 index 00000000..c22695af --- /dev/null +++ b/assets/README.md.b7eec73c.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as e}from"./app.8cddb23b.js";const s='{"title":"vue-vben-admin-doc","description":"","frontmatter":{},"headers":[{"level":2,"title":"如何本地开发","slug":"如何本地开发"}],"relativePath":"README.md","lastUpdated":1697592578589}',t={},o=e('',3);t.render=function(e,s,t,c,d,i){return n(),a("div",null,[o])};export default t;export{s as __pageData}; diff --git a/assets/app.8cddb23b.js b/assets/app.8cddb23b.js new file mode 100644 index 00000000..2975d210 --- /dev/null +++ b/assets/app.8cddb23b.js @@ -0,0 +1,15 @@ +var e=Object.defineProperty,t=Object.defineProperties,n=Object.getOwnPropertyDescriptors,o=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,s=(t,n,o)=>n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[n]=o,i=(e,t)=>{for(var n in t||(t={}))r.call(t,n)&&s(e,n,t[n]);if(o)for(var n of o(t))l.call(t,n)&&s(e,n,t[n]);return e},c=(e,o)=>t(e,n(o));function a(e,t){const n=Object.create(null),o=e.split(",");for(let r=0;r!!n[e.toLowerCase()]:e=>!!n[e]}const u=a("Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt"),d=a("itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly");function p(e){if(T(e)){const t={};for(let n=0;n{if(e){const n=e.split(h);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function m(e){let t="";if(A(e))t=e;else if(T(e))for(let n=0;nnull==e?"":R(e)?JSON.stringify(e,b,2):String(e),b=(e,t)=>P(t)?{[`Map(${t.size})`]:[...t.entries()].reduce(((e,[t,n])=>(e[`${t} =>`]=n,e)),{})}:M(t)?{[`Set(${t.size})`]:[...t.values()]}:!R(t)||T(t)||V(t)?t:String(t),y={},x=[],_=()=>{},k=()=>!1,w=/^on[^a-z]/,C=e=>w.test(e),S=e=>e.startsWith("onUpdate:"),$=Object.assign,E=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},O=Object.prototype.hasOwnProperty,L=(e,t)=>O.call(e,t),T=Array.isArray,P=e=>"[object Map]"===U(e),M=e=>"[object Set]"===U(e),j=e=>"function"==typeof e,A=e=>"string"==typeof e,I=e=>"symbol"==typeof e,R=e=>null!==e&&"object"==typeof e,F=e=>R(e)&&j(e.then)&&j(e.catch),N=Object.prototype.toString,U=e=>N.call(e),V=e=>"[object Object]"===U(e),B=e=>A(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,z=a(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),D=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},H=/-(\w)/g,W=D((e=>e.replace(H,((e,t)=>t?t.toUpperCase():"")))),q=/\B([A-Z])/g,K=D((e=>e.replace(q,"-$1").toLowerCase())),G=D((e=>e.charAt(0).toUpperCase()+e.slice(1))),J=D((e=>e?`on${G(e)}`:"")),Y=(e,t)=>e!==t&&(e==e||t==t),Q=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Z=e=>{const t=parseFloat(e);return isNaN(t)?e:t},ee=new WeakMap,te=[];let ne;const oe=Symbol(""),re=Symbol("");function le(e,t=y){(function(e){return e&&!0===e._isEffect})(e)&&(e=e.raw);const n=function(e,t){const n=function(){if(!n.active)return t.scheduler?void 0:e();if(!te.includes(n)){ce(n);try{return ue.push(ae),ae=!0,te.push(n),ne=n,e()}finally{te.pop(),pe(),ne=te[te.length-1]}}};return n.id=ie++,n.allowRecurse=!!t.allowRecurse,n._isEffect=!0,n.active=!0,n.raw=e,n.deps=[],n.options=t,n}(e,t);return t.lazy||n(),n}function se(e){e.active&&(ce(e),e.options.onStop&&e.options.onStop(),e.active=!1)}let ie=0;function ce(e){const{deps:t}=e;if(t.length){for(let n=0;n{e&&e.forEach((e=>{(e!==ne||e.allowRecurse)&&i.add(e)}))};if("clear"===t)s.forEach(c);else if("length"===n&&T(e))s.forEach(((e,t)=>{("length"===t||t>=o)&&c(e)}));else switch(void 0!==n&&c(s.get(n)),t){case"add":T(e)?B(n)&&c(s.get("length")):(c(s.get(oe)),P(e)&&c(s.get(re)));break;case"delete":T(e)||(c(s.get(oe)),P(e)&&c(s.get(re)));break;case"set":P(e)&&c(s.get(oe))}i.forEach((e=>{e.options.scheduler?e.options.scheduler(e):e()}))}const ve=a("__proto__,__v_isRef,__isVue"),me=new Set(Object.getOwnPropertyNames(Symbol).map((e=>Symbol[e])).filter(I)),ge=ke(),be=ke(!1,!0),ye=ke(!0),xe=ke(!0,!0),_e={};function ke(e=!1,t=!1){return function(n,o,r){if("__v_isReactive"===o)return!e;if("__v_isReadonly"===o)return e;if("__v_raw"===o&&r===(e?t?Xe:Qe:t?Ye:Je).get(n))return n;const l=T(n);if(!e&&l&&L(_e,o))return Reflect.get(_e,o,r);const s=Reflect.get(n,o,r);if(I(o)?me.has(o):ve(o))return s;if(e||fe(n,0,o),t)return s;if(at(s)){return!l||!B(o)?s.value:s}return R(s)?e?tt(s):et(s):s}}["includes","indexOf","lastIndexOf"].forEach((e=>{const t=Array.prototype[e];_e[e]=function(...e){const n=st(this);for(let t=0,r=this.length;t{const t=Array.prototype[e];_e[e]=function(...e){de();const n=t.apply(this,e);return pe(),n}}));function we(e=!1){return function(t,n,o,r){let l=t[n];if(!e&&(o=st(o),l=st(l),!T(t)&&at(l)&&!at(o)))return l.value=o,!0;const s=T(t)&&B(n)?Number(n)!0,deleteProperty:(e,t)=>!0},$e=$({},Ce,{get:be,set:we(!0)});$({},Se,{get:xe});const Ee=e=>R(e)?et(e):e,Oe=e=>R(e)?tt(e):e,Le=e=>e,Te=e=>Reflect.getPrototypeOf(e);function Pe(e,t,n=!1,o=!1){const r=st(e=e.__v_raw),l=st(t);t!==l&&!n&&fe(r,0,t),!n&&fe(r,0,l);const{has:s}=Te(r),i=o?Le:n?Oe:Ee;return s.call(r,t)?i(e.get(t)):s.call(r,l)?i(e.get(l)):void 0}function Me(e,t=!1){const n=this.__v_raw,o=st(n),r=st(e);return e!==r&&!t&&fe(o,0,e),!t&&fe(o,0,r),e===r?n.has(e):n.has(e)||n.has(r)}function je(e,t=!1){return e=e.__v_raw,!t&&fe(st(e),0,oe),Reflect.get(e,"size",e)}function Ae(e){e=st(e);const t=st(this);return Te(t).has.call(t,e)||(t.add(e),he(t,"add",e,e)),this}function Ie(e,t){t=st(t);const n=st(this),{has:o,get:r}=Te(n);let l=o.call(n,e);l||(e=st(e),l=o.call(n,e));const s=r.call(n,e);return n.set(e,t),l?Y(t,s)&&he(n,"set",e,t):he(n,"add",e,t),this}function Re(e){const t=st(this),{has:n,get:o}=Te(t);let r=n.call(t,e);r||(e=st(e),r=n.call(t,e)),o&&o.call(t,e);const l=t.delete(e);return r&&he(t,"delete",e,void 0),l}function Fe(){const e=st(this),t=0!==e.size,n=e.clear();return t&&he(e,"clear",void 0,void 0),n}function Ne(e,t){return function(n,o){const r=this,l=r.__v_raw,s=st(l),i=t?Le:e?Oe:Ee;return!e&&fe(s,0,oe),l.forEach(((e,t)=>n.call(o,i(e),i(t),r)))}}function Ue(e,t,n){return function(...o){const r=this.__v_raw,l=st(r),s=P(l),i="entries"===e||e===Symbol.iterator&&s,c="keys"===e&&s,a=r[e](...o),u=n?Le:t?Oe:Ee;return!t&&fe(l,0,c?re:oe),{next(){const{value:e,done:t}=a.next();return t?{value:e,done:t}:{value:i?[u(e[0]),u(e[1])]:u(e),done:t}},[Symbol.iterator](){return this}}}}function Ve(e){return function(...t){return"delete"!==e&&this}}const Be={get(e){return Pe(this,e)},get size(){return je(this)},has:Me,add:Ae,set:Ie,delete:Re,clear:Fe,forEach:Ne(!1,!1)},ze={get(e){return Pe(this,e,!1,!0)},get size(){return je(this)},has:Me,add:Ae,set:Ie,delete:Re,clear:Fe,forEach:Ne(!1,!0)},De={get(e){return Pe(this,e,!0)},get size(){return je(this,!0)},has(e){return Me.call(this,e,!0)},add:Ve("add"),set:Ve("set"),delete:Ve("delete"),clear:Ve("clear"),forEach:Ne(!0,!1)},He={get(e){return Pe(this,e,!0,!0)},get size(){return je(this,!0)},has(e){return Me.call(this,e,!0)},add:Ve("add"),set:Ve("set"),delete:Ve("delete"),clear:Ve("clear"),forEach:Ne(!0,!0)};function We(e,t){const n=t?e?He:ze:e?De:Be;return(t,o,r)=>"__v_isReactive"===o?!e:"__v_isReadonly"===o?e:"__v_raw"===o?t:Reflect.get(L(n,o)&&o in t?n:t,o,r)}["keys","values","entries",Symbol.iterator].forEach((e=>{Be[e]=Ue(e,!1,!1),De[e]=Ue(e,!0,!1),ze[e]=Ue(e,!1,!0),He[e]=Ue(e,!0,!0)}));const qe={get:We(!1,!1)},Ke={get:We(!1,!0)},Ge={get:We(!0,!1)},Je=new WeakMap,Ye=new WeakMap,Qe=new WeakMap,Xe=new WeakMap;function Ze(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>U(e).slice(8,-1))(e))}function et(e){return e&&e.__v_isReadonly?e:nt(e,!1,Ce,qe,Je)}function tt(e){return nt(e,!0,Se,Ge,Qe)}function nt(e,t,n,o,r){if(!R(e))return e;if(e.__v_raw&&(!t||!e.__v_isReactive))return e;const l=r.get(e);if(l)return l;const s=Ze(e);if(0===s)return e;const i=new Proxy(e,2===s?o:n);return r.set(e,i),i}function ot(e){return rt(e)?ot(e.__v_raw):!(!e||!e.__v_isReactive)}function rt(e){return!(!e||!e.__v_isReadonly)}function lt(e){return ot(e)||rt(e)}function st(e){return e&&st(e.__v_raw)||e}function it(e){return X(e,"__v_skip",!0),e}const ct=e=>R(e)?et(e):e;function at(e){return Boolean(e&&!0===e.__v_isRef)}function ut(e){return function(e,t=!1){if(at(e))return e;return new dt(e,t)}(e)}class dt{constructor(e,t=!1){this._rawValue=e,this._shallow=t,this.__v_isRef=!0,this._value=t?e:ct(e)}get value(){return fe(st(this),0,"value"),this._value}set value(e){Y(st(e),this._rawValue)&&(this._rawValue=e,this._value=this._shallow?e:ct(e),he(st(this),"set","value",e))}}function pt(e){return at(e)?e.value:e}const ft={get:(e,t,n)=>pt(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const r=e[t];return at(r)&&!at(n)?(r.value=n,!0):Reflect.set(e,t,n,o)}};function ht(e){return ot(e)?e:new Proxy(e,ft)}function vt(e){const t=T(e)?new Array(e.length):{};for(const n in e)t[n]=gt(e,n);return t}class mt{constructor(e,t){this._object=e,this._key=t,this.__v_isRef=!0}get value(){return this._object[this._key]}set value(e){this._object[this._key]=e}}function gt(e,t){return at(e[t])?e[t]:new mt(e,t)}class bt{constructor(e,t,n){this._setter=t,this._dirty=!0,this.__v_isRef=!0,this.effect=le(e,{lazy:!0,scheduler:()=>{this._dirty||(this._dirty=!0,he(st(this),"set","value"))}}),this.__v_isReadonly=n}get value(){const e=st(this);return e._dirty&&(e._value=this.effect(),e._dirty=!1),fe(e,0,"value"),e._value}set value(e){this._setter(e)}}function yt(e,t,n,o){let r;try{r=o?e(...o):e()}catch(l){_t(l,t,n)}return r}function xt(e,t,n,o){if(j(e)){const r=yt(e,t,n,o);return r&&F(r)&&r.catch((e=>{_t(e,t,n)})),r}const r=[];for(let l=0;l>>1;Bt(Ct[e])-1?Ct.splice(t,0,e):Ct.push(e),Ft()}}function Ft(){kt||wt||(wt=!0,jt=Mt.then(zt))}function Nt(e,t,n,o){T(e)?n.push(...e):t&&t.includes(e,e.allowRecurse?o+1:o)||n.push(e),Ft()}function Ut(e,t=null){if($t.length){for(At=t,Et=[...new Set($t)],$t.length=0,Ot=0;OtBt(e)-Bt(t))),Pt=0;Ptnull==e.id?1/0:e.id;function zt(e){wt=!1,kt=!0,Ut(e),Ct.sort(((e,t)=>Bt(e)-Bt(t)));try{for(St=0;Ste.trim())):t&&(r=n.map(Z))}let i,c=o[i=J(t)]||o[i=J(W(t))];!c&&l&&(c=o[i=J(K(t))]),c&&xt(c,e,6,r);const a=o[i+"Once"];if(a){if(e.emitted){if(e.emitted[i])return}else(e.emitted={})[i]=!0;xt(a,e,6,r)}}function Ht(e,t,n=!1){if(!t.deopt&&void 0!==e.__emits)return e.__emits;const o=e.emits;let r={},l=!1;if(!j(e)){const o=e=>{const n=Ht(e,t,!0);n&&(l=!0,$(r,n))};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}return o||l?(T(o)?o.forEach((e=>r[e]=null)):$(r,o),e.__emits=r):e.__emits=null}function Wt(e,t){return!(!e||!C(t))&&(t=t.slice(2).replace(/Once$/,""),L(e,t[0].toLowerCase()+t.slice(1))||L(e,K(t))||L(e,t))}let qt=0;const Kt=e=>qt+=e;function Gt(e,t,n={},o,r){let l=e[t];qt++,mo();const s=l&&Jt(l(n)),i=bo(ao,{key:n.key||`_${t}`},s||(o?o():[]),s&&1===e._?64:-2);return!r&&i.scopeId&&(i.slotScopeIds=[i.scopeId+"-s"]),qt--,i}function Jt(e){return e.some((e=>!yo(e)||e.type!==po&&!(e.type===ao&&!Jt(e.children))))?e:null}let Yt=null,Qt=null;function Xt(e){const t=Yt;return Yt=e,Qt=e&&e.type.__scopeId||null,t}function Zt(e){Qt=e}function en(){Qt=null}const tn=e=>nn;function nn(e,t=Yt){if(!t)return e;const n=(...n)=>{qt||mo(!0);const o=Xt(t),r=e(...n);return Xt(o),qt||go(),r};return n._c=!0,n}function on(e){const{type:t,vnode:n,proxy:o,withProxy:r,props:l,propsOptions:[s],slots:i,attrs:c,emit:a,render:u,renderCache:d,data:p,setupState:f,ctx:h}=e;let v;const m=Xt(e);try{let e;if(4&n.shapeFlag){const t=r||o;v=Lo(u.call(t,t,d,l,f,p,h)),e=c}else{const n=t;0,v=Lo(n.length>1?n(l,{attrs:c,slots:i,emit:a}):n(l,null)),e=t.props?c:ln(c)}let m=v;if(!1!==t.inheritAttrs&&e){const t=Object.keys(e),{shapeFlag:n}=m;t.length&&(1&n||6&n)&&(s&&t.some(S)&&(e=sn(e,s)),m=So(m,e))}n.dirs&&(m.dirs=m.dirs?m.dirs.concat(n.dirs):n.dirs),n.transition&&(m.transition=n.transition),v=m}catch(g){ho.length=0,_t(g,e,1),v=Co(po)}return Xt(m),v}function rn(e){let t;for(let n=0;n{let t;for(const n in e)("class"===n||"style"===n||C(n))&&((t||(t={}))[n]=e[n]);return t},sn=(e,t)=>{const n={};for(const o in e)S(o)&&o.slice(9)in t||(n[o]=e[o]);return n};function cn(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let r=0;r{s=!0;const[n,o]=hn(e,t,!0);$(r,n),o&&l.push(...o)};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}if(!o&&!s)return e.__props=x;if(T(o))for(let i=0;i-1,n[1]=o<0||t-1||L(n,"default"))&&l.push(e)}}}return e.__props=[r,l]}function vn(e){return"$"!==e[0]}function mn(e){const t=e&&e.toString().match(/^\s*function (\w+)/);return t?t[1]:""}function gn(e,t){return mn(e)===mn(t)}function bn(e,t){return T(t)?t.findIndex((t=>gn(t,e))):j(t)&&gn(t,e)?0:-1}function yn(e,t,n=Go,o=!1){if(n){const r=n[e]||(n[e]=[]),l=t.__weh||(t.__weh=(...o)=>{if(n.isUnmounted)return;de(),Yo(n);const r=xt(t,n,e,o);return Yo(null),pe(),r});return o?r.unshift(l):r.push(l),l}}const xn=e=>(t,n=Go)=>!Xo&&yn(e,t,n),_n=xn("bm"),kn=xn("m"),wn=xn("bu"),Cn=xn("u"),Sn=xn("bum"),$n=xn("um"),En=xn("rtg"),On=xn("rtc");const Ln={};function Tn(e,t,n){return Pn(e,t,n)}function Pn(e,t,{immediate:n,deep:o,flush:r,onTrack:l,onTrigger:s}=y,i=Go){let c,a,u=!1;if(at(e)?(c=()=>e.value,u=!!e._shallow):ot(e)?(c=()=>e,o=!0):c=T(e)?()=>e.map((e=>at(e)?e.value:ot(e)?jn(e):j(e)?yt(e,i,2,[i&&i.proxy]):void 0)):j(e)?t?()=>yt(e,i,2,[i&&i.proxy]):()=>{if(!i||!i.isUnmounted)return a&&a(),xt(e,i,3,[d])}:_,t&&o){const e=c;c=()=>jn(e())}let d=e=>{a=v.options.onStop=()=>{yt(e,i,4)}},p=T(e)?[]:Ln;const f=()=>{if(v.active)if(t){const e=v();(o||u||Y(e,p))&&(a&&a(),xt(t,i,3,[e,p===Ln?void 0:p,d]),p=e)}else v()};let h;f.allowRecurse=!!t,h="sync"===r?f:"post"===r?()=>to(f,i&&i.suspense):()=>{!i||i.isMounted?function(e){Nt(e,Et,$t,Ot)}(f):f()};const v=le(c,{lazy:!0,onTrack:l,onTrigger:s,scheduler:h});return tr(v,i),t?n?f():p=v():"post"===r?to(v,i&&i.suspense):v(),()=>{se(v),i&&E(i.effects,v)}}function Mn(e,t,n){const o=this.proxy;return Pn(A(e)?()=>o[e]:e.bind(o),t.bind(o),n,this)}function jn(e,t=new Set){if(!R(e)||t.has(e))return e;if(t.add(e),at(e))jn(e.value,t);else if(T(e))for(let n=0;n{jn(e,t)}));else for(const n in e)jn(e[n],t);return e}const An=e=>e.type.__isKeepAlive;function In(e,t,n=Go){const o=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}e()});if(yn(t,o,n),n){let e=n.parent;for(;e&&e.parent;)An(e.parent.vnode)&&Rn(o,t,n,e),e=e.parent}}function Rn(e,t,n,o){const r=yn(t,e,o,!0);$n((()=>{E(o[t],r)}),n)}const Fn=e=>"_"===e[0]||"$stable"===e,Nn=e=>T(e)?e.map(Lo):[Lo(e)],Un=(e,t,n)=>nn((e=>Nn(t(e))),n),Vn=(e,t)=>{const n=e._ctx;for(const o in e){if(Fn(o))continue;const r=e[o];if(j(r))t[o]=Un(0,r,n);else if(null!=r){const e=Nn(r);t[o]=()=>e}}},Bn=(e,t)=>{const n=Nn(t);e.slots.default=()=>n};function zn(e,t){if(null===Yt)return e;const n=Yt.proxy,o=e.dirs||(e.dirs=[]);for(let r=0;r(l.has(e)||(e&&j(e.install)?(l.add(e),e.install(i,...t)):j(e)&&(l.add(e),e(i,...t))),i),mixin:e=>(r.mixins.includes(e)||(r.mixins.push(e),(e.props||e.emits)&&(r.deopt=!0)),i),component:(e,t)=>t?(r.components[e]=t,i):r.components[e],directive:(e,t)=>t?(r.directives[e]=t,i):r.directives[e],mount(l,c,a){if(!s){const u=Co(n,o);return u.appContext=r,c&&t?t(u,l):e(u,l,a),s=!0,i._container=l,l.__vue_app__=i,u.component.proxy}},unmount(){s&&(e(null,i._container),delete i._container.__vue_app__)},provide:(e,t)=>(r.provides[e]=t,i)};return i}}let Kn=!1;const Gn=e=>/svg/.test(e.namespaceURI)&&"foreignObject"!==e.tagName,Jn=e=>8===e.nodeType;function Yn(e){const{mt:t,p:n,o:{patchProp:o,nextSibling:r,parentNode:l,remove:s,insert:i,createComment:c}}=e,a=(n,o,s,i,c,v=!1)=>{const m=Jn(n)&&"["===n.data,g=()=>f(n,o,s,i,c,m),{type:b,ref:y,shapeFlag:x}=o,_=n.nodeType;o.el=n;let k=null;switch(b){case uo:3!==_?k=g():(n.data!==o.children&&(Kn=!0,n.data=o.children),k=r(n));break;case po:k=8!==_||m?g():r(n);break;case fo:if(1===_){k=n;const e=!o.children.length;for(let t=0;t{t(o,e,null,s,i,Gn(e),v)},u=o.type.__asyncLoader;u?u().then(a):a(),k=m?h(n):r(n)}else 64&x?k=8!==_?g():o.type.hydrate(n,o,s,i,c,v,e,d):128&x&&(k=o.type.hydrate(n,o,s,i,Gn(l(n)),c,v,e,a))}return null!=y&&no(y,null,i,o),k},u=(e,t,n,r,l,i)=>{i=i||!!t.dynamicChildren;const{props:c,patchFlag:a,shapeFlag:u,dirs:p}=t;if(-1!==a){if(p&&Dn(t,null,n,"created"),c)if(!i||16&a||32&a)for(const t in c)!z(t)&&C(t)&&o(e,t,null,c[t]);else c.onClick&&o(e,"onClick",null,c.onClick);let f;if((f=c&&c.onVnodeBeforeMount)&&ro(f,n,t),p&&Dn(t,null,n,"beforeMount"),((f=c&&c.onVnodeMounted)||p)&&un((()=>{f&&ro(f,n,t),p&&Dn(t,null,n,"mounted")}),r),16&u&&(!c||!c.innerHTML&&!c.textContent)){let o=d(e.firstChild,t,e,n,r,l,i);for(;o;){Kn=!0;const e=o;o=o.nextSibling,s(e)}}else 8&u&&e.textContent!==t.children&&(Kn=!0,e.textContent=t.children)}return e.nextSibling},d=(e,t,o,r,l,s,i)=>{i=i||!!t.dynamicChildren;const c=t.children,u=c.length;for(let d=0;d{const{slotScopeIds:u}=t;u&&(s=s?s.concat(u):u);const p=l(e),f=d(r(e),t,p,n,o,s,a);return f&&Jn(f)&&"]"===f.data?r(t.anchor=f):(Kn=!0,i(t.anchor=c("]"),p,f),f)},f=(e,t,o,i,c,a)=>{if(Kn=!0,t.el=null,a){const t=h(e);for(;;){const n=r(e);if(!n||n===t)break;s(n)}}const u=r(e),d=l(e);return s(e),n(null,t,d,u,o,i,Gn(d),c),u},h=e=>{let t=0;for(;e;)if((e=r(e))&&Jn(e)&&("["===e.data&&t++,"]"===e.data)){if(0===t)return r(e);t--}return e};return[(e,t)=>{Kn=!1,a(t.firstChild,e,null,null,null),Vt(),Kn&&console.error("Hydration completed but contains mismatches.")},a]}function Qn(e){return j(e)?{setup:e,name:e.name}:e}function Xn(e){j(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:o,delay:r=200,timeout:l,suspensible:s=!0,onError:i}=e;let c,a=null,u=0;const d=()=>{let e;return a||(e=a=t().catch((e=>{if(e=e instanceof Error?e:new Error(String(e)),i)return new Promise(((t,n)=>{i(e,(()=>t((u++,a=null,d()))),(()=>n(e)),u+1)}));throw e})).then((t=>e!==a&&a?a:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),c=t,t))))};return Qn({__asyncLoader:d,name:"AsyncComponentWrapper",setup(){const e=Go;if(c)return()=>Zn(c,e);const t=t=>{a=null,_t(t,e,13,!o)};if(s&&e.suspense)return d().then((t=>()=>Zn(t,e))).catch((e=>(t(e),()=>o?Co(o,{error:e}):null)));const i=ut(!1),u=ut(),p=ut(!!r);return r&&setTimeout((()=>{p.value=!1}),r),null!=l&&setTimeout((()=>{if(!i.value&&!u.value){const e=new Error(`Async component timed out after ${l}ms.`);t(e),u.value=e}}),l),d().then((()=>{i.value=!0})).catch((e=>{t(e),u.value=e})),()=>i.value&&c?Zn(c,e):u.value&&o?Co(o,{error:u.value}):n&&!p.value?Co(n):void 0}})}function Zn(e,{vnode:{ref:t,props:n,children:o}}){const r=Co(e,n,o);return r.ref=t,r}const eo={scheduler:Rt,allowRecurse:!0},to=un,no=(e,t,n,o)=>{if(T(e))return void e.forEach(((e,r)=>no(e,t&&(T(t)?t[r]:t),n,o)));let r;if(o){if(o.type.__asyncLoader)return;r=4&o.shapeFlag?o.component.exposed||o.component.proxy:o.el}else r=null;const{i:l,r:s}=e,i=t&&t.r,c=l.refs===y?l.refs={}:l.refs,a=l.setupState;if(null!=i&&i!==s&&(A(i)?(c[i]=null,L(a,i)&&(a[i]=null)):at(i)&&(i.value=null)),A(s)){const e=()=>{c[s]=r,L(a,s)&&(a[s]=r)};r?(e.id=-1,to(e,n)):e()}else if(at(s)){const e=()=>{s.value=r};r?(e.id=-1,to(e,n)):e()}else j(s)&&yt(s,l,12,[r,c])};function oo(e){return function(e,t){const{insert:n,remove:o,patchProp:r,forcePatchProp:l,createElement:s,createText:i,createComment:c,setText:a,setElementText:u,parentNode:d,nextSibling:p,setScopeId:f=_,cloneNode:h,insertStaticContent:v}=e,m=(e,t,n,o=null,r=null,l=null,s=!1,i=null,c=!1)=>{e&&!xo(e,t)&&(o=te(e),G(e,r,l,!0),e=null),-2===t.patchFlag&&(c=!1,t.dynamicChildren=null);const{type:a,ref:u,shapeFlag:d}=t;switch(a){case uo:g(e,t,n,o);break;case po:b(e,t,n,o);break;case fo:null==e&&k(t,n,o,s);break;case ao:A(e,t,n,o,r,l,s,i,c);break;default:1&d?S(e,t,n,o,r,l,s,i,c):6&d?I(e,t,n,o,r,l,s,i,c):(64&d||128&d)&&a.process(e,t,n,o,r,l,s,i,c,oe)}null!=u&&r&&no(u,e&&e.ref,l,t)},g=(e,t,o,r)=>{if(null==e)n(t.el=i(t.children),o,r);else{const n=t.el=e.el;t.children!==e.children&&a(n,t.children)}},b=(e,t,o,r)=>{null==e?n(t.el=c(t.children||""),o,r):t.el=e.el},k=(e,t,n,o)=>{[e.el,e.anchor]=v(e.children,t,n,o)},w=({el:e,anchor:t},o,r)=>{let l;for(;e&&e!==t;)l=p(e),n(e,o,r),e=l;n(t,o,r)},C=({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=p(e),o(e),e=n;o(t)},S=(e,t,n,o,r,l,s,i,c)=>{s=s||"svg"===t.type,null==e?E(t,n,o,r,l,s,i,c):P(e,t,r,l,s,i,c)},E=(e,t,o,l,i,c,a,d)=>{let p,f;const{type:v,props:m,shapeFlag:g,transition:b,patchFlag:y,dirs:x}=e;if(e.el&&void 0!==h&&-1===y)p=e.el=h(e.el);else{if(p=e.el=s(e.type,c,m&&m.is,m),8&g?u(p,e.children):16&g&&T(e.children,p,null,l,i,c&&"foreignObject"!==v,a,d||!!e.dynamicChildren),x&&Dn(e,null,l,"created"),m){for(const t in m)z(t)||r(p,t,null,m[t],c,e.children,l,i,ee);(f=m.onVnodeBeforeMount)&&ro(f,l,e)}O(p,e,e.scopeId,a,l)}x&&Dn(e,null,l,"beforeMount");const _=(!i||i&&!i.pendingBranch)&&b&&!b.persisted;_&&b.beforeEnter(p),n(p,t,o),((f=m&&m.onVnodeMounted)||_||x)&&to((()=>{f&&ro(f,l,e),_&&b.enter(p),x&&Dn(e,null,l,"mounted")}),i)},O=(e,t,n,o,r)=>{if(n&&f(e,n),o)for(let l=0;l{for(let a=c;a{const a=t.el=e.el;let{patchFlag:d,dynamicChildren:p,dirs:f}=t;d|=16&e.patchFlag;const h=e.props||y,v=t.props||y;let m;if((m=v.onVnodeBeforeUpdate)&&ro(m,n,t,e),f&&Dn(t,e,n,"beforeUpdate"),d>0){if(16&d)j(a,t,h,v,n,o,s);else if(2&d&&h.class!==v.class&&r(a,"class",null,v.class,s),4&d&&r(a,"style",h.style,v.style,s),8&d){const i=t.dynamicProps;for(let t=0;t{m&&ro(m,n,t,e),f&&Dn(t,e,n,"updated")}),o)},M=(e,t,n,o,r,l,s)=>{for(let i=0;i{if(n!==o){for(const a in o){if(z(a))continue;const u=o[a],d=n[a];(u!==d||l&&l(e,a))&&r(e,a,d,u,c,t.children,s,i,ee)}if(n!==y)for(const l in n)z(l)||l in o||r(e,l,n[l],null,c,t.children,s,i,ee)}},A=(e,t,o,r,l,s,c,a,u)=>{const d=t.el=e?e.el:i(""),p=t.anchor=e?e.anchor:i("");let{patchFlag:f,dynamicChildren:h,slotScopeIds:v}=t;f>0&&(u=!0),v&&(a=a?a.concat(v):v),null==e?(n(d,o,r),n(p,o,r),T(t.children,o,p,l,s,c,a,u)):f>0&&64&f&&h&&e.dynamicChildren?(M(e.dynamicChildren,h,o,l,s,c,a),(null!=t.key||l&&t===l.subTree)&&lo(e,t,!0)):B(e,t,o,p,l,s,c,a,u)},I=(e,t,n,o,r,l,s,i,c)=>{t.slotScopeIds=i,null==e?512&t.shapeFlag?r.ctx.activate(t,n,o,s,c):R(t,n,o,r,l,s,c):N(e,t,c)},R=(e,t,n,o,r,l,s)=>{const i=e.component=function(e,t,n){const o=e.type,r=(t?t.appContext:e.appContext)||qo,l={uid:Ko++,vnode:e,type:o,parent:t,appContext:r,root:null,next:null,subTree:null,update:null,render:null,proxy:null,exposed:null,withProxy:null,effects:null,provides:t?t.provides:Object.create(r.provides),accessCache:null,renderCache:[],components:null,directives:null,propsOptions:hn(o,r),emitsOptions:Ht(o,r),emit:null,emitted:null,propsDefaults:y,ctx:y,data:y,props:y,attrs:y,slots:y,refs:y,setupState:y,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null};return l.ctx={_:l},l.root=t?t.root:l,l.emit=Dt.bind(null,l),l}(e,o,r);if(An(e)&&(i.ctx.renderer=oe),function(e,t=!1){Xo=t;const{props:n,children:o}=e.vnode,r=Qo(e);dn(e,n,r,t),((e,t)=>{if(32&e.vnode.shapeFlag){const n=t._;n?(e.slots=t,X(t,"_",n)):Vn(t,e.slots={})}else e.slots={},t&&Bn(e,t);X(e.slots,_o,1)})(e,o);const l=r?function(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Ho);const{setup:o}=n;if(o){const n=e.setupContext=o.length>1?function(e){const t=t=>{e.exposed=ht(t)};return{attrs:e.attrs,slots:e.slots,emit:e.emit,expose:t}}(e):null;Go=e,de();const r=yt(o,e,0,[e.props,n]);if(pe(),Go=null,F(r)){if(t)return r.then((t=>{Zo(e,t)})).catch((t=>{_t(t,e,0)}));e.asyncDep=r}else Zo(e,r)}else er(e)}(e,t):void 0;Xo=!1}(i),i.asyncDep){if(r&&r.registerDep(i,U),!e.el){const e=i.subTree=Co(po);b(null,e,t,n)}}else U(i,e,t,n,r,l,s)},N=(e,t,n)=>{const o=t.component=e.component;if(function(e,t,n){const{props:o,children:r,component:l}=e,{props:s,children:i,patchFlag:c}=t,a=l.emitsOptions;if(t.dirs||t.transition)return!0;if(!(n&&c>=0))return!(!r&&!i||i&&i.$stable)||o!==s&&(o?!s||cn(o,s,a):!!s);if(1024&c)return!0;if(16&c)return o?cn(o,s,a):!!s;if(8&c){const e=t.dynamicProps;for(let t=0;tSt&&Ct.splice(t,1)}(o.update),o.update()}else t.component=e.component,t.el=e.el,o.vnode=t},U=(e,t,n,o,r,l,s)=>{e.update=le((function(){if(e.isMounted){let t,{next:n,bu:o,u:i,parent:c,vnode:a}=e,u=n;n?(n.el=a.el,V(e,n,s)):n=a,o&&Q(o),(t=n.props&&n.props.onVnodeBeforeUpdate)&&ro(t,c,n,a);const p=on(e),f=e.subTree;e.subTree=p,m(f,p,d(f.el),te(f),e,r,l),n.el=p.el,null===u&&function({vnode:e,parent:t},n){for(;t&&t.subTree===e;)(e=t.vnode).el=n,t=t.parent}(e,p.el),i&&to(i,r),(t=n.props&&n.props.onVnodeUpdated)&&to((()=>{ro(t,c,n,a)}),r)}else{let s;const{el:i,props:c}=t,{bm:a,m:u,parent:d}=e;a&&Q(a),(s=c&&c.onVnodeBeforeMount)&&ro(s,d,t);const p=e.subTree=on(e);if(i&&ie?ie(t.el,p,e,r,null):(m(null,p,n,o,e,r,l),t.el=p.el),u&&to(u,r),s=c&&c.onVnodeMounted){const e=t;to((()=>{ro(s,d,e)}),r)}const{a:f}=e;f&&256&t.shapeFlag&&to(f,r),e.isMounted=!0,t=n=o=null}}),eo)},V=(e,t,n)=>{t.component=e;const o=e.vnode.props;e.vnode=t,e.next=null,function(e,t,n,o){const{props:r,attrs:l,vnode:{patchFlag:s}}=e,i=st(r),[c]=e.propsOptions;if(!(o||s>0)||16&s){let o;pn(e,t,r,l);for(const l in i)t&&(L(t,l)||(o=K(l))!==l&&L(t,o))||(c?!n||void 0===n[l]&&void 0===n[o]||(r[l]=fn(c,t||y,l,void 0,e)):delete r[l]);if(l!==i)for(const e in l)t&&L(t,e)||delete l[e]}else if(8&s){const n=e.vnode.dynamicProps;for(let o=0;o{const{vnode:o,slots:r}=e;let l=!0,s=y;if(32&o.shapeFlag){const e=t._;e?n&&1===e?l=!1:($(r,t),n||1!==e||delete r._):(l=!t.$stable,Vn(t,r)),s=t}else t&&(Bn(e,t),s={default:1});if(l)for(const i in r)Fn(i)||i in s||delete r[i]})(e,t.children,n),de(),Ut(void 0,e.update),pe()},B=(e,t,n,o,r,l,s,i,c=!1)=>{const a=e&&e.children,d=e?e.shapeFlag:0,p=t.children,{patchFlag:f,shapeFlag:h}=t;if(f>0){if(128&f)return void H(a,p,n,o,r,l,s,i,c);if(256&f)return void D(a,p,n,o,r,l,s,i,c)}8&h?(16&d&&ee(a,r,l),p!==a&&u(n,p)):16&d?16&h?H(a,p,n,o,r,l,s,i,c):ee(a,r,l,!0):(8&d&&u(n,""),16&h&&T(p,n,o,r,l,s,i,c))},D=(e,t,n,o,r,l,s,i,c)=>{t=t||x;const a=(e=e||x).length,u=t.length,d=Math.min(a,u);let p;for(p=0;pu?ee(e,r,l,!0,!1,d):T(t,n,o,r,l,s,i,c,d)},H=(e,t,n,o,r,l,s,i,c)=>{let a=0;const u=t.length;let d=e.length-1,p=u-1;for(;a<=d&&a<=p;){const o=e[a],u=t[a]=c?To(t[a]):Lo(t[a]);if(!xo(o,u))break;m(o,u,n,null,r,l,s,i,c),a++}for(;a<=d&&a<=p;){const o=e[d],a=t[p]=c?To(t[p]):Lo(t[p]);if(!xo(o,a))break;m(o,a,n,null,r,l,s,i,c),d--,p--}if(a>d){if(a<=p){const e=p+1,d=ep)for(;a<=d;)G(e[a],r,l,!0),a++;else{const f=a,h=a,v=new Map;for(a=h;a<=p;a++){const e=t[a]=c?To(t[a]):Lo(t[a]);null!=e.key&&v.set(e.key,a)}let g,b=0;const y=p-h+1;let _=!1,k=0;const w=new Array(y);for(a=0;a=y){G(o,r,l,!0);continue}let u;if(null!=o.key)u=v.get(o.key);else for(g=h;g<=p;g++)if(0===w[g-h]&&xo(o,t[g])){u=g;break}void 0===u?G(o,r,l,!0):(w[u-h]=a+1,u>=k?k=u:_=!0,m(o,t[u],n,null,r,l,s,i,c),b++)}const C=_?function(e){const t=e.slice(),n=[0];let o,r,l,s,i;const c=e.length;for(o=0;o0&&(t[o]=n[l-1]),n[l]=o)}}l=n.length,s=n[l-1];for(;l-- >0;)n[l]=s,s=t[s];return n}(w):x;for(g=C.length-1,a=y-1;a>=0;a--){const e=h+a,d=t[e],p=e+1{const{el:s,type:i,transition:c,children:a,shapeFlag:u}=e;if(6&u)return void q(e.component.subTree,t,o,r);if(128&u)return void e.suspense.move(t,o,r);if(64&u)return void i.move(e,t,o,oe);if(i===ao){n(s,t,o);for(let e=0;ec.enter(s)),l);else{const{leave:e,delayLeave:r,afterLeave:l}=c,i=()=>n(s,t,o),a=()=>{e(s,(()=>{i(),l&&l()}))};r?r(s,i,a):a()}else n(s,t,o)},G=(e,t,n,o=!1,r=!1)=>{const{type:l,props:s,ref:i,children:c,dynamicChildren:a,shapeFlag:u,patchFlag:d,dirs:p}=e;if(null!=i&&no(i,null,n,null),256&u)return void t.ctx.deactivate(e);const f=1&u&&p;let h;if((h=s&&s.onVnodeBeforeUnmount)&&ro(h,t,e),6&u)Z(e.component,n,o);else{if(128&u)return void e.suspense.unmount(n,o);f&&Dn(e,null,t,"beforeUnmount"),64&u?e.type.remove(e,t,n,r,oe,o):a&&(l!==ao||d>0&&64&d)?ee(a,t,n,!1,!0):(l===ao&&(128&d||256&d)||!r&&16&u)&&ee(c,t,n),o&&J(e)}((h=s&&s.onVnodeUnmounted)||f)&&to((()=>{h&&ro(h,t,e),f&&Dn(e,null,t,"unmounted")}),n)},J=e=>{const{type:t,el:n,anchor:r,transition:l}=e;if(t===ao)return void Y(n,r);if(t===fo)return void C(e);const s=()=>{o(n),l&&!l.persisted&&l.afterLeave&&l.afterLeave()};if(1&e.shapeFlag&&l&&!l.persisted){const{leave:t,delayLeave:o}=l,r=()=>t(n,s);o?o(e.el,s,r):r()}else s()},Y=(e,t)=>{let n;for(;e!==t;)n=p(e),o(e),e=n;o(t)},Z=(e,t,n)=>{const{bum:o,effects:r,update:l,subTree:s,um:i}=e;if(o&&Q(o),r)for(let c=0;c{e.isUnmounted=!0}),t),t&&t.pendingBranch&&!t.isUnmounted&&e.asyncDep&&!e.asyncResolved&&e.suspenseId===t.pendingId&&(t.deps--,0===t.deps&&t.resolve())},ee=(e,t,n,o=!1,r=!1,l=0)=>{for(let s=l;s6&e.shapeFlag?te(e.component.subTree):128&e.shapeFlag?e.suspense.next():p(e.anchor||e.el),ne=(e,t,n)=>{null==e?t._vnode&&G(t._vnode,null,null,!0):m(t._vnode||null,e,t,null,null,null,n),Vt(),t._vnode=e},oe={p:m,um:G,m:q,r:J,mt:R,mc:T,pc:B,pbc:M,n:te,o:e};let re,ie;t&&([re,ie]=t(oe));return{render:ne,hydrate:re,createApp:qn(ne,re)}}(e,Yn)}function ro(e,t,n,o=null){xt(e,t,7,[n,o])}function lo(e,t,n=!1){const o=e.children,r=t.children;if(T(o)&&T(r))for(let l=0;lnull!=e?e:null,wo=({ref:e})=>null!=e?A(e)||at(e)||j(e)?{i:Yt,r:e}:e:null,Co=function(e,t=null,n=null,o=0,r=null,l=!1){e&&e!==io||(e=po);if(yo(e)){const o=So(e,t,!0);return n&&Po(o,n),o}s=e,j(s)&&"__vccOpts"in s&&(e=e.__vccOpts);var s;if(t){(lt(t)||_o in t)&&(t=$({},t));let{class:e,style:n}=t;e&&!A(e)&&(t.class=m(e)),R(n)&&(lt(n)&&!T(n)&&(n=$({},n)),t.style=p(n))}const i=A(e)?1:(e=>e.__isSuspense)(e)?128:(e=>e.__isTeleport)(e)?64:R(e)?4:j(e)?2:0,c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ko(t),ref:t&&wo(t),scopeId:Qt,slotScopeIds:null,children:null,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:o,dynamicProps:r,dynamicChildren:null,appContext:null};if(Po(c,n),128&i){const{content:e,fallback:t}=function(e){const{shapeFlag:t,children:n}=e;let o,r;return 32&t?(o=an(n.default),r=an(n.fallback)):(o=an(n),r=Lo(null)),{content:o,fallback:r}}(c);c.ssContent=e,c.ssFallback=t}!l&&vo&&(o>0||6&i)&&32!==o&&vo.push(c);return c};function So(e,t,n=!1){const{props:o,ref:r,patchFlag:l,children:s}=e,i=t?Mo(o||{},t):o;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:i,key:i&&ko(i),ref:t&&t.ref?n&&r?T(r)?r.concat(wo(t)):[r,wo(t)]:wo(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:s,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ao?-1===l?16:16|l:l,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&So(e.ssContent),ssFallback:e.ssFallback&&So(e.ssFallback),el:e.el,anchor:e.anchor}}function $o(e=" ",t=0){return Co(uo,null,e,t)}function Eo(e,t){const n=Co(fo,null,e);return n.staticCount=t,n}function Oo(e="",t=!1){return t?(mo(),bo(po,null,e)):Co(po,null,e)}function Lo(e){return null==e||"boolean"==typeof e?Co(po):T(e)?Co(ao,null,e):"object"==typeof e?null===e.el?e:So(e):Co(uo,null,String(e))}function To(e){return null===e.el?e:So(e)}function Po(e,t){let n=0;const{shapeFlag:o}=e;if(null==t)t=null;else if(T(t))n=16;else if("object"==typeof t){if(1&o||64&o){const n=t.default;return void(n&&(n._c&&Kt(1),Po(e,n()),n._c&&Kt(-1)))}{n=32;const o=t._;o||_o in t?3===o&&Yt&&(1024&Yt.vnode.patchFlag?(t._=2,e.patchFlag|=1024):t._=1):t._ctx=Yt}}else j(t)?(t={default:t,_ctx:Yt},n=32):(t=String(t),64&o?(n=16,t=[$o(t)]):n=8);e.children=t,e.shapeFlag|=n}function Mo(...e){const t=$({},e[0]);for(let n=1;n1)return n&&j(t)?t():t}}let Ao=!0;function Io(e,t,n=[],o=[],r=[],l=!1){const{mixins:s,extends:i,data:c,computed:a,methods:u,watch:d,provide:p,inject:f,components:h,directives:v,beforeMount:m,mounted:g,beforeUpdate:b,updated:x,activated:k,deactivated:w,beforeDestroy:C,beforeUnmount:S,destroyed:E,unmounted:O,render:L,renderTracked:P,renderTriggered:M,errorCaptured:A,expose:I}=t,F=e.proxy,N=e.ctx,U=e.appContext.mixins;if(l&&L&&e.render===_&&(e.render=L),l||(Ao=!1,Ro("beforeCreate","bc",t,e,U),Ao=!0,No(e,U,n,o,r)),i&&Io(e,i,n,o,r,!0),s&&No(e,s,n,o,r),f)if(T(f))for(let y=0;yUo(e,t,F))),c&&Uo(e,c,F)),a)for(const y in a){const e=a[y],t=or({get:j(e)?e.bind(F,F):j(e.get)?e.get.bind(F,F):_,set:!j(e)&&j(e.set)?e.set.bind(F):_});Object.defineProperty(N,y,{enumerable:!0,configurable:!0,get:()=>t.value,set:e=>t.value=e})}var V;if(d&&o.push(d),!l&&o.length&&o.forEach((e=>{for(const t in e)Vo(e[t],N,F,t)})),p&&r.push(p),!l&&r.length&&r.forEach((e=>{const t=j(e)?e.call(F):e;Reflect.ownKeys(t).forEach((e=>{!function(e,t){if(Go){let n=Go.provides;const o=Go.parent&&Go.parent.provides;o===n&&(n=Go.provides=Object.create(o)),n[e]=t}}(e,t[e])}))})),l&&(h&&$(e.components||(e.components=$({},e.type.components)),h),v&&$(e.directives||(e.directives=$({},e.type.directives)),v)),l||Ro("created","c",t,e,U),m&&_n(m.bind(F)),g&&kn(g.bind(F)),b&&wn(b.bind(F)),x&&Cn(x.bind(F)),k&&In(k.bind(F),"a",V),w&&function(e,t){In(e,"da",t)}(w.bind(F)),A&&((e,t=Go)=>{yn("ec",e,t)})(A.bind(F)),P&&On(P.bind(F)),M&&En(M.bind(F)),S&&Sn(S.bind(F)),O&&$n(O.bind(F)),T(I)&&!l)if(I.length){const t=e.exposed||(e.exposed=ht({}));I.forEach((e=>{t[e]=gt(F,e)}))}else e.exposed||(e.exposed=y)}function Ro(e,t,n,o,r){for(let l=0;l{let t=e;for(let e=0;en[o];if(A(e)){const n=t[e];j(n)&&Tn(r,n)}else if(j(e))Tn(r,e.bind(n));else if(R(e))if(T(e))e.forEach((e=>Vo(e,t,n,o)));else{const o=j(e.handler)?e.handler.bind(n):t[e.handler];j(o)&&Tn(r,o,e)}}function Bo(e,t,n){const o=n.appContext.config.optionMergeStrategies,{mixins:r,extends:l}=t;l&&Bo(e,l,n),r&&r.forEach((t=>Bo(e,t,n)));for(const s in t)o&&L(o,s)?e[s]=o[s](e[s],t[s],n.proxy,s):e[s]=t[s]}const zo=e=>e?Qo(e)?e.exposed?e.exposed:e.proxy:zo(e.parent):null,Do=$(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>zo(e.parent),$root:e=>zo(e.root),$emit:e=>e.emit,$options:e=>function(e){const t=e.type,{__merged:n,mixins:o,extends:r}=t;if(n)return n;const l=e.appContext.mixins;if(!l.length&&!o&&!r)return t;const s={};return l.forEach((t=>Bo(s,t,e))),Bo(s,t,e),t.__merged=s}(e),$forceUpdate:e=>()=>Rt(e.update),$nextTick:e=>It.bind(e.proxy),$watch:e=>Mn.bind(e)}),Ho={get({_:e},t){const{ctx:n,setupState:o,data:r,props:l,accessCache:s,type:i,appContext:c}=e;if("__v_skip"===t)return!0;let a;if("$"!==t[0]){const i=s[t];if(void 0!==i)switch(i){case 0:return o[t];case 1:return r[t];case 3:return n[t];case 2:return l[t]}else{if(o!==y&&L(o,t))return s[t]=0,o[t];if(r!==y&&L(r,t))return s[t]=1,r[t];if((a=e.propsOptions[0])&&L(a,t))return s[t]=2,l[t];if(n!==y&&L(n,t))return s[t]=3,n[t];Ao&&(s[t]=4)}}const u=Do[t];let d,p;return u?("$attrs"===t&&fe(e,0,t),u(e)):(d=i.__cssModules)&&(d=d[t])?d:n!==y&&L(n,t)?(s[t]=3,n[t]):(p=c.config.globalProperties,L(p,t)?p[t]:void 0)},set({_:e},t,n){const{data:o,setupState:r,ctx:l}=e;if(r!==y&&L(r,t))r[t]=n;else if(o!==y&&L(o,t))o[t]=n;else if(L(e.props,t))return!1;return("$"!==t[0]||!(t.slice(1)in e))&&(l[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:r,propsOptions:l}},s){let i;return void 0!==n[s]||e!==y&&L(e,s)||t!==y&&L(t,s)||(i=l[0])&&L(i,s)||L(o,s)||L(Do,s)||L(r.config.globalProperties,s)}},Wo=$({},Ho,{get(e,t){if(t!==Symbol.unscopables)return Ho.get(e,t,e)},has:(e,t)=>"_"!==t[0]&&!u(t)}),qo=Hn();let Ko=0;let Go=null;const Jo=()=>Go||Yt,Yo=e=>{Go=e};function Qo(e){return 4&e.vnode.shapeFlag}let Xo=!1;function Zo(e,t,n){j(t)?e.render=t:R(t)&&(e.setupState=ht(t)),er(e)}function er(e,t){const n=e.type;e.render||(e.render=n.render||_,e.render._rc&&(e.withProxy=new Proxy(e.ctx,Wo))),Go=e,de(),Io(e,n),pe(),Go=null}function tr(e,t=Go){t&&(t.effects||(t.effects=[])).push(e)}function nr(e){return j(e)&&e.displayName||e.name}function or(e){const t=function(e){let t,n;return j(e)?(t=e,n=_):(t=e.get,n=e.set),new bt(t,n,j(e)||!e.set)}(e);return tr(t.effect),t}function rr(e,t,n){const o=arguments.length;return 2===o?R(t)&&!T(t)?yo(t)?Co(e,null,[t]):Co(e,t):Co(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):3===o&&yo(n)&&(n=[n]),Co(e,t,n))}function lr(e,t){let n;if(T(e)||A(e)){n=new Array(e.length);for(let o=0,r=e.length;o{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const r=t?cr.createElementNS(ir,e):cr.createElement(e,n?{is:n}:void 0);return"select"===e&&o&&null!=o.multiple&&r.setAttribute("multiple",o.multiple),r},createText:e=>cr.createTextNode(e),createComment:e=>cr.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>cr.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},cloneNode(e){const t=e.cloneNode(!0);return"_value"in e&&(t._value=e._value),t},insertStaticContent(e,t,n,o){const r=o?ur||(ur=cr.createElementNS(ir,"svg")):ar||(ar=cr.createElement("div"));r.innerHTML=e;const l=r.firstChild;let s=l,i=s;for(;s;)i=s,dr.insert(s,t,n),s=r.firstChild;return[l,i]}};const pr=/\s*!important$/;function fr(e,t,n){if(T(n))n.forEach((n=>fr(e,t,n)));else if(t.startsWith("--"))e.setProperty(t,n);else{const o=function(e,t){const n=vr[t];if(n)return n;let o=W(t);if("filter"!==o&&o in e)return vr[t]=o;o=G(o);for(let r=0;rdocument.createEvent("Event").timeStamp&&(gr=()=>performance.now());const e=navigator.userAgent.match(/firefox\/(\d+)/i);br=!!(e&&Number(e[1])<=53)}let yr=0;const xr=Promise.resolve(),_r=()=>{yr=0};function kr(e,t,n,o,r=null){const l=e._vei||(e._vei={}),s=l[t];if(o&&s)s.value=o;else{const[n,i]=function(e){let t;if(wr.test(e)){let n;for(t={};n=e.match(wr);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[K(e.slice(2)),t]}(t);if(o){!function(e,t,n,o){e.addEventListener(t,n,o)}(e,n,l[t]=function(e,t){const n=e=>{const o=e.timeStamp||gr();(br||o>=n.attached-1)&&xt(function(e,t){if(T(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map((e=>t=>!t._stopped&&e(t)))}return t}(e,n.value),t,5,[e])};return n.value=e,n.attached=(()=>yr||(xr.then(_r),yr=gr()))(),n}(o,r),i)}else s&&(!function(e,t,n,o){e.removeEventListener(t,n,o)}(e,n,s,i),l[t]=void 0)}}const wr=/(?:Once|Passive|Capture)$/;const Cr=/^on[a-z]/;const Sr={beforeMount(e,{value:t},{transition:n}){e._vod="none"===e.style.display?"":e.style.display,n&&t?n.beforeEnter(e):$r(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),$r(e,!0),o.enter(e)):o.leave(e,(()=>{$r(e,!1)})):$r(e,t))},beforeUnmount(e,{value:t}){$r(e,t)}};function $r(e,t){e.style.display=t?e._vod:"none"}const Er=$({patchProp:(e,t,n,o,r=!1,l,s,i,c)=>{switch(t){case"class":!function(e,t,n){if(null==t&&(t=""),n)e.setAttribute("class",t);else{const n=e._vtc;n&&(t=(t?[t,...n]:[...n]).join(" ")),e.className=t}}(e,o,r);break;case"style":!function(e,t,n){const o=e.style;if(n)if(A(n)){if(t!==n){const t=o.display;o.cssText=n,"_vod"in e&&(o.display=t)}}else{for(const e in n)fr(o,e,n[e]);if(t&&!A(t))for(const e in t)null==n[e]&&fr(o,e,"")}else e.removeAttribute("style")}(e,n,o);break;default:C(t)?S(t)||kr(e,t,0,o,s):function(e,t,n,o){if(o)return"innerHTML"===t||!!(t in e&&Cr.test(t)&&j(n));if("spellcheck"===t||"draggable"===t)return!1;if("form"===t)return!1;if("list"===t&&"INPUT"===e.tagName)return!1;if("type"===t&&"TEXTAREA"===e.tagName)return!1;if(Cr.test(t)&&A(n))return!1;return t in e}(e,t,o,r)?function(e,t,n,o,r,l,s){if("innerHTML"===t||"textContent"===t)return o&&s(o,r,l),void(e[t]=null==n?"":n);if("value"!==t||"PROGRESS"===e.tagName){if(""===n||null==n){const o=typeof e[t];if(""===n&&"boolean"===o)return void(e[t]=!0);if(null==n&&"string"===o)return e[t]="",void e.removeAttribute(t);if("number"===o)return e[t]=0,void e.removeAttribute(t)}try{e[t]=n}catch(i){}}else{e._value=n;const t=null==n?"":n;e.value!==t&&(e.value=t)}}(e,t,o,l,s,i,c):("true-value"===t?e._trueValue=o:"false-value"===t&&(e._falseValue=o),function(e,t,n,o){if(o&&t.startsWith("xlink:"))null==n?e.removeAttributeNS(mr,t.slice(6,t.length)):e.setAttributeNS(mr,t,n);else{const o=d(t);null==n||o&&!1===n?e.removeAttribute(t):e.setAttribute(t,o?"":n)}}(e,t,o,r))}},forcePatchProp:(e,t)=>"value"===t},dr);let Or,Lr=!1;const Tr=(...e)=>{const t=(Or=Lr?Or:oo(Er),Lr=!0,Or).createApp(...e),{mount:n}=t;return t.mount=e=>{const t=function(e){if(A(e)){return document.querySelector(e)}return e}(e);if(t)return n(t,!0,t instanceof SVGElement)},t};const Pr="undefined"!=typeof window;function Mr(e,t){const n=function(e,t){t.sort(((e,t)=>{const n=t.split("/").length-e.split("/").length;return 0!==n?n:t.length-e.length}));for(const n of t)if(e.startsWith(n))return n}(t,Object.keys(e));return n?e[n]:void 0}function jr(e,t){t=function(e,t){if(!Pr)return t;const n=e.base,o=n.endsWith("/")?n.slice(0,-1):n;return t.slice(o.length)}(e,t);const n=Mr(e.locales||{},t)||{},o=Mr(e.themeConfig&&e.themeConfig.locales||{},t)||{};return c(i(i({},e),n),{themeConfig:c(i(i({},e.themeConfig),o),{locales:{}}),lang:o.lang||e.lang,locales:{}})}function Ar(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function Ir(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t.endsWith("/")&&(t+="index"),Pr){const e="/";t=t.slice(e.length).replace(/\//g,"_")+".md";const n=__VP_HASH_MAP__[t.toLowerCase()];t=`${e}assets/${t}.${n}.js`}else t=`./${t.slice(1).replace(/\//g,"_")}.md.js`;return t}const Rr=Symbol();function Fr(){return function(){const e=jo(Rr);if(!e)throw new Error("useRouter() is called without provider.");return e}().route}function Nr(e,t,n=!1){const o=document.querySelector(".nav-bar").offsetHeight,r=e.classList.contains(".header-anchor")?e:document.querySelector(decodeURIComponent(t));if(r){const e=r.offsetTop-o-15;!n||Math.abs(e-window.scrollY)>window.innerHeight?window.scrollTo(0,e):window.scrollTo({left:0,top:e,behavior:"smooth"})}}const Ur=Qn({name:"VitePressContent",setup(){const e=Fr();return()=>e.component?rr(e.component):null}}),Vr=Qn({setup(e,{slots:t}){const n=ut(!1);return kn((()=>{n.value=!0})),()=>n.value&&t.default?t.default():null}});const Br=ut((zr='{"lang":"zh-CN","title":"Vben Admin","description":"一个开箱即用的前端框架","base":"/","head":[["meta",{"name":"author","content":"Vbenjs Team"}],["meta",{"name":"keywords","content":"vben, vitejs, vite, ant-design-vue, vue"}],["link",{"rel":"icon","type":"image/svg+xml","href":"/logo.svg"}],["meta",{"name":"viewport","content":"width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"}],["meta",{"name":"keywords","content":"vue vben admin docs"}],["link",{"rel":"icon","href":"/favicon.ico"}]],"themeConfig":{"repo":"vbenjs/vue-vben-admin","docsRepo":"vbenjs/vue-vben-admin-doc","logo":"/logo.png","docsBranch":"main","editLinks":true,"editLinkText":"为此页提供修改建议","nav":[{"text":"指南","link":"/guide/","items":[{"text":"指南","link":"/guide/introduction"},{"text":"深入","link":"/dep/icon"},{"text":"其他","link":"/other/faq"}]},{"text":"组件","link":"/components/","items":[{"text":"介绍","link":"/components/introduction"},{"text":"全局组件","link":"/components/glob/button"},{"text":"常用组件","link":"/components/basic"},{"text":"函数式组件","link":"/components/functional/context-menu"}]},{"text":"相关链接","items":[{"text":"完整版预览","link":"https://vben.vvbin.cn"},{"text":"完整版源码","link":"https://github.com/vbenjs/vue-vben-admin"},{"text":"精简版分支","link":"https://github.com/vbenjs/vue-vben-admin/tree/thin"},{"text":"文档源码","link":"https://github.com/vbenjs/vue-vben-admin-doc"},{"text":"更新日志","link":"https://github.com/vbenjs/vue-vben-admin/blob/main/CHANGELOG.md"}]},{"text":"社区","items":[{"text":"QQ频道【vben admin】","link":"https://pd.qq.com/s/ahgh62mni"},{"text":"KOOK(新)","link":"https://kaihei.co/6ZPFKi"},{"text":"Discord Chat","link":"https://discord.gg/VU62jTecad"}]},{"text":"vben3","items":[{"text":"仓库(beta-1)","link":"https://github.com/jinmao88/vben3"},{"text":"文档","link":"https://vbenjs.github.io/vben3-doc/"}]}],"sidebar":{"/components/":[{"text":"组件","children":[{"text":"前言","link":"/components/introduction"}]},{"text":"全局组件","children":[{"text":"Button","link":"/components/glob/button"}]},{"text":"常用组件","children":[{"text":"Basic","link":"/components/basic"},{"text":"Page","link":"/components/page"},{"text":"Icon","link":"/components/icon"},{"text":"Authority","link":"/components/auth"},{"text":"Form","link":"/components/form"},{"text":"Table","link":"/components/table"},{"text":"PopConfirmButton","link":"/components/pop-confirm-button"},{"text":"CollapseContainer","link":"/components/collapse-container"},{"text":"ScrollContainer","link":"/components/scroll-container"},{"text":"LazyContainer","link":"/components/lazy-container"},{"text":"CodeEditor","link":"/components/code-editor"},{"text":"JsonPreview","link":"/components/json-preview"},{"text":"CountDown","link":"/components/count-down"},{"text":"ClickOutSide","link":"/components/click-out-side"},{"text":"CountTo","link":"/components/count-to"},{"text":"Cropper","link":"/components/cropper"},{"text":"Description","link":"/components/desc"},{"text":"Drawer","link":"/components/drawer"},{"text":"Modal","link":"/components/modal"},{"text":"FlowChart","link":"/components/flow-chart"},{"text":"Upload","link":"/components/upload"},{"text":"Tree","link":"/components/tree"},{"text":"Excel","link":"/components/excel"},{"text":"Qrcode","link":"/components/qrcode"},{"text":"Markdown","link":"/components/markdown"},{"text":"Loading","link":"/components/loading"},{"text":"Tinymce","link":"/components/tinymce"},{"text":"Time","link":"/components/time"},{"text":"StrengthMeter","link":"/components/strength-meter"},{"text":"Verify","link":"/components/verify"},{"text":"Transition","link":"/components/transition"},{"text":"VirtualScroll","link":"/components/virtual-scroll"}]},{"text":"函数式组件","children":[{"text":"ContextMenu","link":"/components/functional/context-menu"},{"text":"Loading","link":"/components/functional/loading"},{"text":"Preview","link":"/components/functional/preview"}]}],"/":[{"text":"指南","children":[{"text":"介绍","link":"/guide/introduction"},{"text":"开始","link":"/guide/"},{"text":"项目配置","link":"/guide/settings"},{"text":"路由","link":"/guide/router"},{"text":"菜单","link":"/guide/menu"},{"text":"权限","link":"/guide/auth"},{"text":"Mock&联调","link":"/guide/mock"},{"text":"组件注册","link":"/guide/component"},{"text":"样式","link":"/guide/design"},{"text":"外部模块","link":"/guide/lib"},{"text":"构建&部署","link":"/guide/deploy"},{"text":"Electron","link":"/guide/electron"}]},{"text":"深入","children":[{"text":"跨域处理","link":"/dep/cors"},{"text":"图标","link":"/dep/icon"},{"text":"国际化","link":"/dep/i18n"},{"text":"项目规范","link":"/dep/lint"},{"text":"黑暗主题","link":"/dep/dark"}]},{"text":"其他","children":[{"text":"常见问题","link":"/other/faq"},{"text":"常见疑点","link":"/other/doubt"},{"text":"测试服务","link":"/other/server"},{"text":"相关项目","link":"/other/project"}]}]}},"locales":{},"customData":{}}',tt(JSON.parse(zr))));var zr;function Dr(){return Br}function Hr(e){const t=e||Fr();return or((()=>jr(Br.value,t.path)))}function Wr(e){const t=e||Fr();return or((()=>t.data))}function qr(e,t){const n=Array.from(document.querySelectorAll("meta"));let o=!0;const r=e=>{o?o=!1:(n.forEach((e=>document.head.removeChild(e))),n.length=0,e&&e.length&&e.forEach((e=>{const t=function([e,t,n]){const o=document.createElement(e);for(const r in t)o.setAttribute(r,t[r]);n&&(o.innerHTML=n);return o}(e);document.head.appendChild(t),n.push(t)})))};var l;Pn((()=>{const n=e.data,o=t.value,l=n&&n.title,s=n&&n.description,i=n&&n.frontmatter.head;var c;document.title=(l?l+" | ":"")+o.title,r([["meta",{charset:"utf-8"}],["meta",{name:"viewport",content:"width=device-width,initial-scale=1"}],["meta",{name:"description",content:s||o.description}],...o.head,...i&&(c=i,c.filter((e=>{return!("meta"===(t=e)[0]&&t[1]&&"description"===t[1].name);var t})))||[]])}),null,l)}let Kr;const Gr={};function Jr(){const e=Wr();return or((()=>e.value.frontmatter))}Zt("data-v-1be840de");const Yr=Co("p",{class:"title"},"Debug",-1),Qr={class:"block"},Xr={class:"block"},Zr={class:"block"};en();Qn({expose:[],setup(e){const t=ut(null),n=ut(!1);return Tn(n,(e=>{!1===e&&(t.value.scrollTop=0)})),(e,o)=>(mo(),bo("div",{class:["debug",{open:n.value}],ref:t,onClick:o[1]||(o[1]=e=>n.value=!n.value)},[Yr,Co("pre",Qr,"$page "+g(e.$page),1),Co("pre",Xr,"$siteByRoute "+g(e.$siteByRoute),1),Co("pre",Zr,"$site "+g(e.$site),1)],2))}}).__scopeId="data-v-1be840de";const el=/#.*$/,tl=/(index)?\.(md|html)$/,nl=/\/$/,ol=/^[a-z]+:/i;function rl(e){return Array.isArray(e)}function ll(e){return ol.test(e)}function sl(e){return decodeURI(e).replace(el,"").replace(tl,"")}function il(e){return/^\//.test(e)?e:`/${e}`}function cl(e){return e.replace(/(index)?(\.(md|html))?$/,"")||"/"}function al(e,t){if(function(e){return!1===e||"auto"===e||rl(e)}(e))return e;t=il(t);for(const n in e)if(t.startsWith(il(n)))return e[n];return"auto"}function ul(e){return e.reduce(((e,t)=>(t.link&&e.push({text:t.text,link:cl(t.link)}),function(e){return void 0!==e.children}(t)&&(e=[...e,...ul(t.children)]),e)),[])}const dl={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",width:"1.2em",height:"1.2em",preserveAspectRatio:"xMidYMid meet",viewBox:"0 0 24 24"},pl=Co("path",{d:"M5.883 18.653c-.3-.2-.558-.455-.86-.816a50.32 50.32 0 0 1-.466-.579c-.463-.575-.755-.84-1.057-.949a1 1 0 0 1 .676-1.883c.752.27 1.261.735 1.947 1.588c-.094-.117.34.427.433.539c.19.227.33.365.44.438c.204.137.587.196 1.15.14c.023-.382.094-.753.202-1.095C5.38 15.31 3.7 13.396 3.7 9.64c0-1.24.37-2.356 1.058-3.292c-.218-.894-.185-1.975.302-3.192a1 1 0 0 1 .63-.582c.081-.024.127-.035.208-.047c.803-.123 1.937.17 3.415 1.096A11.731 11.731 0 0 1 12 3.315c.912 0 1.818.104 2.684.308c1.477-.933 2.613-1.226 3.422-1.096c.085.013.157.03.218.05a1 1 0 0 1 .616.58c.487 1.216.52 2.297.302 3.19c.691.936 1.058 2.045 1.058 3.293c0 3.757-1.674 5.665-4.642 6.392c.125.415.19.879.19 1.38a300.492 300.492 0 0 1-.012 2.716a1 1 0 0 1-.019 1.958c-1.139.228-1.983-.532-1.983-1.525l.002-.446l.005-.705c.005-.708.007-1.338.007-1.998c0-.697-.183-1.152-.425-1.36c-.661-.57-.326-1.655.54-1.752c2.967-.333 4.337-1.482 4.337-4.66c0-.955-.312-1.744-.913-2.404a1 1 0 0 1-.19-1.045c.166-.414.237-.957.096-1.614l-.01.003c-.491.139-1.11.44-1.858.949a1 1 0 0 1-.833.135A9.626 9.626 0 0 0 12 5.315c-.89 0-1.772.119-2.592.35a1 1 0 0 1-.83-.134c-.752-.507-1.374-.807-1.868-.947c-.144.653-.073 1.194.092 1.607a1 1 0 0 1-.189 1.045C6.016 7.89 5.7 8.694 5.7 9.64c0 3.172 1.371 4.328 4.322 4.66c.865.097 1.201 1.177.544 1.748c-.192.168-.429.732-.429 1.364v3.15c0 .986-.835 1.725-1.96 1.528a1 1 0 0 1-.04-1.962v-.99c-.91.061-1.662-.088-2.254-.485z",fill:"currentColor"},null,-1);var fl={render:function(e,t){return mo(),bo("svg",dl,[pl])}};const hl={},vl=tn()(((e,t)=>(mo(),bo("a",{class:"nav-bar-title",href:e.$withBase(e.$localePath),"aria-label":`${e.$siteByRoute.title}, back to home`},[e.$themeConfig.logo?(mo(),bo("img",{key:0,class:"logo",src:e.$withBase(e.$themeConfig.logo),alt:"Logo"},null,8,["src"])):Oo("v-if",!0),$o(" "+g(e.$site.title),1)],8,["href","aria-label"]))));function ml(e){const t=Fr(),{withBase:n}=function(){const e=Dr();return{withBase:function(t){return Ar(e.value.base,t)}}}(),o=ll(e.value.link);return{props:or((()=>{const r=gl(`/${t.data.relativePath}`);let l=!1;if(e.value.activeMatch)l=new RegExp(e.value.activeMatch).test(r);else{const t=gl(n(e.value.link));l="/"===t?t===r:r.startsWith(t)}return{class:{active:l,isExternal:o},href:o?e.value.link:n(e.value.link),target:e.value.target||o?"_blank":null,rel:e.value.rel||o?"noopener noreferrer":null,"aria-label":e.value.ariaLabel}})),isExternal:o}}function gl(e){return e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\.(html|md)$/,"").replace(/\/index$/,"/")}hl.render=vl,hl.__scopeId="data-v-ffb90d4a";const bl={},yl={class:"icon outbound",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},xl=Co("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"},null,-1),_l=Co("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"},null,-1);bl.render=function(e,t){return mo(),bo("svg",yl,[xl,_l])},Zt("data-v-c272f228");const kl={class:"nav-link"};en();var wl=Qn({expose:[],props:{item:{type:null,required:!0}},setup(e){const t=vt(e),{props:n,isExternal:o}=ml(t.item);return(t,r)=>(mo(),bo("div",kl,[Co("a",Mo({class:"item"},pt(n)),[$o(g(e.item.text)+" ",1),pt(o)?(mo(),bo(bl,{key:0})):Oo("v-if",!0)],16)]))}});wl.__scopeId="data-v-c272f228",Zt("data-v-7b16fcd4");const Cl={class:"nav-dropdown-link-item"},Sl=Co("span",{class:"arrow"},null,-1),$l={class:"text"},El={class:"icon"};en();var Ol=Qn({expose:[],props:{item:{type:null,required:!0}},setup(e){const t=vt(e),{props:n,isExternal:o}=ml(t.item);return(t,r)=>(mo(),bo("div",Cl,[Co("a",Mo({class:"item"},pt(n)),[Sl,Co("span",$l,g(e.item.text),1),Co("span",El,[pt(o)?(mo(),bo(bl,{key:0})):Oo("v-if",!0)])],16)]))}});Ol.__scopeId="data-v-7b16fcd4",Zt("data-v-312de885");const Ll={class:"button-text"},Tl={class:"dialog"};en();var Pl=Qn({expose:[],props:{item:{type:null,required:!0}},setup(e){const t=Fr(),n=ut(!1);function o(){n.value=!n.value}return Tn((()=>t.path),(()=>{n.value=!1})),(t,r)=>(mo(),bo("div",{class:["nav-dropdown-link",{open:n.value}]},[Co("button",{class:"button","aria-label":e.item.ariaLabel,onClick:o},[Co("span",Ll,g(e.item.text),1),Co("span",{class:["button-arrow",n.value?"down":"right"]},null,2)],8,["aria-label"]),Co("ul",Tl,[(mo(!0),bo(ao,null,lr(e.item.items,(e=>(mo(),bo("li",{key:e.text,class:"dialog-item"},[Co(Ol,{item:e},null,8,["item"])])))),128))])],2))}});Pl.__scopeId="data-v-312de885",Zt("data-v-1e870408");const Ml={key:0,class:"nav-links"},jl={key:1,class:"item"};en();var Al=Qn({expose:[],setup(e){const t=Hr(),n=function(){const e=Fr(),t=Dr();return or((()=>{const n=t.value.themeConfig.locales;if(!n)return null;const o=Object.keys(n);if(o.length<=1)return null;const r=Pr?t.value.base:"/",l=r.endsWith("/")?r.slice(0,-1):r,s=e.path.slice(l.length),i=o.find((e=>"/"!==e&&s.startsWith(e))),c=i?s.substring(i.length-1):s,a=o.map((e=>{const t=e.endsWith("/")?e.slice(0,-1):e;return{text:n[e].label,link:`${t}${c}`}})),u=i||"/";return{text:n[u].selectText?n[u].selectText:"Languages",items:a}}))}(),o=or((()=>r.value||repo.value)),r=or((()=>t.value.themeConfig.nav));return(e,t)=>pt(o)?(mo(),bo("nav",Ml,[pt(r)?(mo(!0),bo(ao,{key:0},lr(pt(r),(e=>(mo(),bo("div",{key:e.text,class:"item"},[e.items?(mo(),bo(Pl,{key:0,item:e},null,8,["item"])):(mo(),bo(wl,{key:1,item:e},null,8,["item"]))])))),128)):Oo("v-if",!0),pt(n)?(mo(),bo("div",jl,[Co(Pl,{item:pt(n)},null,8,["item"])])):Oo("v-if",!0),Oo('
\n \n
')])):Oo("v-if",!0)}});Al.__scopeId="data-v-1e870408";var Il={emits:["toggle"]};const Rl=Co("svg",{class:"icon",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",viewBox:"0 0 448 512"},[Co("path",{fill:"currentColor",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z",class:""})],-1);Il.render=function(e,t,n,o,r,l){return mo(),bo("div",{class:"sidebar-button",onClick:t[1]||(t[1]=t=>e.$emit("toggle"))},[Rl])};const Fl={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",width:"1.2em",height:"1.2em",preserveAspectRatio:"xMidYMid meet",viewBox:"0 0 24 24"},Nl=Co("path",{d:"M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938A7.999 7.999 0 0 0 4 12z",fill:"currentColor"},null,-1);var Ul={render:function(e,t){return mo(),bo("svg",Fl,[Nl])}};const Vl={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",width:"1.2em",height:"1.2em",preserveAspectRatio:"xMidYMid meet",viewBox:"0 0 24 24"},Bl=Co("path",{d:"M12 18a6 6 0 1 1 0-12a6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8a4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636L5.636 7.05L3.515 4.93zM16.95 18.364l1.414-1.414l2.121 2.121l-1.414 1.414l-2.121-2.121zm2.121-14.85l1.414 1.415l-2.121 2.121l-1.414-1.414l2.121-2.121zM5.636 16.95l1.414 1.414l-2.121 2.121l-1.414-1.414l2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z",fill:"currentColor"},null,-1);var zl={render:function(e,t){return mo(),bo("svg",Vl,[Bl])}}; +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */const Dl="undefined"!=typeof window,Hl=()=>{};const Wl=e=>e();function ql(e,t,n={}){const{eventFilter:o=Wl}=n,r=function(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var r=0;for(o=Object.getOwnPropertySymbols(e);rs.apply(this,e)),{fn:s,thisArg:this,args:e})}),r);var l,s}function Kl(e){Jo()&&$n(e)}const Gl=Dl?window:void 0;const Jl={boolean:{read:e=>null!=e?"true"===e:null,write:e=>String(e)},object:{read:e=>e?JSON.parse(e):null,write:e=>JSON.stringify(e)},number:{read:e=>null!=e?Number.parseFloat(e):null,write:e=>String(e)},any:{read:e=>null!=e&&"null"!==e?e:null,write:e=>String(e)},string:{read:e=>null!=e?e:null,write:e=>String(e)}};function Yl(e,t,n=(null==Gl?void 0:Gl.localStorage),o={}){var r;const{flush:l="pre",deep:s=!0,listenToStorageChanges:i=!0,window:c=Gl,eventFilter:a}=o,u=ut(t),d=null==t?"any":"boolean"==typeof t?"boolean":"string"==typeof t?"string":"object"==typeof t||Array.isArray(t)?"object":Number.isNaN(t)?"any":"number",p=null!==(r=o.serializer)&&void 0!==r?r:Jl[d];function f(o){if(n&&(!o||o.key===e))try{const r=o?o.newValue:n.getItem(e);null==r?(u.value=t,n.setItem(e,p.write(t))):u.value=p.read(r)}catch(r){console.warn(r)}}return f(),c&&i&&function(...e){let t,n,o,r;if("string"==typeof e[0]?([n,o,r]=e,t=Gl):[t,n,o,r]=e,!t)return Hl;let l=Hl;const s=Tn((()=>pt(t)),(e=>{l(),e&&(e.addEventListener(n,o,r),l=()=>{e.removeEventListener(n,o,r),l=Hl})}),{immediate:!0,flush:"post"}),i=()=>{s(),l()};Kl(i)}(c,"storage",f),ql(u,(()=>{if(n)try{null==u.value?n.removeItem(e):n.setItem(e,p.write(u.value))}catch(t){console.warn(t)}}),{flush:l,deep:s,eventFilter:a}),u}function Ql(e){return function(e,t={}){const{window:n=Gl}=t;if(!n)return ut(!1);const o=n.matchMedia(e),r=ut(o.matches),l=e=>{r.value=e.matches};return"addEventListener"in o?o.addEventListener("change",l):o.addListener(l),Kl((()=>{"removeEventListener"in o?o.removeEventListener("change",l):o.removeListener(l)})),r}("(prefers-color-scheme: dark)",e)}var Xl,Zl;(Zl=Xl||(Xl={})).UP="UP",Zl.RIGHT="RIGHT",Zl.DOWN="DOWN",Zl.LEFT="LEFT",Zl.NONE="NONE";const es=function(e={}){const{selector:t="html",attribute:n="class",valueDark:o="dark",valueLight:r="",window:l=Gl,storage:s=(null==Gl?void 0:Gl.localStorage),storageKey:i="vueuse-color-scheme",listenToStorageChanges:c=!0}=e,a=Ql({window:l}),u=null==i?ut("auto"):Yl(i,"auto",s,{window:l,listenToStorageChanges:c}),d=or({get:()=>"auto"===u.value?a.value:"dark"===u.value,set(e){e===a.value?u.value="auto":u.value=e?"dark":"light"}}),p=e.onChanged||(e=>{const s=null==l?void 0:l.document.querySelector(t);"class"===n?(null==s||s.classList.toggle(o,e),r&&(null==s||s.classList.toggle(r,!e))):null==s||s.setAttribute(n,e?o:r)});return Tn(d,p,{flush:"post"}),function(e,t=!0){Jo()?kn(e):t?e():It(e)}((()=>p(d.value))),d}({storageKey:"vben-admin-color-scheme",valueLight:"light"});var ts=Qn({expose:[],setup(e){const t=function(e=!1){if(at(e))return t=>{e.value="boolean"==typeof t?t:!e.value};{const t=ut(e),n=e=>{t.value="boolean"==typeof e?e:!t.value};return[t,n]}}(es);return(e,n)=>{const o=Ul,r=zl;return mo(),bo("button",{class:"nav-btn","aria-label":"Toggle Theme",onClick:n[1]||(n[1]=(...e)=>pt(t)&&pt(t)(...e))},[zn(Co(o,null,null,512),[[Sr,pt(es)]]),zn(Co(r,null,null,512),[[Sr,!pt(es)]])])}}});const ns=["GitHub","GitLab","Bitbucket"].map((e=>[e,new RegExp(e,"i")]));function os(){const e=Hr();return or((()=>{const t=e.value.themeConfig,n=t.docsRepo||t.repo;if(!n)return null;const o=/^https?:/.test(r=n)?r:`https://github.com/${r}`;var r;return{text:function(e,t){if(t)return t;const n=e.match(/^https?:\/\/[^/]+/);if(!n)return"Source";const o=ns.find((([e,t])=>t.test(n[0])));if(o&&o[0])return o[0];return"Source"}(o,t.repoLabel),link:o}}))}Zt("data-v-2332dbaa");const rs={class:"nav-bar"},ls=Co("div",{class:"flex-grow"},null,-1),ss={class:"nav"},is={class:"nav-icons"},cs={class:"item"},as={key:0,class:"item"},us={class:"nav-btn",href:"https://github.com/vbenjs/vue-vben-admin",target:"_blank","aria-label":"View GitHub Repo"};en();var ds=Qn({expose:[],emits:["toggle"],setup(e){const t=os();return(e,n)=>{const o=fl;return mo(),bo("header",rs,[Co(Il,{onToggle:n[1]||(n[1]=t=>e.$emit("toggle"))}),Co(hl),ls,Co("div",ss,[Co(Al)]),Co("div",is,[Co("div",cs,[Co(ts)]),pt(t)?(mo(),bo("div",as,[Co("a",us,[Co(o)])])):Oo("v-if",!0)]),Gt(e.$slots,"search",{},void 0,!0)])}}});function ps(){let e=null,t=null;const n=function(e,t){let n,o=!1;return()=>{n&&clearTimeout(n),o?n=setTimeout(e,t):(e(),o=!0,setTimeout((()=>{o=!1}),t))}}(o,300);function o(){const e=function(e){return[].slice.call(document.querySelectorAll(".header-anchor")).filter((t=>e.some((e=>e.hash===t.hash))))}([].slice.call(document.querySelectorAll(".sidebar a.sidebar-link-item")));for(let t=0;t ul > li");o&&o!==t.parentElement?(e=o.querySelector("a"),e&&e.classList.add("active")):e=null}function l(e){e&&e.classList.remove("active")}kn((()=>{o(),window.addEventListener("scroll",n)})),Cn((()=>{r(decodeURIComponent(location.hash))})),$n((()=>{window.removeEventListener("scroll",n)}))}function fs(e){const t=document.querySelector(".nav-bar").offsetHeight;return e.parentElement.offsetTop-t-15}function hs(e,t,n){const o=window.scrollY;return 0===e&&0===o?[!0,null]:o{if(e-1>t)return;const s={text:r,link:`#${l}`};2===e?(o=s,n.push(s)):o&&(o.children||(o.children=[])).push(s)})),n}ds.__scopeId="data-v-2332dbaa";const ms=e=>{const t=Fr(),n=Dr(),o=t.data.headers,r=e.item.text,l=function(e,t){if(void 0===t)return t;if(t.startsWith("#"))return t;return function(e,t){const n=e.endsWith("/"),o=t.startsWith("/");return n&&o?e.slice(0,-1)+t:n||o?e+t:`${e}/${t}`}(e,t)}(n.value.base,e.item.link),s=e.item.children,i=function(e,t){return void 0!==t&&sl(`/${e.data.relativePath}`)===sl(t)}(t,e.item.link),c=gs(i,s,o);return rr("li",{class:"sidebar-link"},[rr(l?"a":"p",{class:{"sidebar-link-item":!0,active:i},href:l},r),c])};function gs(e,t,n){return t&&t.length>0?rr("ul",{class:"sidebar-links"},t.map((e=>rr(ms,{item:e})))):e&&n?gs(!1,function(e){return bs(function(e){let t;return(e=e.map((e=>Object.assign({},e)))).forEach((e=>{2===e.level?t=e:t&&(t.children||(t.children=[])).push(e)})),e.filter((e=>2===e.level))}(e))}(n)):null}function bs(e){return e.map((e=>({text:e.title,link:`#${e.slug}`,children:e.children?bs(e.children):void 0})))}const ys={key:0,class:"sidebar-links"};var xs=Qn({expose:[],setup(e){const t=function(){const e=Fr(),t=Hr();return ps(),or((()=>{const n=e.data.headers,o=e.data.frontmatter.sidebar,r=e.data.frontmatter.sidebarDepth;if(!1===o)return[];if("auto"===o)return vs(n,r);const l=al(t.value.themeConfig.sidebar,e.data.relativePath);return!1===l?[]:"auto"===l?vs(n,r):l}))}();return(e,n)=>pt(t).length>0?(mo(),bo("ul",ys,[(mo(!0),bo(ao,null,lr(pt(t),(e=>(mo(),bo(pt(ms),{key:e.text,item:e},null,8,["item"])))),128))])):Oo("v-if",!0)}}),_s=Qn({expose:[],props:{open:{type:Boolean,required:!0}},setup:e=>(t,n)=>(mo(),bo(ao,null,[Co("aside",{class:["sidebar",{open:e.open}]},[Co(Al,{class:"nav"}),Gt(t.$slots,"sidebar-top",{},void 0,!0),Co(xs),Gt(t.$slots,"sidebar-bottom",{},void 0,!0)],2),Oo(" ")],2112))});_s.__scopeId="data-v-4668b452";const ks=/bitbucket.org/;function ws(){const e=Hr(),t=Wr();return{url:or((()=>{const n=null==t.value.frontmatter.editLink?e.value.themeConfig.editLinks:t.value.frontmatter.editLink;const{repo:o,docsDir:r="",docsBranch:l="master",docsRepo:s=o}=e.value.themeConfig,{relativePath:i}=t.value;return n&&i&&o?function(e,t,n,o,r){return ks.test(e)?function(e,t,n,o,r){return(ll(t)?t:e).replace(nl,"")+`/src/${o}/`+(n?n.replace(nl,"")+"/":"")+r+`?mode=edit&spa=0&at=${o}&fileviewer=file-view-default`}(e,t,n,o,r):function(e,t,n,o,r){return(ll(t)?t:`https://github.com/${t}`).replace(nl,"")+`/edit/${o}/`+(n?n.replace(nl,"")+"/":"")+r}(0,t,n,o,r)}(o,s,r,l,i):null})),text:or((()=>e.value.themeConfig.editLinkText||"Edit this page"))}}Zt("data-v-045573c2");const Cs={class:"edit-link"};en();var Ss=Qn({expose:[],setup(e){const{url:t,text:n}=ws();return(e,o)=>(mo(),bo("div",Cs,[pt(t)?(mo(),bo("a",{key:0,class:"link",href:pt(t),target:"_blank",rel:"noopener noreferrer"},[$o(g(pt(n))+" ",1),Co(bl,{class:"icon"})],8,["href"])):Oo("v-if",!0)]))}});Ss.__scopeId="data-v-045573c2",Zt("data-v-03e55a27");const $s={key:0,class:"last-updated"},Es={class:"prefix"},Os={class:"datetime"};en();var Ls=Qn({expose:[],setup(e){const t=Hr(),n=Wr(),o=or((()=>{const e=t.value.themeConfig.lastUpdated;return void 0!==e&&!1!==e})),r=or((()=>{const e=t.value.themeConfig.lastUpdated;return!0===e?"Last Updated":e})),l=ut("");return kn((()=>{l.value=new Date(n.value.lastUpdated).toLocaleString("en-US")})),(e,t)=>pt(o)?(mo(),bo("p",$s,[Co("span",Es,g(pt(r))+":",1),Co("span",Os,g(l.value),1)])):Oo("v-if",!0)}});Ls.__scopeId="data-v-03e55a27",Zt("data-v-22e60b1a");const Ts={class:"page-footer"},Ps={class:"edit"},Ms={class:"updated"};en();var js=Qn({expose:[],setup:e=>(e,t)=>(mo(),bo("footer",Ts,[Co("div",Ps,[Co(Ss)]),Co("div",Ms,[Co(Ls)])]))});function As(){const e=Hr(),t=Wr(),n=or((()=>cl(il(t.value.relativePath)))),o=or((()=>{const t=al(e.value.themeConfig.sidebar,n.value);return rl(t)?ul(t):[]})),r=or((()=>o.value.findIndex((e=>e.link===n.value)))),l=or((()=>{if(!1!==e.value.themeConfig.nextLinks&&r.value>-1&&r.value{if(!1!==e.value.themeConfig.prevLinks&&r.value>0)return o.value[r.value-1]})),i=or((()=>!!l.value||!!s.value));return{next:l,prev:s,hasLinks:i}}js.__scopeId="data-v-22e60b1a";const Is={},Rs={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Fs=Co("path",{d:"M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"},null,-1);Is.render=function(e,t){return mo(),bo("svg",Rs,[Fs])};const Ns={},Us={xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},Vs=Co("path",{d:"M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"},null,-1);Ns.render=function(e,t){return mo(),bo("svg",Us,[Vs])},Zt("data-v-0facf926");const Bs={key:0,class:"next-and-prev-link"},zs={class:"container"},Ds={class:"prev"},Hs={class:"text"},Ws={class:"next"},qs={class:"text"};en();var Ks=Qn({expose:[],setup(e){const{hasLinks:t,prev:n,next:o}=As();return(e,r)=>pt(t)?(mo(),bo("div",Bs,[Co("div",zs,[Co("div",Ds,[pt(n)?(mo(),bo("a",{key:0,class:"link",href:e.$withBase(pt(n).link)},[Co(Is,{class:"icon icon-prev"}),Co("span",Hs,g(pt(n).text),1)],8,["href"])):Oo("v-if",!0)]),Co("div",Ws,[pt(o)?(mo(),bo("a",{key:0,class:"link",href:e.$withBase(pt(o).link)},[Co("span",qs,g(pt(o).text),1),Co(Ns,{class:"icon icon-next"})],8,["href"])):Oo("v-if",!0)])])])):Oo("v-if",!0)}});Ks.__scopeId="data-v-0facf926",Zt("data-v-7abc59e6");const Gs={class:"page"},Js={class:"container"},Ys={class:"content"};en();var Qs=Qn({expose:[],setup:e=>(e,t)=>{const n=so("Content");return mo(),bo("main",Gs,[Co("div",Js,[Gt(e.$slots,"top",{},void 0,!0),Co("div",Ys,[Co(n)]),Co(js),Co(Ks),Gt(e.$slots,"bottom",{},void 0,!0)])])}});Qs.__scopeId="data-v-7abc59e6";const Xs={key:0,id:"ads-container"};var Zs=Qn({expose:[],setup(e){const t=Xn((()=>function(e,t){if(!t)return e();if(void 0===Kr){const e=document.createElement("link").relList;Kr=e&&e.supports&&e.supports("modulepreload")?"modulepreload":"preload"}return Promise.all(t.map((e=>{if(e in Gr)return;Gr[e]=!0;const t=e.endsWith(".css"),n=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${n}`))return;const o=document.createElement("link");return o.rel=t?"stylesheet":Kr,t||(o.as="script",o.crossOrigin=""),o.href=e,document.head.appendChild(o),t?new Promise(((e,t)=>{o.addEventListener("load",e),o.addEventListener("error",t)})):void 0}))).then((()=>e()))}((()=>import("./Home.00e49e13.js")),void 0))),n=()=>null,o=n,r=n,l=n,s=Fr(),i=Dr(),c=Hr(),a=or((()=>i.value.themeConfig)),u=Wr(),d=or((()=>!!s.data.frontmatter.customLayout)),p=or((()=>!!s.data.frontmatter.home)),f=or((()=>{const{themeConfig:e}=c.value,{frontmatter:t}=s.data;return!1!==t.navbar&&!1!==e.navbar&&(i.value.title||e.logo||e.repo||e.nav)})),h=ut(!1),v=or((()=>{const{frontmatter:e}=s.data;if(e.home||!1===e.sidebar)return!1;const{themeConfig:t}=c.value;return!(rl(n=al(t.sidebar,s.data.relativePath))?0===n.length:!n);var n})),m=e=>{h.value="boolean"==typeof e?e:!h.value},g=m.bind(null,!1);Tn(s,g);const b=or((()=>[{"no-navbar":!f.value,"sidebar-open":h.value,"no-sidebar":!v.value}]));return(e,n)=>{const s=so("Content"),i=so("Debug");return mo(),bo(ao,null,[Co("div",{class:["theme",pt(b)]},[pt(f)?(mo(),bo(ds,{key:0,onToggle:m},{search:nn((()=>[Gt(e.$slots,"navbar-search",{},(()=>[pt(a).algolia?(mo(),bo(pt(l),{options:pt(a).algolia,multilang:!!pt(a).locales,key:pt(c).lang},null,8,["options","multilang"])):Oo("v-if",!0)]))])),_:1})):Oo("v-if",!0),Co(_s,{open:h.value},{"sidebar-top":nn((()=>[Gt(e.$slots,"sidebar-top")])),"sidebar-bottom":nn((()=>[Gt(e.$slots,"sidebar-bottom")])),_:1},8,["open"]),Oo(" TODO: make this button accessible "),Co("div",{class:"sidebar-mask",onClick:n[1]||(n[1]=e=>m(!1))}),pt(d)?(mo(),bo(s,{key:1})):pt(p)?(mo(),bo(pt(t),{key:2},{hero:nn((()=>[Gt(e.$slots,"home-hero")])),features:nn((()=>[Gt(e.$slots,"home-features")])),footer:nn((()=>[Gt(e.$slots,"home-footer")])),_:1})):(mo(),bo(Qs,{key:3},{top:nn((()=>[Gt(e.$slots,"page-top-ads",{},(()=>[pt(a).carbonAds&&pt(a).carbonAds.carbon?(mo(),bo("div",Xs,[Co(pt(o),{key:"carbon"+pt(u).relativePath,code:pt(a).carbonAds.carbon,placement:pt(a).carbonAds.placement},null,8,["code","placement"])])):Oo("v-if",!0)])),Gt(e.$slots,"page-top")])),bottom:nn((()=>[Gt(e.$slots,"page-bottom"),Gt(e.$slots,"page-bottom-ads",{},(()=>[pt(a).carbonAds&&pt(a).carbonAds.custom?(mo(),bo(pt(r),{key:"custom"+pt(u).relativePath,code:pt(a).carbonAds.custom,placement:pt(a).carbonAds.placement},null,8,["code","placement"])):Oo("v-if",!0)]))])),_:1}))],2),Co(i)],64)}}});const ei={class:"theme"},ti=Co("h1",null,"404",-1);var ni=Qn({expose:[],setup(e){const t=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."];return(e,n)=>(mo(),bo("div",ei,[ti,Co("blockquote",null,g(t[Math.floor(Math.random()*t.length)]),1),Co("a",{href:e.$site.base,"aria-label":"go to home"},"Take me home.",8,["href"])]))}});var oi=i({},{Layout:Zs,NotFound:ni});const ri=new Set,li=()=>document.createElement("link");let si;const ii=Pr&&(si=li())&&si.relList&&si.relList.supports&&si.relList.supports("prefetch")?e=>{const t=li();t.rel="prefetch",t.href=e,document.head.appendChild(t)}:e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};const ci=oi.NotFound||(()=>"404 Not Found"),ai={name:"VitePressApp",setup(){const e=Hr();return kn((()=>{Tn((()=>e.value.lang),(e=>{document.documentElement.lang=e}),{immediate:!0})})),function(){if(!Pr)return;if(!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const o=()=>{n&&n.disconnect(),n=new IntersectionObserver((e=>{e.forEach((e=>{if(e.isIntersecting){const t=e.target;n.unobserve(t);const{pathname:o}=t;if(!ri.has(o)){ri.add(o);const e=Ir(o);ii(e)}}}))})),t((()=>{document.querySelectorAll("#app a").forEach((e=>{const{target:t,hostname:o,pathname:r}=e,l=r.match(/\.\w+$/);l&&".html"!==l[0]||"_blank"!==t&&o===location.hostname&&(r!==location.pathname?n.observe(e):ri.add(r))}))}))};kn(o);const r=Fr();Tn((()=>r.path),o),$n((()=>{n&&n.disconnect()}))}(),()=>rr(oi.Layout)}};function ui(){const e=function(){let e,t=Pr;return function(e,t){const n=et({path:"/",component:null,data:null});function o(e=(Pr?location.href:"/")){const t=new URL(e,"http://a.com");return t.pathname.endsWith("/")||t.pathname.endsWith(".html")||(t.pathname+=".html",e=t.pathname+t.search+t.hash),Pr&&(history.replaceState({scrollPosition:window.scrollY},document.title),history.pushState(null,"",e)),l(e)}let r=null;async function l(o,l=0){const s=new URL(o,"http://a.com"),i=r=s.pathname;try{let t=e(i);if("then"in t&&"function"==typeof t.then&&(t=await t),r===i){r=null;const{default:e,__pageData:o}=t;if(!e)throw new Error(`Invalid route component: ${e}`);n.path=i,n.component=it(e),n.data=tt(JSON.parse(o)),Pr&&It((()=>{if(s.hash&&!l){const e=document.querySelector(decodeURIComponent(s.hash));if(e)return void Nr(e,s.hash)}window.scrollTo(0,l)}))}}catch(c){c.message.match(/fetch/)||console.error(c),r===i&&(r=null,n.path=i,n.component=t?it(t):null)}}return Pr&&(window.addEventListener("click",(e=>{const t=e.target.closest("a");if(t){const{href:n,protocol:r,hostname:l,pathname:s,hash:i,target:c}=t,a=window.location,u=s.match(/\.\w+$/);e.ctrlKey||e.shiftKey||e.altKey||e.metaKey||"_blank"===c||r!==a.protocol||l!==a.hostname||u&&".html"!==u[0]||(e.preventDefault(),s===a.pathname?i&&i!==a.hash&&(history.pushState(null,"",i),Nr(t,i,t.classList.contains("header-anchor"))):o(n))}}),{capture:!0}),window.addEventListener("popstate",(e=>{l(location.href,e.state&&e.state.scrollPosition||0)})),window.addEventListener("hashchange",(e=>{e.preventDefault()}))),{route:n,go:o}}((n=>{let o=Ir(n);return t&&(e=o),(t||e===o)&&(o=o.replace(/\.js$/,".lean.js")),Pr?(t=!1,import(o)):require(o)}),ci)}(),t=Tr(ai);t.provide(Rr,e);const n=Hr(e.route),o=Wr(e.route);return Pr&&qr(e.route,n),function(e,t,n,o){Object.defineProperties(e.config.globalProperties,{$site:{get:()=>t.value},$siteByRoute:{get:()=>n.value},$themeConfig:{get:()=>n.value.themeConfig},$page:{get:()=>o.value},$frontmatter:{get:()=>o.value.frontmatter},$lang:{get:()=>n.value.lang},$localePath:{get(){const{locales:e}=t.value,{lang:o}=n.value,r=Object.keys(e).find((t=>e[t].lang===o));return e&&r||"/"}},$title:{get:()=>o.value.title?o.value.title+" | "+n.value.title:n.value.title},$description:{get:()=>o.value.description||n.value.description},$withBase:{value:e=>Ar(t.value.base,e)}})}(t,Br,n,o),function(e){e.component("Content",Ur),e.component("ClientOnly",Vr),e.component("Debug",(()=>null))}(t),oi.enhanceApp&&oi.enhanceApp({app:t,router:e,siteData:Br}),{app:t,router:e}}if(Pr){const{app:e,router:t}=ui();t.go().then((()=>{e.mount("#app")}))}export{ao as F,wl as _,Eo as a,Co as b,bo as c,ui as createApp,$o as d,Qn as e,Jr as f,or as g,pt as h,Oo as i,en as j,so as k,Gt as l,mo as o,Zt as p,lr as r,g as t,Hr as u,tn as w}; diff --git a/assets/components_auth.md.7bb93906.js b/assets/components_auth.md.7bb93906.js new file mode 100644 index 00000000..a6a563f2 --- /dev/null +++ b/assets/components_auth.md.7bb93906.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Authority","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/auth.md","lastUpdated":1697592578589}',p={},o=s('

Authority

用于项目权限的组件,一般用于按钮级等细粒度权限管理

Usage

<template>\n  <div>\n    <Authority :value="RoleEnum.ADMIN">\n      <a-button type="primary" block> 只有admin角色可见 </a-button>\n    </Authority>\n  </div>\n</template>\n<script>\n  import { Authority } from '/@/components/Authority';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { Authority },\n  });\n</script>\n

Props

属性类型默认值说明
valueRoleEnum,RoleEnum[],string,string[]-角色信息或者权限编码。会自动区分权限模式
',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_auth.md.7bb93906.lean.js b/assets/components_auth.md.7bb93906.lean.js new file mode 100644 index 00000000..3f331a73 --- /dev/null +++ b/assets/components_auth.md.7bb93906.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Authority","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/auth.md","lastUpdated":1697592578589}',p={},o=s('',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_basic.md.28757feb.js b/assets/components_basic.md.28757feb.js new file mode 100644 index 00000000..322f2d2a --- /dev/null +++ b/assets/components_basic.md.28757feb.js @@ -0,0 +1 @@ +import{o as a,c as s,a as n}from"./app.8cddb23b.js";const t='{"title":"Basic 基础组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"BasicTitle","slug":"basictitle"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Slots","slug":"slots"},{"level":2,"title":"BasicArrow","slug":"basicarrow"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"BasicHelp","slug":"basichelp"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-2"},{"level":3,"title":"Slots","slug":"slots-1"}],"relativePath":"components/basic.md","lastUpdated":1697592578589}',p={},e=n('

Basic 基础组件

一些比较基础的通用组件使用方式

BasicTitle

用于显示标题,可以显示帮助按钮及文本

Usage

<template>\n  <div>\n    <BasicTitle helpMessage="提示1">标题</BasicTitle>\n    <BasicTitle :helpMessage="['提示1', '提示2']">标题</BasicTitle>\n  </div>\n</template>\n<script>\n  import { BasicTitle } from '/@/components/Basic/index';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { BasicTitle },\n  });\n</script>\n

Props

属性类型默认值说明
helpMessagestring|string[]-标题右侧帮助按钮信息
spanbooleanfalse是否显示标题左侧蓝色色块
normalbooleanfalse将文字默认化,不加粗

Slots

名称说明
default标题文本

BasicArrow

带动画的箭头组件

Usage

<template>\n  <div>\n    <BasicArrow :expand="false" />\n  </div>\n</template>\n<script>\n  import { BasicArrow } from '/@/components/Basic/index';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { BasicArrow },\n  });\n</script>\n

Props

属性类型默认值说明
expandbooleanfalse箭头展开状态
topbooleanfalse箭头默认向上
bottombooleanfalse箭头默认向下
insetbooleanfalse取消 padding/margin,用于内嵌

BasicHelp

帮助按钮组件

Usage

<template>\n  <div>\n    <BasicHelp :text="['提示1', '提示2']" />\n    <BasicHelp text="提示" />\n  </div>\n</template>\n<script>\n  import { BasicHelp } from '/@/components/Basic/index';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { BasicHelp },\n  });\n</script>\n

Props

属性类型默认值可选值说明
fontSizestring14px-字体大小
colorstring#fff-颜色
textstring|string[]--文本列表
showIndexbooleantrue-是否显示序号,在 text 为 string[]情况下生效
maxWidthstring600px-最大宽度
placementstringright-显示方向,参考 Tooltip 组件

Slots

名称说明
default默认图标
',24);p.render=function(n,t,p,o,c,l){return a(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_basic.md.28757feb.lean.js b/assets/components_basic.md.28757feb.lean.js new file mode 100644 index 00000000..f3386a90 --- /dev/null +++ b/assets/components_basic.md.28757feb.lean.js @@ -0,0 +1 @@ +import{o as a,c as s,a as n}from"./app.8cddb23b.js";const t='{"title":"Basic 基础组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"BasicTitle","slug":"basictitle"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Slots","slug":"slots"},{"level":2,"title":"BasicArrow","slug":"basicarrow"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"BasicHelp","slug":"basichelp"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-2"},{"level":3,"title":"Slots","slug":"slots-1"}],"relativePath":"components/basic.md","lastUpdated":1697592578589}',p={},e=n('',24);p.render=function(n,t,p,o,c,l){return a(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_click-out-side.md.218c4280.js b/assets/components_click-out-side.md.218c4280.js new file mode 100644 index 00000000..893da16c --- /dev/null +++ b/assets/components_click-out-side.md.218c4280.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"ClickOutSide","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/click-out-side.md","lastUpdated":1697592578589}',p={},e=a('

ClickOutSide

用于监听包裹的元素点击外部触发事件

Usage

<template>\n  <div>\n    <ClickOutSide @clickOutside="() => (showRef = false)">\n      <div @click="() => (showRef = true)">\n        {{ showRef ? '鼠标点击那部(点击边框外可以恢复)' : '点击该区域状态(初始状态)' }}\n      </div>\n    </ClickOutSide>\n  </div>\n</template>\n<script>\n  import { defineComponent, ref } from 'vue';\n  import { ClickOutSide } from '/@/components/ClickOutSide/';\n  export default defineComponent({\n    components: { ClickOutSide },\n    setup() {\n      const showRef = ref(false);\n      return {\n        showRef,\n      };\n    },\n  });\n</script>\n

Events

事件回调参数说明
clickOutside()=>void点击包裹元素外部区域触发

Slots

名称说明
default被包裹的元素
',8);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_click-out-side.md.218c4280.lean.js b/assets/components_click-out-side.md.218c4280.lean.js new file mode 100644 index 00000000..b8f93452 --- /dev/null +++ b/assets/components_click-out-side.md.218c4280.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"ClickOutSide","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/click-out-side.md","lastUpdated":1697592578589}',p={},e=a('',8);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_code-editor.md.a00c679f.js b/assets/components_code-editor.md.a00c679f.js new file mode 100644 index 00000000..3378bef8 --- /dev/null +++ b/assets/components_code-editor.md.a00c679f.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"CodeEditor","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/code-editor.md","lastUpdated":1697592578589}',p={},o=s('

CodeEditor

代码编辑器

Usage

<template>\n  <CodeEditor v-model:value="value" :mode="modeValue" />\n</template>\n<script>\n  import { defineComponent, ref } from 'vue';\n  export default defineComponent({\n    components: { CodeEditor },\n    setup() {\n      const modeValue = ref('application/json');\n      return { value, modeValue };\n    },\n  });\n</script>\n

Props

属性类型默认值可选值说明
value(v-model:value)any--绑定值
modestringapplication/json'application/json','htmlmixed','javascript'代码类型
readonlyboolean--是否只读
',6);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_code-editor.md.a00c679f.lean.js b/assets/components_code-editor.md.a00c679f.lean.js new file mode 100644 index 00000000..76db058a --- /dev/null +++ b/assets/components_code-editor.md.a00c679f.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"CodeEditor","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/code-editor.md","lastUpdated":1697592578589}',p={},o=s('',6);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_collapse-container.md.d3614750.js b/assets/components_collapse-container.md.d3614750.js new file mode 100644 index 00000000..9bbce336 --- /dev/null +++ b/assets/components_collapse-container.md.d3614750.js @@ -0,0 +1 @@ +import{o as t,c as n,a}from"./app.8cddb23b.js";const s='{"title":"CollapseContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/collapse-container.md","lastUpdated":1697592578589}',e={},p=a('

CollapseContainer

区域折叠卡片容器

Usage

<template>\n  <div>\n    <CollapseContainer> content </CollapseContainer>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { CollapseContainer } from '/@/components/Container/index';\n\n  export default defineComponent({\n    components: {\n      CollapseContainer,\n    },\n  });\n</script>\n

Props

属性类型默认值可选值说明
titlestring--标题
canExpanbooleantrue-是否可以展开,为true显示折叠按钮
helpMessagestring[],string--标题右侧温馨提醒
triggerWindowResizebooleanfalse-展开收缩的时候是否触发 window.resize
loadingbooleanfalse-显示加载骨架屏
lazyTimenumber0-延迟加载时间

Slots

名称说明
title自定义标题
action自定义右侧操作按钮
default默认区域
footer自定义底部区域
',8);e.render=function(a,s,e,o,c,d){return t(),n("div",null,[p])};export default e;export{s as __pageData}; diff --git a/assets/components_collapse-container.md.d3614750.lean.js b/assets/components_collapse-container.md.d3614750.lean.js new file mode 100644 index 00000000..5651618b --- /dev/null +++ b/assets/components_collapse-container.md.d3614750.lean.js @@ -0,0 +1 @@ +import{o as t,c as n,a}from"./app.8cddb23b.js";const s='{"title":"CollapseContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/collapse-container.md","lastUpdated":1697592578589}',e={},p=a('',8);e.render=function(a,s,e,o,c,d){return t(),n("div",null,[p])};export default e;export{s as __pageData}; diff --git a/assets/components_count-down.md.9adb65a3.js b/assets/components_count-down.md.9adb65a3.js new file mode 100644 index 00000000..a37c86b9 --- /dev/null +++ b/assets/components_count-down.md.9adb65a3.js @@ -0,0 +1 @@ +import{o as n,c as t,a}from"./app.8cddb23b.js";const s='{"title":"CountDown","description":"","frontmatter":{},"headers":[{"level":2,"title":"CountButton","slug":"countbutton"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"CountDownInput","slug":"countdowninput"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"}],"relativePath":"components/count-down.md","lastUpdated":1697592578589}',p={},o=a('

CountDown

倒计时组件

CountButton

倒计时按钮组件

Usage

<template>\n  <CountButton />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { CountButton } from '/@/components/CountDown';\n\n  export default defineComponent({\n    components: { CountButton },\n  });\n</script>\n

Props

属性类型默认值可选值说明
valueany--绑定值
countnumber60-倒计时时间
beforeStartFunc()=>promise--倒计时之前执行的函数,返回 true 才会开始执行

CountDownInput

倒计时输入框按钮组件

Usage

<template>\n  <CountdownInput />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { CountdownInput } from '/@/components/CountDown';\n\n  export default defineComponent({\n    components: { CountdownInput },\n  });\n</script>\n

Props

属性类型默认值可选值说明
valueany--绑定值
sizestring'default', 'large', 'small'-输入框即按钮大小
countnumber60-倒计时时间
sendCodeApi()=>promise--倒计时之前执行的函数,返回 true 才会开始执行
',14);p.render=function(a,s,p,e,c,u){return n(),t("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_count-down.md.9adb65a3.lean.js b/assets/components_count-down.md.9adb65a3.lean.js new file mode 100644 index 00000000..af0ef4f6 --- /dev/null +++ b/assets/components_count-down.md.9adb65a3.lean.js @@ -0,0 +1 @@ +import{o as n,c as t,a}from"./app.8cddb23b.js";const s='{"title":"CountDown","description":"","frontmatter":{},"headers":[{"level":2,"title":"CountButton","slug":"countbutton"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"CountDownInput","slug":"countdowninput"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"}],"relativePath":"components/count-down.md","lastUpdated":1697592578589}',p={},o=a('',14);p.render=function(a,s,p,e,c,u){return n(),t("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_count-to.md.e7a76610.js b/assets/components_count-to.md.e7a76610.js new file mode 100644 index 00000000..fd13e5da --- /dev/null +++ b/assets/components_count-to.md.e7a76610.js @@ -0,0 +1 @@ +import{o as t,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"CountTo","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Methods","slug":"methods"}],"relativePath":"components/count-to.md","lastUpdated":1697592578589}',o={},e=n('

CountTo

数字动画组件

该组件对 vue-countTo 进行了重构,改造成适配 vue3 语法的组件。

Usage

<template>\n  <CountTo prefix="$" :color="'#409EFF'" :startVal="1" :endVal="200000" :duration="8000" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { CountTo } from '/@/components/CountTo/index';\n\n  export default defineComponent({\n    components: {\n      CountTo,\n    },\n  });\n</script>\n

Props

属性类型默认值说明
startValnumber0起始值
endValnumber2021结束值
durationnumber1500动画持续时间
autoplaybooleantrue自动执行
prefixstring-前缀
suffixstring-后缀
separatorstring,分隔符
colorstring-字体颜色
useEasingbooleantrue是否开启动画
transitionstringlinear动画效果
decimalsnumber0保留小数点位数

Methods

名称回调参数说明
start()=>void开始执行动画
reset()=>void重置
',9);o.render=function(n,s,o,p,d,c){return t(),a("div",null,[e])};export default o;export{s as __pageData}; diff --git a/assets/components_count-to.md.e7a76610.lean.js b/assets/components_count-to.md.e7a76610.lean.js new file mode 100644 index 00000000..55973bac --- /dev/null +++ b/assets/components_count-to.md.e7a76610.lean.js @@ -0,0 +1 @@ +import{o as t,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"CountTo","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Methods","slug":"methods"}],"relativePath":"components/count-to.md","lastUpdated":1697592578589}',o={},e=n('',9);o.render=function(n,s,o,p,d,c){return t(),a("div",null,[e])};export default o;export{s as __pageData}; diff --git a/assets/components_cropper.md.a5f71a93.js b/assets/components_cropper.md.a5f71a93.js new file mode 100644 index 00000000..8eac3941 --- /dev/null +++ b/assets/components_cropper.md.a5f71a93.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Cropper","description":"","frontmatter":{},"headers":[{"level":2,"title":"CropperImage","slug":"cropperimage"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"CropperAvatar","slug":"cropperavatar"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":3,"title":"Events","slug":"events"},{"level":3,"title":"Methods","slug":"methods"}],"relativePath":"components/cropper.md","lastUpdated":1697592578589}',p={},o=s('

Cropper

图片裁剪组件

CropperImage

图片裁剪组件

Usage

<template>\n  <CropperImage ref="refCropper" :src="img" @cropend="handleCropend" style="width: 40vw" />\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { CropperImage } from '/@/components/Cropper';\n  import img from '/@/assets/images/header.jpg';\n\n  export default defineComponent({\n    components: {\n      CropperImage,\n    },\n    setup() {\n      const info = ref('');\n      const cropperImg = ref('');\n\n      function handleCropend({ imgBase64, imgInfo }) {\n        info.value = imgInfo;\n        cropperImg.value = imgBase64;\n      }\n\n      return {\n        img,\n        info,\n        cropperImg,\n        handleCropend,\n      };\n    },\n  });\n</script>\n

Props

属性类型默认值说明
srcstring-图片源
altstring-图片 alt
circledbooleanfalse圆形裁剪框
realTimePreviewbooleantrue实时触发预览
heightstring360px高度
crossoriginstring-crossorigin
imageStyleobject``图片样式
optionsobjectDefaultOptionscorpperjs 配置项

DefaultOptions

{\n  aspectRatio: 1,\n  zoomable: true,\n  zoomOnTouch: true,\n  zoomOnWheel: true,\n  cropBoxMovable: true,\n  cropBoxResizable: true,\n  toggleDragModeOnDblclick: true,\n  autoCrop: true,\n  background: true,\n  highlight: true,\n  center: true,\n  responsive: true,\n  restore: true,\n  checkCrossOrigin: true,\n  checkOrientation: true,\n  scalable: true,\n  modal: true,\n  guides: true,\n  movable: true,\n  rotatable: true,\n}\n

CropperAvatar

头像裁剪组件

Usage

<template>\n  <CropperAvatar :uploadApi="uploadApi" />\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { CropperAvatar } from '/@/components/Cropper';\n  import { uploadApi } from '/@/api/sys/upload';\n\n  export default defineComponent({\n    components: {\n      CropperAvatar,\n    },\n  });\n</script>\n

Props

属性类型默认值说明版本
widthstring,number200px图片源
uploadApi({ file: Blob, name: string }) => Promise<void>-图片上传接口
valueString-当前头像地址(v-model)2.5.3
showBtnBooleantrue是否显示按钮2.5.3
btnTextString-按钮文案2.5.3
btnPropsButtonProps-按钮的其它属性2.5.3

Events

名称参数说明版本
changevalue: String当头像上传完成时触发2.5.3

Methods

名称定义说明版本
openModal()=>void打开上传Modal2.5.3
closeModal()=>void关闭上传Modal2.5.3
',20);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_cropper.md.a5f71a93.lean.js b/assets/components_cropper.md.a5f71a93.lean.js new file mode 100644 index 00000000..55cf3832 --- /dev/null +++ b/assets/components_cropper.md.a5f71a93.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Cropper","description":"","frontmatter":{},"headers":[{"level":2,"title":"CropperImage","slug":"cropperimage"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"CropperAvatar","slug":"cropperavatar"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":3,"title":"Events","slug":"events"},{"level":3,"title":"Methods","slug":"methods"}],"relativePath":"components/cropper.md","lastUpdated":1697592578589}',p={},o=s('',20);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_desc.md.c82924aa.js b/assets/components_desc.md.c82924aa.js new file mode 100644 index 00000000..0b2683d0 --- /dev/null +++ b/assets/components_desc.md.c82924aa.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Description 详情组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useDescription","slug":"usedescription"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"DescItem","slug":"descitem"}],"relativePath":"components/desc.md","lastUpdated":1697592578589}',p={},o=a('

Description 详情组件

antv 的 Descriptions 组件进行封装

Usage

<template>\n  <div class="p-4">\n    <Description\n      title="基础示例"\n      :collapseOptions="{ canExpand: true, helpMessage: 'help me' }"\n      :column="3"\n      :data="mockData"\n      :schema="schema"\n    />\n    <Description @register="register" class="mt-4" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { Alert } from 'ant-design-vue';\n  import { Description, DescItem, useDescription } from '/@/components/Description/index';\n  const mockData: any = {\n    username: 'test',\n    nickName: 'VB',\n    age: 123,\n    phone: '15695909xxx',\n    email: '190848757@qq.com',\n    addr: '厦门市思明区',\n    sex: '男',\n    certy: '3504256199xxxxxxxxx',\n    tag: 'orange',\n  };\n  const schema: DescItem[] = [\n    {\n      field: 'username',\n      label: '用户名',\n    },\n    {\n      field: 'nickName',\n      label: '昵称',\n      render: (curVal, data) => {\n        return `${data.username}-${curVal}`;\n      },\n    },\n    {\n      field: 'phone',\n      label: '联系电话',\n    },\n    {\n      field: 'email',\n      label: '邮箱',\n    },\n    {\n      field: 'addr',\n      label: '地址',\n    },\n  ];\n  export default defineComponent({\n    components: { Description, Alert },\n    setup() {\n      const [register] = useDescription({\n        title: 'useDescription',\n        data: mockData,\n        schema: schema,\n      });\n      return { mockData, schema, register };\n    },\n  });\n</script>\n

useDescription

参考以上示例

const [register] = useDescription(Props);\n

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv Description

属性类型默认值可选值说明
titlestring--标题
sizestringsmall-大小
borderedbooleantrue-是否展示边框
columnNumber, Object{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }-一行的 DescriptionItems 数量
useCollapseboolean--是否包裹 CollapseContainer 组件
collapseOptionsObject--CollapseContainer 组件属性
schemaDescItem[]--详情项配置,见下方 DescItem 配置
dataobject--数据源

DescItem

属性类型默认值可选值说明
fieldstring--字段名
labelstring--标签名
labelMinWidthnumber--label 最小宽度
contentMinWidthnumber--content 最小宽度
labelStyleany--label 样式
spannumber--和并列数量
show(data)=>boolean--动态判断当前组件是否显示
render(val: string, data: any)=>VNode,undefined,Element,string,number--自定义渲染 content
',12);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_desc.md.c82924aa.lean.js b/assets/components_desc.md.c82924aa.lean.js new file mode 100644 index 00000000..272578d1 --- /dev/null +++ b/assets/components_desc.md.c82924aa.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Description 详情组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useDescription","slug":"usedescription"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"DescItem","slug":"descitem"}],"relativePath":"components/desc.md","lastUpdated":1697592578589}',p={},o=a('',12);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_drawer.md.6f60c980.js b/assets/components_drawer.md.6f60c980.js new file mode 100644 index 00000000..8340eab8 --- /dev/null +++ b/assets/components_drawer.md.6f60c980.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Drawer 抽屉组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useDrawer","slug":"usedrawer"},{"level":2,"title":"useDrawerInner","slug":"usedrawerinner"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/drawer.md","lastUpdated":1697592578589}',p={},o=s('

Drawer 抽屉组件

antv 的 drawer 组件进行封装,扩展拖拽,全屏,自适应高度等功能。

Usage

由于 drawer 内部代码一般独立成单独文件,推荐独立成组件来进行开发,所以示例都是以独立的文件来进行说明

独立组件代码,用于写组件内部的内容

<template>\n  <BasicDrawer v-bind="$attrs" title="Drawer Title" width="50%"> Drawer Info. </BasicDrawer>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicDrawer } from '/@/components/Drawer';\n  export default defineComponent({\n    components: { BasicDrawer },\n  });\n</script>\n

页面引用弹窗

<template>\n  <div>\n    <Drawer @register="register" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { Alert } from 'ant-design-vue';\n  import { useDrawer } from '/@/components/Drawer';\n  import Drawer from './Drawer.vue';\n\n  export default defineComponent({\n    components: { Drawer },\n    setup() {\n      const [register, { openDrawer }] = useDrawer();\n      return {\n        register,\n        openDrawer,\n      };\n    },\n  });\n</script>\n

useDrawer

useDrawer 用于操作组件

const [register, { openDrawer, setDrawerProps }] = useDrawer();\n

register

register 用于注册 useDrawer,如果需要使用 useDrawer 提供的 api,必须将 register 传入组件的 onRegister

原理其实很简单,就是 vue 的组件子传父通信,内部通过 emit("register",instance) 实现。

同时,独立出去的组件需要将 attrs 绑定到 Drawer 的上面。

<BasicDrawer v-bind="$attrs"> Drawer Info. </BasicDrawer>\n

openDrawer

用于打开/关闭弹窗

// true/false: 打开关闭弹窗\n// data: 传递到子组件的数据\nopenDrawer(true, data);\n

closeDrawer

用于关闭弹窗

closeDrawer();\n

setDrawerProps

用于更改 drawer 的 props 参数因为 drawer 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setDrawerProps 方便更改内部 drawer 的 props

Props 内容可以见下方

setDrawerProps(props);\n

useDrawerInner

用于独立的 Drawer 内部调用

<template>\n  <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%">\n    Drawer Info.\n    <a-button type="primary" @click="closeDrawer">内部关闭drawer</a-button>\n  </BasicDrawer>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';\n  export default defineComponent({\n    components: { BasicDrawer },\n    setup() {\n      const [register, { closeDrawer }] = useDrawerInner();\n      return { register, closeDrawer };\n    },\n  });\n</script>\n

useModalInner用于操作独立组件

const [register, { closeModal, setModalProps }] = useModalInner(callback);\n

callback

type: (data:any)=>void

回调函数用于接收 openDrawer 第二个参数传递的值

openDrawer((data: any) => {\n  console.log(data);\n});\n

closeDrawer

用于关闭抽屉

closeDrawer();\n

changeOkLoading

用于修改确认按钮的 loading 状态

// true or false\nchangeOkLoading(true);\n

changeLoading

用于修改 modal 的 loading 状态

// true or false\nchangeLoading(true);\n

setDrawerProps

用于更改 drawer 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供setDrawerProps 方便更改内部 drawer 的 props

Props 内容可以见下方

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv drawer

属性类型默认值可选值说明
isDetailbooleanfalse-是否为详情模式
loadingbooleanfalse-loading 状态
loadingTextstring``-loading 文本 s
showDetailBackbooleantrue-isDetail=true 状态下是否显示返回按钮
closeFunc() => Promise<boolean>--自定义关闭函数,返回true关闭,否则不关闭
showFooterboolean--是否显示底部
footerHeightnumber60-底部区域高度

Events

事件回调参数说明
close(e)=>void点击关闭回调
visible-change(visible:boolean)=>void弹窗打开关闭时触发
ok(e)=>void点击确定回调
',52);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_drawer.md.6f60c980.lean.js b/assets/components_drawer.md.6f60c980.lean.js new file mode 100644 index 00000000..c9dc2ccb --- /dev/null +++ b/assets/components_drawer.md.6f60c980.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Drawer 抽屉组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useDrawer","slug":"usedrawer"},{"level":2,"title":"useDrawerInner","slug":"usedrawerinner"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/drawer.md","lastUpdated":1697592578589}',p={},o=s('',52);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_excel.md.b9baf91f.js b/assets/components_excel.md.b9baf91f.js new file mode 100644 index 00000000..e9189512 --- /dev/null +++ b/assets/components_excel.md.b9baf91f.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Excel 组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Import","slug":"import"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Events","slug":"events"},{"level":3,"title":"ExcelData","slug":"exceldata"},{"level":2,"title":"Export","slug":"export"},{"level":3,"title":"数组格式数据导出","slug":"数组格式数据导出"},{"level":3,"title":"自定义导出格式","slug":"自定义导出格式"},{"level":3,"title":"json 格式导出","slug":"json-格式导出"},{"level":2,"title":"Function","slug":"function"},{"level":3,"title":"JsonToSheet Type","slug":"jsontosheet-type"},{"level":3,"title":"AoAToSheet Type","slug":"aoatosheet-type"}],"relativePath":"components/excel.md","lastUpdated":1697592578589}',p={},e=a('

Excel 组件

excel 导入导出操作

项目中使用到的是 XLSX,具体文档可以参考XLSX 文档

Import

Usage

<template>\n  <ImpExcel @success="loadDataSuccess">\n    <a-button class="m-3">导入Excel</a-button>\n  </ImpExcel>\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { ImpExcel, ExcelData } from '/@/components/Excel';\n  export default defineComponent({\n    components: { ImpExcel },\n    setup() {\n      function loadDataSuccess(excelDataList: ExcelData[]) {\n        tableListRef.value = [];\n        console.log(excelDataList);\n        for (const excelData of excelDataList) {\n          const {\n            header,\n            results,\n            meta: { sheetName },\n          } = excelData;\n          const columns: BasicColumn[] = [];\n          for (const title of header) {\n            columns.push({ title, dataIndex: title });\n          }\n          tableListRef.value.push({ title: sheetName, dataSource: results, columns });\n        }\n      }\n      return {\n        loadDataSuccess,\n      };\n    },\n  });\n</script>\n

Events

事件回调参数说明
success(res:ExcelData)=>void导入成功回调
error()=>void导出错误

ExcelData

属性类型默认值说明
header:string[];table 表头
results:T[];table 数据
meta:{ sheetName: string };table title

Export

具体详情可以参考完整版示例

import { jsonToSheetXlsx, aoaToSheetXlsx } from '/@/components/Excel';\n

数组格式数据导出

import { aoaToSheetXlsx } from '/@/components/Excel';\n// 保证data顺序与header一致\naoaToSheetXlsx({\n  data: [],\n  header: [],\n  filename: '二维数组方式导出excel.xlsx',\n});\n

自定义导出格式

import { jsonToSheetXlsx } from '/@/components/Excel';\n\njsonToSheetXlsx({\n  data,\n  filename,\n  write2excelOpts: {\n    // 可以是 xlsx/html/csv/txt\n    bookType,\n  },\n});\n

json 格式导出

import { jsonToSheetXlsx } from '/@/components/Excel';\n\njsonToSheetXlsx({\n  data,\n  filename: '使用key作为默认头部.xlsx',\n});\n\njsonToSheetXlsx({\n  data,\n  header: {\n    id: 'ID',\n    name: '姓名',\n    age: '年龄',\n    no: '编号',\n    address: '地址',\n    beginTime: '开始时间',\n    endTime: '结束时间',\n  },\n  filename: '自定义头部.xlsx',\n  json2sheetOpts: {\n    // 指定顺序\n    header: ['name', 'id'],\n  },\n});\n

Function

方法回调参数返回值说明
jsonToSheetXlsxFunction(JsonToSheet)json 格式数据,导出到 excel
aoaToSheetXlsxFunction(AoAToSheet)数组格式,导出到 excel

JsonToSheet Type

属性类型默认值说明
dataT[]JSON 对象数组
header?:T;表头未设置则取 JSON 对象的 key 作为 header
filename?:stringexcel-list.xlsx导出的文件名
json2sheetOpts?:JSON2SheetOpts调用 XLSX.utils.json_to_sheet 的可选参数
write2excelOpts?:WritingOptions{ bookType: 'xlsx' }调用 XLSX.writeFile 的可选参数,具体参 XLSX 文档

AoAToSheet Type

属性类型默认值说明
dataT[][];二维数组
header?:T;表头 ;未设置则没有表头
filename?:string;excel-list.xlsx导出的文件名
write2excelOpts?:WritingOptions;{ bookType: 'xlsx' }调用 XLSX.writeFile 的可选参数
',25);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_excel.md.b9baf91f.lean.js b/assets/components_excel.md.b9baf91f.lean.js new file mode 100644 index 00000000..6709c27b --- /dev/null +++ b/assets/components_excel.md.b9baf91f.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Excel 组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Import","slug":"import"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Events","slug":"events"},{"level":3,"title":"ExcelData","slug":"exceldata"},{"level":2,"title":"Export","slug":"export"},{"level":3,"title":"数组格式数据导出","slug":"数组格式数据导出"},{"level":3,"title":"自定义导出格式","slug":"自定义导出格式"},{"level":3,"title":"json 格式导出","slug":"json-格式导出"},{"level":2,"title":"Function","slug":"function"},{"level":3,"title":"JsonToSheet Type","slug":"jsontosheet-type"},{"level":3,"title":"AoAToSheet Type","slug":"aoatosheet-type"}],"relativePath":"components/excel.md","lastUpdated":1697592578589}',p={},e=a('',25);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_flow-chart.md.387f4a76.js b/assets/components_flow-chart.md.387f4a76.js new file mode 100644 index 00000000..0c891d40 --- /dev/null +++ b/assets/components_flow-chart.md.387f4a76.js @@ -0,0 +1 @@ +import{o as a,c as n,a as t}from"./app.8cddb23b.js";const s='{"title":"FlowChart","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/flow-chart.md","lastUpdated":1697592578589}',p={},o=t('

FlowChart

流程图组件,基于 didi/LogicFlow 的简单封装。详细配置请参考文档 FlowChart

Usage

<template>\n  <FlowChart :data="demoData" />\n</template>\n\n<script lang="ts">\n  import { FlowChart } from '/@/components/FlowChart';\n  import { PageWrapper } from '/@/components/Page';\n\n  import demoData from './dataTurbo.json';\n  export default {\n    components: { FlowChart, PageWrapper },\n    setup() {\n      return { demoData };\n    },\n  };\n</script>\n

Props

属性类型默认值可选值说明
flowOptionsobject--FlowCharts 配置项
dataobject--流程数据
toolbarbooleantrue-是否显示工具栏
patternItems[]--左侧拖拽列表数据
',6);p.render=function(t,s,p,e,c,l){return a(),n("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_flow-chart.md.387f4a76.lean.js b/assets/components_flow-chart.md.387f4a76.lean.js new file mode 100644 index 00000000..1c95fc38 --- /dev/null +++ b/assets/components_flow-chart.md.387f4a76.lean.js @@ -0,0 +1 @@ +import{o as a,c as n,a as t}from"./app.8cddb23b.js";const s='{"title":"FlowChart","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/flow-chart.md","lastUpdated":1697592578589}',p={},o=t('',6);p.render=function(t,s,p,e,c,l){return a(),n("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_form.md.3e11ed4d.js b/assets/components_form.md.3e11ed4d.js new file mode 100644 index 00000000..2d7d87c3 --- /dev/null +++ b/assets/components_form.md.3e11ed4d.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Form 表单组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"useForm 方式","slug":"useform-方式"},{"level":3,"title":"template 方式","slug":"template-方式"},{"level":2,"title":"useForm","slug":"useform"},{"level":3,"title":"示例","slug":"示例"},{"level":3,"title":"参数介绍","slug":"参数介绍"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"ColEx","slug":"colex"},{"level":3,"title":"ActionButtonOption","slug":"actionbuttonoption"},{"level":3,"title":"fieldMapToTime","slug":"fieldmaptotime"},{"level":3,"title":"FormSchema","slug":"formschema"},{"level":3,"title":"Divider schema 说明","slug":"divider-schema-说明"},{"level":2,"title":"自行添加需要的组件类型","slug":"自行添加需要的组件类型"},{"level":3,"title":"方式 1","slug":"方式-1"},{"level":3,"title":"方式 2","slug":"方式-2"},{"level":3,"title":"render","slug":"render"},{"level":3,"title":"slot","slug":"slot"},{"level":3,"title":"ifShow/show/dynamicDisabled","slug":"ifshow-show-dynamicdisabled"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"ApiSelect","slug":"apiselect"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"ApiTreeSelect","slug":"apitreeselect"},{"level":3,"title":"Props","slug":"props-2"},{"level":2,"title":"RadioButtonGroup","slug":"radiobuttongroup"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-3"}],"relativePath":"components/form.md","lastUpdated":1697592578589}',p={},o=a('

Form 表单组件

antv 的 form 组件进行封装,扩展一些常用的功能

如果文档内没有,可以尝试在在线示例内寻找

Usage

useForm 方式

下面是一个使用简单表单的示例,只有一个输入框

<template>\n  <div class="m-4">\n    <BasicForm\n      :labelWidth="100"\n      :schemas="schemas"\n      :actionColOptions="{ span: 24 }"\n      @submit="handleSubmit"\n    />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicForm, FormSchema } from '/@/components/Form';\n  import { CollapseContainer } from '/@/components/Container';\n  import { useMessage } from '/@/hooks/web/useMessage';\n  const schemas: FormSchema[] = [\n    {\n      field: 'field',\n      component: 'Input',\n      label: '字段1',\n      colProps: {\n        span: 8,\n      },\n      defaultValue: '1',\n      componentProps: {\n        placeholder: '自定义placeholder',\n        onChange: (e) => {\n          console.log(e);\n        },\n      },\n    },\n  ];\n\n  export default defineComponent({\n    components: { BasicForm, CollapseContainer },\n    setup() {\n      const { createMessage } = useMessage();\n      return {\n        schemas,\n        handleSubmit: (values: any) => {\n          createMessage.success('click search,values:' + JSON.stringify(values));\n        },\n      };\n    },\n  });\n</script>\n

template 方式

所有可调用函数见下方 Methods 说明

<template>\n  <div class="m-4">\n    <BasicForm\n      :schemas="schemas"\n      ref="formElRef"\n      :labelWidth="100"\n      @submit="handleSubmit"\n      :actionColOptions="{ span: 24 }"\n    />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { BasicForm, FormSchema, FormActionType, FormProps } from '/@/components/Form';\n  import { CollapseContainer } from '/@/components/Container';\n  const schemas: FormSchema[] = [];\n\n  export default defineComponent({\n    components: { BasicForm, CollapseContainer },\n    setup() {\n      const formElRef = ref<Nullable<FormActionType>>(null);\n      return {\n        formElRef,\n        schemas,\n        setProps(props: FormProps) {\n          const formEl = formElRef.value;\n          if (!formEl) return;\n          formEl.setProps(props);\n        },\n      };\n    },\n  });\n</script>\n

useForm

form 组件还提供了 useForm,方便调用函数内部方法

示例

<template>\n  <BasicForm @register="register" @submit="handleSubmit" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';\n  import { CollapseContainer } from '/@/components/Container/index';\n  import { useMessage } from '/@/hooks/web/useMessage';\n  const schemas: FormSchema[] = [\n    {\n      field: 'field1',\n      component: 'Input',\n      label: '字段1',\n      colProps: {\n        span: 8,\n      },\n      componentProps: {\n        placeholder: '自定义placeholder',\n        onChange: (e: any) => {\n          console.log(e);\n        },\n      },\n    },\n  ];\n\n  export default defineComponent({\n    components: { BasicForm, CollapseContainer },\n    setup() {\n      const { createMessage } = useMessage();\n      const [register, { setProps }] = useForm({\n        labelWidth: 120,\n        schemas,\n        actionColOptions: {\n          span: 24,\n        },\n      });\n      return {\n        register,\n        schemas,\n        handleSubmit: (values: any) => {\n          createMessage.success('click search,values:' + JSON.stringify(values));\n        },\n        setProps,\n      };\n    },\n  });\n</script>\n

参数介绍

const [register, methods] = useForm(props);\n

参数 props 内的值可以是 computed 或者 ref 类型

register

register 用于注册 useForm,如果需要使用 useForm 提供的 api,必须将 register 传入组件的 onRegister

<template>\n  <BasicForm @register="register" @submit="handleSubmit" />\n</template>\n<script>\n  export default defineComponent({\n    components: { BasicForm },\n    setup() {\n      const [register] = useForm();\n      return {\n        register,\n      };\n    },\n  });\n</script>\n

Methods见下方说明

Methods

getFieldsValue

类型: () => Recordable;

说明: 获取表单值

setFieldsValue

类型: <T>(values: T) => Promise<void>

说明: 设置表单字段值

resetFields

类型: ()=> Promise<void>

说明: 重置表单值

validateFields

类型: (nameList?: NamePath[]) => Promise<any>

说明: 校验指定表单项

validate

类型: (nameList?: NamePath[]) => Promise<any>

说明: 校验整个表单

submit

类型: () => Promise<void>

说明: 提交表单

scrollToField

类型: (name: NamePath, options?: ScrollOptions) => Promise<void>

说明: 滚动到对应字段位置

clearValidate

类型: (name?: string | string[]) => Promise<void>

说明: 清空校验

setProps

TIP

设置表单的 props 可以直接在标签上传递,也可以使用 setProps,或者初始化直接写 useForm(props)

类型: (formProps: Partial<FormProps>) => Promise<void>

说明: 设置表单 Props

removeSchemaByField

类型: (field: string | string[]) => Promise<void>

说明: 根据 field 删除 Schema

appendSchemaByField

类型: ( schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined ) => Promise<void>

说明: 插入到指定 filed 后面,如果没传指定 field,则插入到最后,当 first = true 时插入到第一个位置

updateSchema

类型: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>

说明: 更新表单的 schema, 只更新函数所传的参数

e.g

updateSchema({ field: 'filed', componentProps: { disabled: true } });\nupdateSchema([\n  { field: 'filed', componentProps: { disabled: true } },\n  { field: 'filed1', componentProps: { disabled: false } },\n]);\n

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv form

属性类型默认值可选值说明版本
schemasSchema[]--表单配置,见下方 FormSchema 配置
submitOnResetbooleanfalse-重置时是否提交表单
labelColPartial<ColEx>--整个表单通用 LabelCol 配置
wrapperColPartial<ColEx>--整个表单通用 wrapperCol 配置
baseColPropsPartial<ColEx>--配置所有选子项的 ColProps,不需要逐个配置,子项也可单独配置优先与全局
baseRowStyleobject--配置所有 Row 的 style 样式
labelWidthnumber , string--扩展 form 组件,增加 label 宽度,表单内所有组件适用,可以单独在某个项覆盖或者禁用
labelAlignstring-left,rightlabel 布局
mergeDynamicDataobject--额外传递到子组件的参数 values
autoFocusFirstItembooleanfalse-是否聚焦第一个输入框,只在第一个表单项为 input 的时候作用
compactbooleanfalsetrue/false紧凑类型表单,减少 margin-bottom
sizestringdefault'default' , 'small' , 'large'向表单内所有组件传递 size 参数,自定义组件需自行实现 size 接收
disabledbooleanfalsetrue/false向表单内所有组件传递 disabled 属性,自定义组件需自行实现 disabled 接收
autoSetPlaceHolderbooleantrue true/false自动设置表单内组件的 placeholder,自定义组件需自行实现
autoSubmitOnEnterbooleanfalse true/false在 input 中输入时按回车自动提交2.4.0
rulesMessageJoinLabelbooleanfalsetrue/false如果表单项有校验,会自动生成校验信息,该参数控制是否将字段中文名字拼接到自动生成的信息后方
showAdvancedButtonbooleanfalsetrue/false是否显示收起展开按钮
emptySpannumber , Partial<ColEx>0-空白行格,可以是数值或者 col 对象 数
autoAdvancedLinenumber3-如果 showAdvancedButton 为 true,超过指定行数行默认折叠
alwaysShowLinesnumber1-折叠时始终保持显示的行数2.7.1
showActionButtonGroupbooleantruetrue/false是否显示操作按钮(重置/提交)
actionColOptionsPartial<ColEx>--操作按钮外层 Col 组件配置,如果开启 showAdvancedButton,则不用设置,具体见下方 actionColOptions
showResetButtonbooleantrue-是否显示重置按钮
resetButtonOptionsobject-重置按钮配置见下方 ActionButtonOption
showSubmitButtonbooleantrue-是否显示提交按钮
submitButtonOptionsobject-确认按钮配置见下方 ActionButtonOption
resetFunc () => Promise<void>-重置表单行为前执行自定义重置按钮逻辑() => Promise<void>;
submitFunc () => Promise<void>-自定义提交按钮逻辑() => Promise<void>;
fieldMapToTime[string, [string, string], string?][]'timestamp' ,'timestampStartDay' ,momentjs 时间格式用于将表单内时间区域的应设成 2 个字段,见下方说明

ColEx

src/components/Form/src/types/index.ts

ActionButtonOption

BasicButtonProps

export interface ButtonProps extends BasicButtonProps {\n  text?: string;\n}\n

fieldMapToTime

将表单内时间区域的值映射成 2 个字段

如果表单内有时间区间组件,获取到的值是一个数组,但是往往我们传递到后台需要是 2 个字段

useForm({\n  fieldMapToTime: [\n    // data为时间组件在表单内的字段,startTime,endTime为转化后的开始时间与结束时间\n    // 'YYYY-MM-DD'为时间格式,参考moment\n    ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],\n    // 支持多个字段\n    ['datetime1', ['startTime1', 'endTime1'], 'YYYY-MM-DD HH:mm:ss'],\n  ],\n});\n\n// fieldMapToTime没写的时候表单获取到的值\n{\n  datetime: [Date(),Date()]\n}\n//  ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],等同于 dayjs(Date()).format('YYYY-MM-DD'). 之后\n{\n    startTime: '2020-08-12',\n    endTime: '2020-08-15',\n}\n\n// ['datetime', ['startTime', 'endTime'], 'timestamp'],等同于 dayjs(Date()).unix(). 之后\n{\n    startTime: 1597190400,\n    endTime: 1597449600,\n}\n\n// ['datetime', ['startTime', 'endTime'], 'timestampStartDay'],等同于 dayjs(Date()).startOf('day').unix(). 之后\n{\n    startTime: 1597190400,\n    endTime: 1597449600,\n}\n

FormSchema

属性类型默认值可选值说明
fieldstring--字段名
labelstring--标签名
subLabelstring--二级标签名灰色
suffixstring , number , ((values: RenderCallbackParams) => string / number);--组件后面的内容
changeEventstring--表单更新事件名称
helpMessagestring , string[]--标签名右侧温馨提示
helpComponentPropsHelpComponentProps--标签名右侧温馨提示组件 props,见下方 HelpComponentProps
labelWidthstring , number--覆盖统一设置的 labelWidth
disabledLabelWidthbooleanfalsetrue/false禁用 form 全局设置的 labelWidth,自己手动设置 labelCol 和 wrapperCol
componentstring--组件类型,见下方 ComponentType
componentPropsany,()=>{}--所渲染的组件的 props
rulesValidationRule[]--校验规则,见下方 ValidationRule
requiredboolean--简化 rules 配置,为 true 则转化成 [{required:true}]。2.4.0之前的版本只支持 string 类型的值
rulesMessageJoinLabelbooleanfalse-校验信息是否加入 label
itemPropsany--参考下方 FormItem
colPropsColEx--参考上方 actionColOptions
defaultValueobject--所渲渲染组件的初始值
render(renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string--自定义渲染组件
renderColContent(renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string--自定义渲染组件(需要自行包含 formItem)
renderComponentContent(renderCallbackParams: RenderCallbackParams) => any / string--自定义渲染组内部的 slot
slotstring--自定义 slot,渲染组件
colSlotstring--自定义 slot,渲染组件 (需要自行包含 formItem)
show boolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判断当前组件是否显示,css 控制,不会删除 dom
ifShow boolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判断当前组件是否显示,js 控制,会删除 dom
dynamicDisabledboolean / ((renderCallbackParams: RenderCallbackParams) => boolean) --动态判断当前组件是否禁用
dynamicRulesboolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判返当前组件你校验规则

RenderCallbackParams

export interface RenderCallbackParams {\n  schema: FormSchema;\n  values: any;\n  model: any;\n  field: string;\n}\n

componentProps

  • 当值为对象类型时,该对象将作为component所对应组件的的 props 传入组件

  • 当值为一个函数时候

参数有 4 个

schema: 表单的整个 schemas

formActionType: 操作表单的函数。与 useForm 返回的操作函数一致

formModel: 表单的双向绑定对象,这个值是响应式的。所以可以方便处理很多操作

tableAction: 操作表格的函数,与 useTable 返回的操作函数一致。注意该参数只在表格内开启搜索表单的时候有值,其余情况为null,

{\n  // 简单例子,值改变的时候操作表格或者修改表单内其他元素的值\n  component:'Input',\n  componentProps: ({ schema, tableAction, formActionType, formModel }) => {\n    return {\n      // xxxx props\n      onChange:e=>{\n        const {reload}=tableAction\n        reload()\n        // or\n        formModel.xxx='123'\n      }\n    };\n  };\n}\n

HelpComponentProps

export interface HelpComponentProps {\n  maxWidth: string;\n  // 是否显示序号\n  showIndex: boolean;\n  // 文本列表\n  text: any;\n  // 颜色\n  color: string;\n  // 字体大小\n  fontSize: string;\n  icon: string;\n  absolute: boolean;\n  // 定位\n  position: any;\n}\n

ComponentType

schema 内组件的可选类型

export type ComponentType =\n  | 'Input'\n  | 'InputGroup'\n  | 'InputPassword'\n  | 'InputSearch'\n  | 'InputTextArea'\n  | 'InputNumber'\n  | 'InputCountDown'\n  | 'Select'\n  | 'ApiSelect'\n  | 'TreeSelect'\n  | 'RadioButtonGroup'\n  | 'RadioGroup'\n  | 'Checkbox'\n  | 'CheckboxGroup'\n  | 'AutoComplete'\n  | 'Cascader'\n  | 'DatePicker'\n  | 'MonthPicker'\n  | 'RangePicker'\n  | 'WeekPicker'\n  | 'TimePicker'\n  | 'Switch'\n  | 'StrengthMeter'\n  | 'Upload'\n  | 'IconPicker'\n  | 'Render'\n  | 'Slider'\n  | 'Rate'\n  | 'Divider'; // v2.7.2新增\n

Divider schema 说明

Divider类型用于在schemas中占位,将会渲染成一个分割线(始终占一整行的版面),可以用于较长表单的版面分隔。请只将 Divider 类型的 schema 当作一个分割线,而不是一个常规的表单字段。

  • Divider仅在showAdvancedButton为 false 时才会显示(也就是说如果启用了表单收起和展开功能,Divider将不会显示)
  • Divider 使用schema中的label以及helpMessage来渲染分割线中的提示内容
  • Divider 可以使用componentProps来设置除type之外的 props
  • Divider 不会渲染AFormItem,因此schema中除labelcomponentPropshelpMessagehelpComponentProps以外的属性不会被用到

自行添加需要的组件类型

src/components/Form/src/componentMap.ts 内,添加需要的组件,并在上方 ComponentType 添加相应的类型 key

方式 1

这种写法适用与适用频率较高的组件

componentMap.set('componentName', 组件);\n\n// ComponentType\nexport type ComponentType = xxxx | 'componentName';\n

方式 2

使用 useComponentRegister 进行注册

这种写法只能在当前页使用,页面销毁之后会从 componentMap 删除相应的组件

import { useComponentRegister } from '@/components/form/index';\n\nimport { StrengthMeter } from '@/components/strength-meter/index';\n\nuseComponentRegister('StrengthMeter', StrengthMeter);\n

提示

方式 2 出现的原因是为了减少打包体积,如果某个组件体积很大,用方式 1 的话可能会使首屏体积增加

render

自定义渲染内容

<template>\n  <div class="m-4">\n    <BasicForm @register="register" @submit="handleSubmit" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, h } from 'vue';\n  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';\n  import { useMessage } from '/@/hooks/web/useMessage';\n  import { Input } from 'ant-design-vue';\n  const schemas: FormSchema[] = [\n    {\n      field: 'field1',\n      component: 'Input',\n      label: '字段1',\n      colProps: {\n        span: 8,\n      },\n      rules: [{ required: true }],\n      render: ({ model, field }) => {\n        return h(Input, {\n          placeholder: '请输入',\n          value: model[field],\n          onChange: (e: ChangeEvent) => {\n            model[field] = e.target.value;\n          },\n        });\n      },\n    },\n    {\n      field: 'field2',\n      component: 'Input',\n      label: '字段2',\n      colProps: {\n        span: 8,\n      },\n      rules: [{ required: true }],\n      renderComponentContent: () => {\n        return {\n          suffix: () => 'suffix',\n        };\n      },\n    },\n  ];\n  export default defineComponent({\n    components: { BasicForm },\n    setup() {\n      const { createMessage } = useMessage();\n      const [register, { setProps }] = useForm({\n        labelWidth: 120,\n        schemas,\n        actionColOptions: {\n          span: 24,\n        },\n      });\n      return {\n        register,\n        schemas,\n        handleSubmit: (values: any) => {\n          createMessage.success('click search,values:' + JSON.stringify(values));\n        },\n        setProps,\n      };\n    },\n  });\n</script>\n

slot

自定义渲染内容

提示

使用插槽自定义表单域时,请注意 antdv 有关 FormItem 的相关说明

<template>\n  <div class="m-4">\n    <BasicForm @register="register">\n      <template #customSlot="{ model, field }">\n        <a-input v-model:value="model[field]" />\n      </template>\n    </BasicForm>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'compatible-vue';\n  import { BasicForm, useForm } from '@/components/Form/index';\n  import { BasicModal } from '@/components/modal/index';\n  export default defineComponent({\n    name: 'FormDemo',\n    setup(props) {\n      const [register] = useForm({\n        labelWidth: 100,\n        actionColOptions: {\n          span: 24,\n        },\n        schemas: [\n          {\n            field: 'field1',\n            label: '字段1',\n            slot: 'customSlot',\n          },\n        ],\n      });\n      return {\n        register,\n      };\n    },\n  });\n</script>\n

ifShow/show/dynamicDisabled

自定义显示/禁用

<template>\n  <div class="m-4">\n    <BasicForm @register="register" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';\n  const schemas: FormSchema[] = [\n    {\n      field: 'field1',\n      component: 'Input',\n      label: '字段1',\n      colProps: {\n        span: 8,\n      },\n      show: ({ values }) => {\n        return !!values.field5;\n      },\n    },\n    {\n      field: 'field2',\n      component: 'Input',\n      label: '字段2',\n      colProps: {\n        span: 8,\n      },\n      ifShow: ({ values }) => {\n        return !!values.field6;\n      },\n    },\n    {\n      field: 'field3',\n      component: 'DatePicker',\n      label: '字段3',\n      colProps: {\n        span: 8,\n      },\n      dynamicDisabled: ({ values }) => {\n        return !!values.field7;\n      },\n    },\n  ];\n\n  export default defineComponent({\n    components: { BasicForm },\n    setup() {\n      const [register, { setProps }] = useForm({\n        labelWidth: 120,\n        schemas,\n        actionColOptions: {\n          span: 24,\n        },\n      });\n      return {\n        register,\n        schemas,\n        setProps,\n      };\n    },\n  });\n</script>\n

antv form

Slots

名称说明
formFooter表单底部区域
formHeader表单顶部区域
resetBefore重置按钮前
submitBefore提交按钮前
advanceBefore展开按钮前
advanceAfter展开按钮后

ApiSelect

远程下拉加载组件,该组件可以用于学习参考如何自定义组件集成到 Form 组件内,将自定义组件交由 Form 去管理

Usage

const schemas: FormSchema[] = [\n  {\n    field: 'field',\n    component: 'ApiSelect',\n    label: '字段',\n  },\n];\n

Props

属性类型默认值说明
numberToStringbooleanfalse是否将number值转化为string
api()=>Promise<{ label: string; value: string; disabled?: boolean }[]>-数据接口,接受一个 Promise 对象
paramsobject-接口参数。此属性改变时会自动重新加载接口数据
resultFieldstring-接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式
labelFieldstringlabel下拉数组项内label显示文本的字段,支持x.x.x格式
valueFieldstringvalue下拉数组项内value实际值的字段,支持x.x.x格式
immediatebooleantrue是否立即请求接口,否则将在第一次点击时候触发请求

ApiTreeSelect

远程下拉树加载组件,和ApiSelect类似,2.6.1 以上版本

Props

属性类型默认值说明
api()=>Promise<{ label: string; value: string; children?: any[] }[]>-数据接口,接受一个 Promise 对象
paramsobject-接口参数。此属性改变时会自动重新加载接口数据
resultFieldstring-接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式
immediatebooleantrue是否立即请求接口。

RadioButtonGroup

Radio Button 风格的选择按钮

Usage

const schemas: FormSchema[] = [\n  {\n    field: 'field',\n    component: 'RadioButtonGroup',\n    label: '字段',\n  },\n];\n

Props

属性类型默认值说明
options{ label: string; value: string; disabled?: boolean }[]-数据字段
',133);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_form.md.3e11ed4d.lean.js b/assets/components_form.md.3e11ed4d.lean.js new file mode 100644 index 00000000..4cd061ab --- /dev/null +++ b/assets/components_form.md.3e11ed4d.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Form 表单组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"useForm 方式","slug":"useform-方式"},{"level":3,"title":"template 方式","slug":"template-方式"},{"level":2,"title":"useForm","slug":"useform"},{"level":3,"title":"示例","slug":"示例"},{"level":3,"title":"参数介绍","slug":"参数介绍"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"ColEx","slug":"colex"},{"level":3,"title":"ActionButtonOption","slug":"actionbuttonoption"},{"level":3,"title":"fieldMapToTime","slug":"fieldmaptotime"},{"level":3,"title":"FormSchema","slug":"formschema"},{"level":3,"title":"Divider schema 说明","slug":"divider-schema-说明"},{"level":2,"title":"自行添加需要的组件类型","slug":"自行添加需要的组件类型"},{"level":3,"title":"方式 1","slug":"方式-1"},{"level":3,"title":"方式 2","slug":"方式-2"},{"level":3,"title":"render","slug":"render"},{"level":3,"title":"slot","slug":"slot"},{"level":3,"title":"ifShow/show/dynamicDisabled","slug":"ifshow-show-dynamicdisabled"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"ApiSelect","slug":"apiselect"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"ApiTreeSelect","slug":"apitreeselect"},{"level":3,"title":"Props","slug":"props-2"},{"level":2,"title":"RadioButtonGroup","slug":"radiobuttongroup"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-3"}],"relativePath":"components/form.md","lastUpdated":1697592578589}',p={},o=a('',133);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_context-menu.md.3bd48599.js b/assets/components_functional_context-menu.md.3bd48599.js new file mode 100644 index 00000000..bbd312c5 --- /dev/null +++ b/assets/components_functional_context-menu.md.3bd48599.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"ContextMenu","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"createContextMenu","slug":"createcontextmenu"}],"relativePath":"components/functional/context-menu.md","lastUpdated":1697592578589}',p={},o=a('

ContextMenu

函数式创建右键菜单组件, 只要能拿到 dom 的 event 对象就能为其创建右键菜单。

Usage

<template>\n  <div>\n    <a-button type="primary" @contextmenu="handleContext">Right Click on me</a-button>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { useContextMenu } from '/@/hooks/web/useContextMenu';\n  import { CollapseContainer } from '/@/components/Container';\n  import { useMessage } from '/@/hooks/web/useMessage';\n  export default defineComponent({\n    components: { CollapseContainer },\n    setup() {\n      const [createContextMenu] = useContextMenu();\n      const { createMessage } = useMessage();\n      function handleContext(e: MouseEvent) {\n        createContextMenu({\n          event: e,\n          items: [\n            {\n              label: 'New',\n              icon: 'ant-design:plus-outlined',\n              handler: () => {\n                createMessage.success('click new');\n              },\n            },\n            {\n              label: 'Open',\n              icon: 'ant-design:folder-open-filled',\n              handler: () => {\n                createMessage.success('click open');\n              },\n            },\n          ],\n        });\n      }\n      return { handleContext };\n    },\n  });\n</script>\n

createContextMenu

Options

属性类型默认值可选值说明
eventEvent--需要创建的 dom 的 Event 对象
itemsContextMenuItem[]--右键菜单列表,ContextMenuItem见下方说明

ContextMenuItem

属性类型说明
labelstring文本
iconstring图标,参考图标组件
disabledboolean是否禁用
handler()=>void点击触发函数
',9);p.render=function(a,t,p,e,c,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_context-menu.md.3bd48599.lean.js b/assets/components_functional_context-menu.md.3bd48599.lean.js new file mode 100644 index 00000000..89b6dbc3 --- /dev/null +++ b/assets/components_functional_context-menu.md.3bd48599.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"ContextMenu","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"createContextMenu","slug":"createcontextmenu"}],"relativePath":"components/functional/context-menu.md","lastUpdated":1697592578589}',p={},o=a('',9);p.render=function(a,t,p,e,c,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_loading.md.8cd1f253.js b/assets/components_functional_loading.md.8cd1f253.js new file mode 100644 index 00000000..eee3c049 --- /dev/null +++ b/assets/components_functional_loading.md.8cd1f253.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Loading","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useLoading","slug":"useloading"},{"level":3,"title":"UseLoadingOptions","slug":"useloadingoptions"},{"level":3,"title":"LoadingProps","slug":"loadingprops"},{"level":3,"title":"返回值","slug":"返回值"}],"relativePath":"components/functional/loading.md","lastUpdated":1697592578589}',p={},o=s('

Loading

Usage

<template>\n  <div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">\n    <a-alert message="函数方式" />\n\n    <a-button class="my-4 mr-4" type="primary" @click="openFnFullLoading">全屏 Loading</a-button>\n    <a-button class="my-4" type="primary" @click="openFnWrapLoading">容器内 Loading</a-button>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, reactive, toRefs, ref } from 'vue';\n  import { Loading, useLoading } from '/@/components/Loading';\n  export default defineComponent({\n    components: { Loading },\n    setup() {\n      const [openFullLoading, closeFullLoading] = useLoading({\n        tip: '加载中...',\n      });\n\n      const [openWrapLoading, closeWrapLoading] = useLoading({\n        target: wrapEl,\n        props: {\n          tip: '加载中...',\n          absolute: true,\n        },\n      });\n\n      function openFnFullLoading() {\n        openFullLoading();\n\n        setTimeout(() => {\n          closeFullLoading();\n        }, 2000);\n      }\n\n      function openFnWrapLoading() {\n        openWrapLoading();\n\n        setTimeout(() => {\n          closeWrapLoading();\n        }, 2000);\n      }\n\n      return {\n        openFnFullLoading,\n        openFnWrapLoading,\n        ...toRefs(compState),\n      };\n    },\n  });\n</script>\n

useLoading

使用

import { useLoading } from '/@/components/Loading';\n\nconst [open, close, setTip] = useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOptions>);\n

UseLoadingOptions

属性类型默认值可选值说明
targetHTMLElement or Ref<HTMLElement>--挂载的 dom 节点
propsLoadingProps--loading 组件参数

LoadingProps

属性类型默认值可选值说明
tipstring--加载文本
sizedefault, small , largedefault-大小
absolutebooleanfalse-绝对定位,为 false 时可以全屏
loadingboolean--当前加载状态
backgroundstring--背景色,
theme'dark' or 'light'light-背景色主题 ,当背景色不为空时使用背景色

返回值

open

打开 loading

close

关闭 loading

setTip

设置加在提示文案(v2.6.2以上版本)

',17);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_loading.md.8cd1f253.lean.js b/assets/components_functional_loading.md.8cd1f253.lean.js new file mode 100644 index 00000000..e3ec1af6 --- /dev/null +++ b/assets/components_functional_loading.md.8cd1f253.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Loading","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useLoading","slug":"useloading"},{"level":3,"title":"UseLoadingOptions","slug":"useloadingoptions"},{"level":3,"title":"LoadingProps","slug":"loadingprops"},{"level":3,"title":"返回值","slug":"返回值"}],"relativePath":"components/functional/loading.md","lastUpdated":1697592578589}',p={},o=s('',17);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_preview.md.6a63f787.js b/assets/components_functional_preview.md.6a63f787.js new file mode 100644 index 00000000..2cce634d --- /dev/null +++ b/assets/components_functional_preview.md.6a63f787.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Preview","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"createImgPreview","slug":"createimgpreview"},{"level":3,"title":"参数/Options","slug":"参数-options"},{"level":3,"title":"返回值/PreviewActions","slug":"返回值-previewactions"}],"relativePath":"components/functional/preview.md","lastUpdated":1697592578589}',p={},o=s('

Preview

将图片预览组件组件函数化。通过函数方便创建组件

Usage

<template>\n  <div class="p-4">\n    <Alert message="有预览图" type="info" />\n    <div class="flex justify-center mt-4">\n      <img :src="img" v-for="img in imgList" :key="img" class="mr-2" @click="handleClick(img)" />\n    </div>\n    <Alert message="无预览图" type="info" />\n    <a-button @click="handlePreview" type="primary" class="mt-4">预览图片</a-button>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { Alert } from 'ant-design-vue';\n  import { createImgPreview } from '/@/components/Preview/index';\n  const imgList: string[] = [\n    'https://picsum.photos/id/66/346/216',\n    'https://picsum.photos/id/67/346/216',\n    'https://picsum.photos/id/68/346/216',\n  ];\n  export default defineComponent({\n    components: { Alert },\n    setup() {\n      function handleClick(img: string) {\n        createImgPreview({ imageList: [img] });\n      }\n\n      function handlePreview() {\n        createImgPreview({ imageList: imgList });\n      }\n      return { imgList, handleClick, handlePreview };\n    },\n  });\n</script>\n

createImgPreview

参数/Options

属性类型默认值可选值说明
imgListstring[]--图片列表
indexnumber0-初始预览时的图片索引
scaleStepnumber--缩放步进值(每次缩放的幅度)。默认为自动(当前缩放值的10%)
defaultWidthnumber--默认宽度(单位px)。当提供此值时,所有图片初始时都会被缩放至此宽度
maskClosablebooleanfalsetrue/false点击遮罩时是否自动关闭预览
rememberStatebooleanfalsetrue/false是否记住每张图片各自的缩放状态
onImgLoad({ index: number, url: string, dom: HTMLImageElement }) => void--图片加载成功时的回调函数
onImgError({ index: number, url: string, dom: HTMLImageElement }) => void--图片加载失败时的回调函数

返回值/PreviewActions

可用于控制当前预览状态

interface PreviewActions {\n  // 重置状态\n  resume: () => void;\n  // 关闭预览\n  close: () => void;\n  // 显示前一张\n  prev: () => void;\n  // 显示后一张\n  next: () => void;\n  // 设置缩放比例(针对当前图片)\n  setScale: (scale: number) => void;\n  // 设置旋转角度(针对当前图片)\n  setRotate: (rotate: number) => void;\n}\n
',10);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_functional_preview.md.6a63f787.lean.js b/assets/components_functional_preview.md.6a63f787.lean.js new file mode 100644 index 00000000..3118b2ef --- /dev/null +++ b/assets/components_functional_preview.md.6a63f787.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Preview","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"createImgPreview","slug":"createimgpreview"},{"level":3,"title":"参数/Options","slug":"参数-options"},{"level":3,"title":"返回值/PreviewActions","slug":"返回值-previewactions"}],"relativePath":"components/functional/preview.md","lastUpdated":1697592578589}',p={},o=s('',10);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_glob_button.md.30d4499c.js b/assets/components_glob_button.md.30d4499c.js new file mode 100644 index 00000000..cb614e69 --- /dev/null +++ b/assets/components_glob_button.md.30d4499c.js @@ -0,0 +1 @@ +import{o as t,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"button 按钮","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/glob/button.md","lastUpdated":1697592578589}',o={},p=n('

button 按钮

二次封装按钮组件,且使用相同的组件名替换全局的 a-button 组件

TIP

  • 按钮不需要 import,已经全局注册,直接使用 a-button 标签即可
  • 如果是 Tsx 文件,需要手动 import

Usage

<template>\n  <a-button color="success">成功按钮</a-button>\n  <a-button color="error">错误按钮</a-button>\n  <a-button color="warning">警告按钮</a-button>\n</template>\n

Props

提示

保持 ant design button 组件 原有功能的情况下扩展以下属性

属性类型默认值说明
color'error','warning', 'success'-按钮的颜色场景状态颜色,
preIconstring-按钮文本前图标,参考 Icon 组件
postIconstring-按钮文本后图标,参考 Icon 组件
iconSizenumber14按钮图标大小
',8);o.render=function(n,s,o,e,c,l){return t(),a("div",null,[p])};export default o;export{s as __pageData}; diff --git a/assets/components_glob_button.md.30d4499c.lean.js b/assets/components_glob_button.md.30d4499c.lean.js new file mode 100644 index 00000000..76612889 --- /dev/null +++ b/assets/components_glob_button.md.30d4499c.lean.js @@ -0,0 +1 @@ +import{o as t,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"button 按钮","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/glob/button.md","lastUpdated":1697592578589}',o={},p=n('',8);o.render=function(n,s,o,e,c,l){return t(),a("div",null,[p])};export default o;export{s as __pageData}; diff --git a/assets/components_icon.md.59ee5f53.js b/assets/components_icon.md.59ee5f53.js new file mode 100644 index 00000000..01251456 --- /dev/null +++ b/assets/components_icon.md.59ee5f53.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"icon 图标组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Icon","slug":"icon"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"SvgIcon","slug":"svgicon"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"IconPicker","slug":"iconpicker"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-2"}],"relativePath":"components/icon.md","lastUpdated":1697592578589}',p={},o=a('

icon 图标组件

Icon

用于项目内组件的展示,基本支持所有图标库(支持按需加载,只打包所用到的图标)

icon 组件位于 src/components/Icon

TIP

icon 的值可以在 IconifyNetlify 上查询

Usage

<template>\n  <Icon icon="gg:loadbar-doc"></Icon>\n</template>\n\n<script>\n  import { defineComponent } from 'vue';\n  import { Icon } from '/@/components/Icon';\n  export default defineComponent({\n    components: { Icon },\n  });\n</script>\n

Props

属性类型默认值说明
iconstring-图标名
colorstring-图标颜色
sizenumber16图标大小
prefixstring-图标前缀

提示

如果 icon 值以 |svg 结尾,则会渲染成 SvgIcon 组件

SvgIcon

用于使用项目 svg 雪碧图

Usage

<template>\n  <div>\n    <SvgIcon name="test"> </SvgIcon>\n  </div>\n</template>\n<script>\n  import { SvgIcon } from '/@/components/Icon';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { SvgIcon },\n  });\n</script>\n

Props

属性类型默认值说明
namestring-svg 图标名
sizenumber16图标大小

IconPicker

本组件详细说明请参阅图标选择器

Usage

<template>\n  <div>\n    <IconPicker />\n  </div>\n</template>\n<script>\n  import { IconPicker } from '/@/components/Icon';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { IconPicker },\n  });\n</script>\n

Props

属性类型默认值说明
widthstring100%宽度
pageSizenumber140每页显示的图标数
copybooleanfalse是否可以复制
modestringiconify备选图标池,为 svg 时,会读取所有 svg sprite 图标。详见下方说明

mode 说明

  • modeiconify时,会使用预生成的图标集数据作为备选图标池
  • modesvg时,会使用 /src/assets/icons 下的所有svg图标(可包含一级子目录)作为备选图标池,详见vite-plugin-svg-icons
',23);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_icon.md.59ee5f53.lean.js b/assets/components_icon.md.59ee5f53.lean.js new file mode 100644 index 00000000..b9f42910 --- /dev/null +++ b/assets/components_icon.md.59ee5f53.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"icon 图标组件","description":"","frontmatter":{},"headers":[{"level":2,"title":"Icon","slug":"icon"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":2,"title":"SvgIcon","slug":"svgicon"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Props","slug":"props-1"},{"level":2,"title":"IconPicker","slug":"iconpicker"},{"level":3,"title":"Usage","slug":"usage-2"},{"level":3,"title":"Props","slug":"props-2"}],"relativePath":"components/icon.md","lastUpdated":1697592578589}',p={},o=a('',23);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_introduction.md.d908af44.js b/assets/components_introduction.md.d908af44.js new file mode 100644 index 00000000..5f3e1710 --- /dev/null +++ b/assets/components_introduction.md.d908af44.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"前言","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"}],"relativePath":"components/introduction.md","lastUpdated":1697592578589}',p={},o=s('

前言

注意事项

组件的 defaultXXX 属性不要使用,ant-design-vue 2.2 版本之后将会逐步移除。二次封装的组件也不兼容 defaultXXX 属性。

Usage

该项目的组件大部分没有进行全局注册。采用了按需引入注册方式,如下

<template>\n  <ConfigProvider>\n    <router-view />\n  </ConfigProvider>\n</template>\n\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { ConfigProvider } from 'ant-design-vue';\n  export default defineComponent({\n    name: 'App',\n    components: { ConfigProvider },\n  });\n</script>\n
',5);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_introduction.md.d908af44.lean.js b/assets/components_introduction.md.d908af44.lean.js new file mode 100644 index 00000000..0de261a8 --- /dev/null +++ b/assets/components_introduction.md.d908af44.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"前言","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"}],"relativePath":"components/introduction.md","lastUpdated":1697592578589}',p={},o=s('',5);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_json-preview.md.ca86822d.js b/assets/components_json-preview.md.ca86822d.js new file mode 100644 index 00000000..bcc0f96a --- /dev/null +++ b/assets/components_json-preview.md.ca86822d.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"JsonPreview","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/json-preview.md","lastUpdated":1697592578589}',p={},o=s('

JsonPreview

json 数据预览组件

Usage

<template>\n  <JsonPreview :data="data" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { JsonPreview } from '/@/components/CodeEditor';\n\n  export default defineComponent({\n    components: { JsonPreview },\n    setup() {\n      return {\n        data: {},\n      };\n    },\n  });\n</script>\n

Props

属性类型默认值可选值说明
dataobject--需要预览的 Json 数据
',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_json-preview.md.ca86822d.lean.js b/assets/components_json-preview.md.ca86822d.lean.js new file mode 100644 index 00000000..82fe3e4a --- /dev/null +++ b/assets/components_json-preview.md.ca86822d.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"JsonPreview","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/json-preview.md","lastUpdated":1697592578589}',p={},o=s('',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_lazy-container.md.7fe04b3b.js b/assets/components_lazy-container.md.7fe04b3b.js new file mode 100644 index 00000000..2a4fa862 --- /dev/null +++ b/assets/components_lazy-container.md.7fe04b3b.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"LazyContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/lazy-container.md","lastUpdated":1697592578589}',p={},o=s('

LazyContainer

延时加载/懒加载组件, 只在组件可见或者延迟一段时间才进行加载

Usage

<template>\n  <div class="p-4 lazy-base-demo">\n    <div class="lazy-base-demo-wrap">\n      <h1>向下滚动</h1>\n      <LazyContainer @init="() => {}">\n        <TargetContent />\n        <template #skeleton>\n          <Skeleton :rows="10" />\n        </template>\n      </LazyContainer>\n    </div>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { Skeleton } from 'ant-design-vue';\n  import TargetContent from './TargetContent.vue';\n  import { LazyContainer } from '/@/components/Container/index';\n  export default defineComponent({\n    components: { LazyContainer, TargetContent, Skeleton },\n  });\n</script>\n<style lang="less" scoped>\n  .lazy-base-demo {\n    &-wrap {\n      display: flex;\n      width: 50%;\n      height: 2000px;\n      margin: 20px auto;\n      text-align: center;\n      background: #fff;\n      justify-content: center;\n      flex-direction: column;\n      align-items: center;\n    }\n\n    h1 {\n      height: 1300px;\n      margin: 20px 0;\n    }\n  }\n</style>\n

Props

属性类型默认值可选值说明
timeoutnumber--等待时间,如果指定了时间,不论可见与否,在指定时间之后自动加载
viewportHTMLElement--组件所在的视口,如果组件是在页面容器内滚动,视口就是该容器
thresholdstring0px-预加载阈值, css 单位
direction'vertical', 'horizontal' , vertical-视口的滚动方向, vertical 代表垂直方向,horizontal 代表水平方向
tagstring'div-包裹组件的外层容器的标签名
transitionNamestring'lazy-container-transition 动画 name
maxWaitingTimenumber'80-最大等待时间

Events

事件回调参数说明
init()=>void初始化之后

Slots

名称说明
default默认区域
skeleton懒加载骨架屏
',10);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_lazy-container.md.7fe04b3b.lean.js b/assets/components_lazy-container.md.7fe04b3b.lean.js new file mode 100644 index 00000000..6d52edb5 --- /dev/null +++ b/assets/components_lazy-container.md.7fe04b3b.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"LazyContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/lazy-container.md","lastUpdated":1697592578589}',p={},o=s('',10);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_loading.md.9345e82a.js b/assets/components_loading.md.9345e82a.js new file mode 100644 index 00000000..8597d5c3 --- /dev/null +++ b/assets/components_loading.md.9345e82a.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Loading","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"}],"relativePath":"components/loading.md","lastUpdated":1697592578589}',p={},o=s('

Loading

Usage

<template>\n  <div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">\n    <a-button class="my-4 mr-4" type="primary" @click="openCompFullLoading">全屏 Loading</a-button>\n    <a-button class="my-4" type="primary" @click="openCompAbsolute">容器内 Loading</a-button>\n    <Loading :loading="loading" :absolute="absolute" :tip="tip" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, reactive, toRefs, ref } from 'vue';\n  import { Loading } from '/@/components/Loading';\n  export default defineComponent({\n    components: { Loading },\n    setup() {\n      const compState = reactive({\n        absolute: false,\n        loading: false,\n        tip: '加载中...',\n      });\n\n      function openLoading(absolute: boolean) {\n        compState.absolute = absolute;\n        compState.loading = true;\n        setTimeout(() => {\n          compState.loading = false;\n        }, 2000);\n      }\n\n      function openCompFullLoading() {\n        openLoading(false);\n      }\n\n      function openCompAbsolute() {\n        openLoading(true);\n      }\n\n      return {\n        openCompFullLoading,\n        openCompAbsolute,\n        ...toRefs(compState),\n      };\n    },\n  });\n</script>\n

Props

属性类型默认值可选值说明
tipstring--加载文本
sizedefault, small , largedefault-大小
absolutebooleanfalse-绝对定位,为 false 时可以全屏
loadingboolean--当前加载状态
backgroundstring--背景色
theme'dark' or 'light'light-背景色主题,当背景色不为空时使用背景色
',5);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_loading.md.9345e82a.lean.js b/assets/components_loading.md.9345e82a.lean.js new file mode 100644 index 00000000..1e23e116 --- /dev/null +++ b/assets/components_loading.md.9345e82a.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Loading","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"}],"relativePath":"components/loading.md","lastUpdated":1697592578589}',p={},o=s('',5);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_markdown.md.12502c77.js b/assets/components_markdown.md.12502c77.js new file mode 100644 index 00000000..5948062e --- /dev/null +++ b/assets/components_markdown.md.12502c77.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Markdown","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"Methods","slug":"methods"}],"relativePath":"components/markdown.md","lastUpdated":1697592578589}',p={},o=s('

Markdown

基于 Vditor 的 MarkDown 编辑器

Usage

<template>\n  <div class="p-4">\n    <a-button @click="toggleTheme" class="mb-2" type="primary">黑暗主题</a-button>\n    <MarkDown v-model:value="value" ref="markDownRef" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref, unref } from 'vue';\n  import { MarkDown, MarkDownActionType } from '/@/components/Markdown';\n  export default defineComponent({\n    components: { MarkDown },\n    setup() {\n      const markDownRef = ref<Nullable<MarkDownActionType>>(null);\n      const valueRef = ref(`\n# title\n\n# content\n`);\n\n      function toggleTheme() {\n        const markDown = unref(markDownRef);\n        if (!markDown) return;\n        const vditor = markDown.getVditor();\n        vditor.setTheme('dark');\n      }\n      return {\n        value: valueRef,\n        toggleTheme,\n        markDownRef,\n      };\n    },\n  });\n</script>\n

Props

TIP

除以下两个外,props 还可以传入 vidtor 的所有属性。可用 v-bind 统一绑定

属性类型默认值可选值说明
v-modelstring--双向绑定文本值
heightnumber--高度

Methods

名称回调参数说明
getVditorFunction获取 vditor 实例
',9);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_markdown.md.12502c77.lean.js b/assets/components_markdown.md.12502c77.lean.js new file mode 100644 index 00000000..ab0a3c45 --- /dev/null +++ b/assets/components_markdown.md.12502c77.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Markdown","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"Methods","slug":"methods"}],"relativePath":"components/markdown.md","lastUpdated":1697592578589}',p={},o=s('',9);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_modal.md.ab172b28.js b/assets/components_modal.md.ab172b28.js new file mode 100644 index 00000000..a14f9fea --- /dev/null +++ b/assets/components_modal.md.ab172b28.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Modal 弹窗","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useModal","slug":"usemodal"},{"level":2,"title":"useModalInner","slug":"usemodalinner"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/modal.md","lastUpdated":1697592578589}',p={},o=s('

Modal 弹窗

对 antv 的 modal 组件进行封装,扩展拖拽,全屏,自适应高度等功能

代码路径 src/components/Modal

Usage

由于弹窗内代码一般作为单文件组件存在,也推荐这样做,所以示例都为单文件组件形式

TIP

注意 v-bind="$attrs"记得写,用于将弹窗组件的 attribute 传入 BasicModal 组件

// Modal.vue\n<template>\n  <BasicModal v-bind="$attrs" title="Modal Title" :helpMessage="['提示1', '提示2']">\n    Modal Info.\n  </BasicModal>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicModal } from '/@/components/Modal';\n  export default defineComponent({\n    components: { BasicModal },\n    setup() {\n      return {};\n    },\n  });\n</script>\n

页面引用弹窗

// Page.vue\n<template>\n  <div class="px-10">\n    <Modal @register="register" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { useModal } from '/@/components/Modal';\n  import Modal from './Modal.vue';\n  export default defineComponent({\n    components: { Modal },\n    setup() {\n      const [register, { openModal }] = useModal();\n      return {\n        register,\n        openModal,\n      };\n    },\n  });\n</script>\n

useModal

用于外部组件调用

useModal 用于操作组件

const [register, { openModal, setModalProps }] = useModal();\n

register

register 用于注册 useModal,如果需要使用 useModal 提供的 api,必须将 register 传入组件的 onRegister

原理其实很简单,就是 vue 的组件子传父通信,内部通过 emit("register",instance) 实现。

同时独立出去的组件需要将 attrs 绑定到 BasicModal 上面。

<template>\n  <BasicModal v-bind="$attrs"></BasicModal>\n</template>\n

openModal

用于打开/关闭弹窗

// true/false: 打开关闭弹窗\n// data: 传递到子组件的数据\nopenModal(true, data);\n

closeModal

用于关闭弹窗

closeModal();\n

setModalProps

用于更改 modal 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setModalProps 方便更改内部 modal 的 props

Props 内容可以见下方

setModalProps(props);\n

useModalInner

用于独立的 Modal 内部调用

Usage

<template>\n  <BasicModal\n    v-bind="$attrs"\n    @register="register"\n    title="Modal Title"\n    :helpMessage="['提示1', '提示2']"\n  >\n    <a-button type="primary" @click="closeModal" class="mr-2">从内部关闭弹窗</a-button>\n\n    <a-button type="primary" @click="setModalProps">从内部修改title</a-button>\n  </BasicModal>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicModal, useModalInner } from '/@/components/Modal';\n  export default defineComponent({\n    components: { BasicModal },\n    setup() {\n      const [register, { closeModal, setModalProps }] = useModalInner();\n      return {\n        register,\n        closeModal,\n        setModalProps: () => {\n          setModalProps({ title: 'Modal New Title' });\n        },\n      };\n    },\n  });\n</script>\n

useModalInner用于操作独立组件

const [register, { closeModal, setModalProps }] = useModalInner(callback);\n

callback

type: (data:any)=>void

回调函数用于接收 openModal 第二个参数传递的值

useModal((data: any) => {\n  console.log(data);\n});\n

closeModal

用于关闭弹窗

closeModal();\n

changeOkLoading

用于修改确认按钮的 loading 状态

changeOkLoading(true);\n

changeLoading

用于修改 modal 的 loading 状态

// true or false\nchangeLoading(true);\n

setModalProps

用于更改 modal 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setModalProps 方便更改内部 modal 的 props

Props 内容可以见下方

Props

TIP

除以下参数外,组件库文档内的 props 也都支持,具体可以参考 antv modal

属性类型默认值可选值说明
titlestring--modal 标题
heightnumber--固定 modal 的高度
minHeightnumber--设置 modal 的最小高度
draggablebooleantruetrue/false是否开启拖拽
useWrapperbooleantruetrue/false是否开启自适应高度,开启后会跟随屏幕变化自适应内容,并出现滚动条
wrapperFooterOffsetnumber0-开启是适应高度后,如果超过屏幕高度,底部和顶部会保持一样的间距,该参数可以用来缩小底部的间距
canFullscreenbooleantruetrue/false是否可以进行全屏
defaultFullscreenbooleanfalsetrue/false默认全屏
loadingbooleanfalsetrue/falseloading 状态
loadingTipstring--loading 文本
showCancelBtnbooleantruetrue/false显示关闭按钮
showOkBtnbooleantruetrue/false显示确认按钮
helpMessagestring , string[]--标题右侧提示文本
centeredbooleanfalsetrue/false是否居中弹窗
cancelTextstring'关闭'-关闭按钮文本
okTextstring'保存'-确认按钮文本
closeFunc() => Promise<boolean>关闭函数-关闭前执行,返回 true 则关闭,否则不关闭

Events

事件回调参数说明
okfunction(e)点击确定回调
cancelfunction(e)点击取消回调
visible-change(visible:boolean)=>{}打开或者关闭触发

Slots

名称说明
default默认区域
footer底部区域(会替换掉默认的按钮)
insertFooter关闭按钮的左边(不使用footer插槽时有效)
centerFooter关闭按钮和确认按钮的中间(不使用footer插槽时有效)
appendFooter确认按钮的右边(不使用footer插槽时有效)
',57);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_modal.md.ab172b28.lean.js b/assets/components_modal.md.ab172b28.lean.js new file mode 100644 index 00000000..946e822c --- /dev/null +++ b/assets/components_modal.md.ab172b28.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Modal 弹窗","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"useModal","slug":"usemodal"},{"level":2,"title":"useModalInner","slug":"usemodalinner"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/modal.md","lastUpdated":1697592578589}',p={},o=s('',57);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_page.md.f76be211.js b/assets/components_page.md.f76be211.js new file mode 100644 index 00000000..f1b7ef05 --- /dev/null +++ b/assets/components_page.md.f76be211.js @@ -0,0 +1 @@ +import{o as a,c as n,a as t}from"./app.8cddb23b.js";const s='{"title":"Page","description":"","frontmatter":{},"headers":[{"level":2,"title":"PageWrapper","slug":"pagewrapper"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Slots","slug":"slots"},{"level":2,"title":"PageFooter","slug":"pagefooter"},{"level":3,"title":"使用","slug":"使用"},{"level":3,"title":"Slots","slug":"slots-1"}],"relativePath":"components/page.md","lastUpdated":1697592578589}',p={},e=t('

Page

页面相关组件

PageWrapper

用于包裹页面组件

Usage

<template>\n  <div>\n    <PageWrapper>\n      <template #left>left</template>\n      <template #right>right</template>\n    </PageWrapper>\n  </div>\n</template>\n<script>\n  import { PageWrapper } from '/@/components/Page';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { PageWrapper },\n    setup() {\n      return {};\n    },\n  });\n</script>\n

Props

属性类型默认值说明
titlestring-pageHeader title
dense是否缩小主体区域false为 true 将会取消 padding/margin
contentstring-pageHeader Content 内容
contentStyleobject-主体区域样式
contentClassstring-主体区域 class
contentBackgroundboolean-主体区域背景
contentFullHeightbooleanfalse主体区域是否占满整个屏幕高度
fixedHeightbooleanfalse固定主体区域高度

Slots

pageHeader 的 slot 都支持

名称说明
leftFooterPageFooter 左侧区域
rightFooterPageFooter 右侧区域
headerContentpageHeader 主体内容
default主体区域

用于页面底部工具栏

使用

<template>\n  <div>\n    <PageFooter>\n      <template #left>left</template>\n      <template #right>right</template>\n    </PageFooter>\n  </div>\n</template>\n<script>\n  import { PageFooter } from '/@/components/Page';\n  import { defineComponent } from 'vue';\n  export default defineComponent({\n    components: { PageFooter },\n    setup() {\n      return {};\n    },\n  });\n</script>\n

Slots

名称说明
left左侧区域
right右侧区域
',17);p.render=function(t,s,p,o,c,l){return a(),n("div",null,[e])};export default p;export{s as __pageData}; diff --git a/assets/components_page.md.f76be211.lean.js b/assets/components_page.md.f76be211.lean.js new file mode 100644 index 00000000..a0642ca1 --- /dev/null +++ b/assets/components_page.md.f76be211.lean.js @@ -0,0 +1 @@ +import{o as a,c as n,a as t}from"./app.8cddb23b.js";const s='{"title":"Page","description":"","frontmatter":{},"headers":[{"level":2,"title":"PageWrapper","slug":"pagewrapper"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Slots","slug":"slots"},{"level":2,"title":"PageFooter","slug":"pagefooter"},{"level":3,"title":"使用","slug":"使用"},{"level":3,"title":"Slots","slug":"slots-1"}],"relativePath":"components/page.md","lastUpdated":1697592578589}',p={},e=t('',17);p.render=function(t,s,p,o,c,l){return a(),n("div",null,[e])};export default p;export{s as __pageData}; diff --git a/assets/components_pop-confirm-button.md.e437f662.js b/assets/components_pop-confirm-button.md.e437f662.js new file mode 100644 index 00000000..46209540 --- /dev/null +++ b/assets/components_pop-confirm-button.md.e437f662.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"PopConfirmButton 按钮","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/pop-confirm-button.md","lastUpdated":1697592578589}',p={},o=s('

PopConfirmButton 按钮

带有 PopConfirm 下拉菜单功能的按钮

Usage

<template>\n  <PopConfirmButton>按钮文本</PopConfirmButton>\n</template>\n\n<script>\n  import { defineComponent } from 'vue';\n  import { PopConfirmButton } from '/@/components/Button';\n  export default defineComponent({\n    components: { PopConfirmButton },\n  });\n</script>\n

Props

提示

保持 anv design popconfirm 组件 原有功能的情况下扩展以下属性

属性类型默认值说明
enablebooleantrue是否启用下拉菜单,为 false 则显示默认按钮
',7);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_pop-confirm-button.md.e437f662.lean.js b/assets/components_pop-confirm-button.md.e437f662.lean.js new file mode 100644 index 00000000..c91f1e47 --- /dev/null +++ b/assets/components_pop-confirm-button.md.e437f662.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"PopConfirmButton 按钮","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/pop-confirm-button.md","lastUpdated":1697592578589}',p={},o=s('',7);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_qrcode.md.5d95ff15.js b/assets/components_qrcode.md.5d95ff15.js new file mode 100644 index 00000000..6937b305 --- /dev/null +++ b/assets/components_qrcode.md.5d95ff15.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"QrCode","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Methods","slug":"methods"},{"level":2,"title":"事件","slug":"事件"}],"relativePath":"components/qrcode.md","lastUpdated":1697592578589}',p={},o=a('

QrCode

用于生成二维码的组件

Usage

<template>\n  <QrCode :value="qrCodeUrl" />\n</template>\n<script lang="ts">\n  import { defineComponent, ref, unref } from 'vue';\n  import { QrCode, QrCodeActionType } from '/@/components/Qrcode/index';\n  import LogoImg from '/@/assets/images/logo.png';\n  const qrCodeUrl = 'https://www.vvbin.cn';\n  export default defineComponent({\n    components: { QrCode },\n    setup() {\n      const qrRef = ref<Nullable<QrCodeActionType>>(null);\n      function download() {\n        const qrEl = unref(qrRef);\n        if (!qrEl) return;\n        qrEl.download('文件名');\n      }\n      return {\n        qrCodeUrl,\n        LogoImg,\n        download,\n        qrRef,\n      };\n    },\n  });\n</script>\n<style scoped>\n  .qrcode-demo-item {\n    width: 30%;\n    margin-right: 1%;\n  }\n</style>\n

Props

属性类型默认值可选值说明
valuestring--二维码地址
optionsQRCodeRenderersOptions--二维码配置 ,见 QRCodeRenderersOptions
widthnumber2-宽度
logostring|LogoType--中间 logo 配置,见 LogoType
tag渲染标签canvascanvas | imgimg 不支持内嵌 logo

QRCodeRenderersOptions

/**\n * 定义margin的宽度。.\n * Default: 4\n */\nmargin?: number;\n/**\n * 比例因子。值1表示每个模块1像素(黑点)。\n * Default: 4\n */\nscale?: number;\n/**\n * 为输出图像强制指定宽度。\n * 如果宽度太小而不能包含qr符号,则此选项将被忽略。\n * 优先于规模。\n */\nwidth?: number;\ncolor?: {\n  /**\n   * 暗模块的颜色。值必须为十六进制格式(RGBA).\n   * 注意:深色应始终比color.light暗。.\n   * Default: #000000ff\n   */\n  dark?: string;\n  /**\n   * 照明模块的颜色。值必须为十六进制格式(RGBA).\n   * Default: #ffffffff\n   */\n  light?: string;\n};\n\n

LogoType

{\n  // logo图片\n  src: string;\n  // logo大小\n  logoSize: number;\n  // 背景颜色\n  bgColor: string;\n  // logo圆角\n  logoRadius: number;\n}\n

Methods

名称回调参数说明
downloadFunction(fileName:string)下载

事件

名称回调参数说明
done(data: QrcodeDoneEventParams)=>void绘制完成
error(error)=>void生成二维码时发生错误

QrcodeDoneEventParams

{\n  url: string;  // 二维码DataURL数据\n  ctx?: CanvasRenderingContext2D;  // 该对象为画布的2D渲染上下文,仅在tag为canvas时有效,可用于自定义绘制\n}\n

done 事件回调中可以对二维码进行自定义的绘制,示例代码如下:

<QrCode\n  :value="qrCodeUrl"\n  :width="200"\n  @done="onQrcodeDone"\n/>\n
function onQrcodeDone({ ctx }) {\n  if (ctx instanceof CanvasRenderingContext2D) {\n    // 额外绘制\n    ctx.fillStyle = 'black';\n    ctx.font = '16px "微软雅黑"';\n    ctx.textBaseline = 'bottom';\n    ctx.textAlign = 'center';\n    ctx.fillText('你帅你先扫', 100, 195, 200);\n  }\n}\n

有关 CanvasRenderingContext2D 的更多资料以及绘制方法,请参考MDN

',20);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_qrcode.md.5d95ff15.lean.js b/assets/components_qrcode.md.5d95ff15.lean.js new file mode 100644 index 00000000..a482cf0f --- /dev/null +++ b/assets/components_qrcode.md.5d95ff15.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"QrCode","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Methods","slug":"methods"},{"level":2,"title":"事件","slug":"事件"}],"relativePath":"components/qrcode.md","lastUpdated":1697592578589}',p={},o=a('',20);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_scroll-container.md.cb595324.js b/assets/components_scroll-container.md.cb595324.js new file mode 100644 index 00000000..3f70de98 --- /dev/null +++ b/assets/components_scroll-container.md.cb595324.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"ScrollContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Methods","slug":"methods"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/scroll-container.md","lastUpdated":1697592578589}',p={},o=s('

ScrollContainer

参考 element-ui 的 el-scrollbar 组件实现

滚动容器组件

Usage

<template>\n  <div class="p-4">\n    <div class="my-4">\n      <a-button @click="scrollTo(100)">滚动到100px位置</a-button>\n      <a-button @click="scrollTo(800)">滚动到800px位置</a-button>\n      <a-button @click="scrollTo(0)">滚动到顶部</a-button>\n      <a-button @click="scrollBottom()">滚动到底部</a-button>\n    </div>\n    <div class="scroll-wrap">\n      <ScrollContainer ref="scrollRef">\n        <ul>\n          <template v-for="index in 100" :key="index">\n            <li>{{ index }}</li>\n          </template>\n        </ul>\n      </ScrollContainer>\n    </div>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref, unref } from 'vue';\n  import { CollapseContainer } from '/@/components/Container/index';\n  import { ScrollContainer, ScrollActionType } from '/@/components/Container/index';\n  export default defineComponent({\n    components: { CollapseContainer, ScrollContainer },\n    setup() {\n      const scrollRef = ref<Nullable<ScrollActionType>>(null);\n      const getScroll = () => {\n        const scroll = unref(scrollRef);\n        if (!scroll) {\n          throw new Error('scroll is Null');\n        }\n        return scroll;\n      };\n\n      function scrollTo(top: number) {\n        getScroll()?.scrollTo(top);\n      }\n\n      function scrollBottom() {\n        getScroll()?.scrollBottom();\n      }\n\n      return {\n        scrollTo,\n        scrollRef,\n        scrollBottom,\n      };\n    },\n  });\n</script>\n<style lang="less" scoped>\n  .scroll-wrap {\n    width: 50%;\n    height: 300px;\n    background: #fff;\n  }\n</style>\n

Methods

名称回调参数说明
getScrollWrap()=>HtmlElement获取滚动容器 el
scrollBottomFunction滚动到底部
scrollToFunction(to:number,duration = 500)滚动到指定位置

Slots

名称说明
default默认区域
',9);p.render=function(s,t,p,c,e,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_scroll-container.md.cb595324.lean.js b/assets/components_scroll-container.md.cb595324.lean.js new file mode 100644 index 00000000..5ffdd566 --- /dev/null +++ b/assets/components_scroll-container.md.cb595324.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"ScrollContainer","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Methods","slug":"methods"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/scroll-container.md","lastUpdated":1697592578589}',p={},o=s('',9);p.render=function(s,t,p,c,e,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_strength-meter.md.709cd846.js b/assets/components_strength-meter.md.709cd846.js new file mode 100644 index 00000000..2523f804 --- /dev/null +++ b/assets/components_strength-meter.md.709cd846.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"StrengthMeter","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/strength-meter.md","lastUpdated":1697592578589}',p={},e=s('

StrengthMeter

用于校验密码强度

Usage

<template>\n  <div class="p-4 flex justify-center">\n    <div class="demo-wrap p-10">\n      <StrengthMeter placeholder="默认" />\n      <StrengthMeter placeholder="禁用" disabled />\n      <br />\n      <StrengthMeter placeholder="隐藏input" :show-input="false" value="!@#qwe12345" />\n    </div>\n  </div>\n</template>\n\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import StrengthMeter from '/@/components/StrengthMeter/index';\n  export default defineComponent({\n    components: {\n      StrengthMeter,\n    },\n  });\n</script>\n<style lang="less" scoped>\n  .demo-wrap {\n    width: 50%;\n    background: #fff;\n    border-radius: 10px;\n  }\n</style>\n

Props

属性类型默认值可选值说明
valuestring--校验的值
showInputbooleantrue-是否显示 input
disabledbooleanfalse-是否禁用

Events

事件回调参数说明
score-changenumber强度值改变触发
changestringinput 值改变触发
',8);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_strength-meter.md.709cd846.lean.js b/assets/components_strength-meter.md.709cd846.lean.js new file mode 100644 index 00000000..a2a3ef9b --- /dev/null +++ b/assets/components_strength-meter.md.709cd846.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"StrengthMeter","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/strength-meter.md","lastUpdated":1697592578589}',p={},e=s('',8);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_table.md.3c62f0f9.js b/assets/components_table.md.3c62f0f9.js new file mode 100644 index 00000000..cf66e879 --- /dev/null +++ b/assets/components_table.md.3c62f0f9.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Table 表格","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"示例","slug":"示例"},{"level":3,"title":"template 示例","slug":"template-示例"},{"level":3,"title":"BasicColumn 和 tableAction 通过权限和业务控制显示隐藏的示例","slug":"basiccolumn-和-tableaction-通过权限和业务控制显示隐藏的示例"},{"level":2,"title":"useTable","slug":"usetable"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"TableSetting","slug":"tablesetting"},{"level":2,"title":"BasicColumn","slug":"basiccolumn"},{"level":3,"title":"EditComponentType","slug":"editcomponenttype"},{"level":3,"title":"CellFormat","slug":"cellformat"},{"level":2,"title":"事件","slug":"事件"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"Form-Slots","slug":"form-slots"},{"level":2,"title":"ColumnSetting组件","slug":"columnsetting组件"},{"level":2,"title":"内置组件(只能用于表格内部)","slug":"内置组件(只能用于表格内部)"},{"level":3,"title":"TableAction","slug":"tableaction"},{"level":3,"title":"TableImg","slug":"tableimg"},{"level":2,"title":"全局配置","slug":"全局配置"}],"relativePath":"components/table.md","lastUpdated":1697592578589}',p={},o=s('

Table 表格

antv 的 table 组件进行封装

如果文档内没有,可以尝试在在线示例内寻找

Usage

示例

<template>\n  <div class="p-4">\n    <BasicTable\n      title="基础示例"\n      titleHelpMessage="温馨提醒"\n      :columns="columns"\n      :dataSource="data"\n      :canResize="canResize"\n      :loading="loading"\n      :striped="striped"\n      :bordered="border"\n      :pagination="{ pageSize: 20 }"\n    >\n      <template #toolbar>\n        <a-button type="primary"> 操作按钮 </a-button>\n      </template>\n    </BasicTable>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { BasicTable } from '/@/components/Table';\n  import { getBasicColumns, getBasicData } from './tableData';\n\n  export default defineComponent({\n    components: { BasicTable },\n    setup() {\n      return {\n        columns: getBasicColumns(),\n        data: getBasicData(),\n      };\n    },\n  });\n</script>\n

template 示例

所有可调用函数见下方 Methods 说明

<template>\n  <div class="p-4">\n    <BasicTable\n      :canResize="false"\n      title="RefTable示例"\n      titleHelpMessage="使用Ref调用表格内方法"\n      ref="tableRef"\n      :api="api"\n      :columns="columns"\n      rowKey="id"\n      :rowSelection="{ type: 'checkbox' }"\n    />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref, unref } from 'vue';\n  import { BasicTable, TableActionType } from '/@/components/Table';\n  import { getBasicColumns, getBasicShortColumns } from './tableData';\n  import { demoListApi } from '/@/api/demo/table';\n  export default defineComponent({\n    components: { BasicTable },\n    setup() {\n      const tableRef = ref<Nullable<TableActionType>>(null);\n\n      function getTableAction() {\n        const tableAction = unref(tableRef);\n        if (!tableAction) {\n          throw new Error('tableAction is null');\n        }\n        return tableAction;\n      }\n      function changeLoading() {\n        getTableAction().setLoading(true);\n        setTimeout(() => {\n          getTableAction().setLoading(false);\n        }, 1000);\n      }\n      return {\n        tableRef,\n        api: demoListApi,\n        columns: getBasicColumns(),\n        changeLoading,\n      };\n    },\n  });\n</script>\n

BasicColumn 和 tableAction 通过权限和业务控制显示隐藏的示例

<template>\n  <div class="p-4">\n    <BasicTable @register="registerTable">\n      <template #action="{ record }">\n        <TableAction\n          :actions="[\n            {\n              label: '编辑',\n              onClick: handleEdit.bind(null, record),\n              auth: 'other', // 根据权限控制是否显示: 无权限,不显示\n            },\n            {\n              label: '删除',\n              icon: 'ic:outline-delete-outline',\n              onClick: handleDelete.bind(null, record),\n              auth: 'super', // 根据权限控制是否显示: 有权限,会显示\n            },\n          ]"\n          :dropDownActions="[\n            {\n              label: '启用',\n              popConfirm: {\n                title: '是否启用?',\n                confirm: handleOpen.bind(null, record),\n              },\n              ifShow: (_action) => {\n                return record.status !== 'enable'; // 根据业务控制是否显示: 非enable状态的不显示启用按钮\n              },\n            },\n            {\n              label: '禁用',\n              popConfirm: {\n                title: '是否禁用?',\n                confirm: handleOpen.bind(null, record),\n              },\n              ifShow: () => {\n                return record.status === 'enable'; // 根据业务控制是否显示: enable状态的显示禁用按钮\n              },\n            },\n            {\n              label: '同时控制',\n              popConfirm: {\n                title: '是否动态显示?',\n                confirm: handleOpen.bind(null, record),\n              },\n              auth: 'super', // 同时根据权限和业务控制是否显示\n              ifShow: () => {\n                return true; // 根据业务控制是否显示\n              },\n            },\n          ]"\n        />\n      </template>\n    </BasicTable>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';\n\n  import { demoListApi } from '/@/api/demo/table';\n  const columns: BasicColumn[] = [\n    {\n      title: '姓名',\n      dataIndex: 'name',\n      auth: 'test', // 根据权限控制是否显示: 无权限,不显示\n    },\n    {\n      title: '地址',\n      dataIndex: 'address',\n      auth: 'super', // 同时根据权限控制是否显示\n      ifShow: (_column) => {\n        return true; // 根据业务控制是否显示\n      },\n    },\n  ];\n  export default defineComponent({\n    components: { BasicTable, TableAction },\n    setup() {\n      const [registerTable] = useTable({\n        title: 'TableAction组件及固定列示例',\n        api: demoListApi,\n        columns: columns,\n        bordered: true,\n        actionColumn: {\n          width: 250,\n          title: 'Action',\n          dataIndex: 'action',\n          slots: { customRender: 'action' },\n        },\n      });\n      function handleEdit(record: Recordable) {\n        console.log('点击了编辑', record);\n      }\n      function handleDelete(record: Recordable) {\n        console.log('点击了删除', record);\n      }\n      function handleOpen(record: Recordable) {\n        console.log('点击了启用', record);\n      }\n      return {\n        registerTable,\n        handleEdit,\n        handleDelete,\n        handleOpen,\n      };\n    },\n  });\n</script>\n

useTable

使用组件自带的 useTable 可以方便使用表单

下面是一个使用简单表格的示例,

<template>\n  <BasicTable @register="registerTable" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicTable, useTable } from '/@/components/Table';\n  import { getBasicColumns, getBasicShortColumns } from './tableData';\n  import { demoListApi } from '/@/api/demo/table';\n  export default defineComponent({\n    components: { BasicTable },\n    setup() {\n      const [\n        registerTable,\n        {\n          setLoading,\n        },\n      ] = useTable({\n        api: demoListApi,\n        columns: getBasicColumns(),\n      });\n\n      function changeLoading() {\n        setLoading(true);\n        setTimeout(() => {\n          setLoading(false);\n        }, 1000);\n      }\n      }\n      return {\n        registerTable,\n        changeLoading,\n      };\n    },\n  });\n</script>\n

Usage

用于调用 Table 内部方法及 table 参数配置

// 表格的props也可以直接注册到useTable内部\nconst [register, methods] = useTable(props);\n

register

register 用于注册 useTable,如果需要使用useTable提供的 api,必须将 register 传入组件的 onRegister

<template>\n  <BasicTable @register="register" />\n</template>\n<script>\n  export default defineComponent({\n    components: { BasicForm },\n    setup() {\n      const [register] = useTable();\n      return { register };\n    },\n  });\n</script>\n

Methods

setProps

类型:(props: Partial<BasicTableProps>) => void

说明: 用于设置表格参数

reload

类型:(opt?: FetchParams) => Promise<void>

说明: 刷新表格

redoHeight

类型:() => void

说明: 重新计算表格高度

setLoading

类型:(loading: boolean) => void

说明: 设置表格 loading 状态

getDataSource

获取表格数据

类型:<T = Recordable>() => T[]

说明: 获取表格数据

getRawDataSource

获取后端接口原始数据

类型:<T = Recordable>() => T

说明: 获取后端接口原始数据

getColumns

类型:(opt?: GetColumnsParams) => BasicColumn[]

说明: 获取表格数据

setColumns

类型:(columns: BasicColumn[] | string[]) => void

说明: 设置表头数据

setTableData

类型:<T = Recordable>(values: T[]) => void

说明: 设置表格数据

setPagination

类型:(info: Partial<PaginationProps>) => void

说明: 设置分页信息

deleteSelectRowByKey

类型:(key: string) => void

说明: 根据 key 删除取消选中行

getSelectRowKeys

类型:() => string[]

说明: 获取选中行的 keys

getSelectRows

类型:<T = Recordable>() => T[]

说明: 获取选中行的 rows

clearSelectedRowKeys

类型:() => void

说明: 清空选中行

setSelectedRowKeys

类型:(rowKeys: string[] | number[]) => void

说明: 设置选中行

getPaginationRef

类型:() => PaginationProps | boolean

说明: 获取当前分页信息

getShowPagination

类型:() => boolean

说明: 获取当前是否显示分页

setShowPagination

类型:(show: boolean) => Promise<void>

说明: 设置当前是否显示分页

getRowSelection

类型:() => TableRowSelection<Recordable>

说明: 获取勾选框信息

updateTableData

类型:(index: number, key: string, value: any)=>void

说明: 更新表格数据

updateTableDataRecord

类型: (rowKey: string | number, record: Recordable) => Recordable | void

说明: 根据唯一的 rowKey 更新指定行的数据.可用于不刷新整个表格而局部更新数据

deleteTableDataRecord

类型: (rowKey: string | number | string[] | number[]) => void

说明: 根据唯一的rowKey 动态删除指定行的数据.可用于不刷新整个表格而局部更新数据

insertTableDataRecord

类型: (record: Recordable, index?: number) => Recordable | void

说明: 可根据传入的 index 值决定插入数据行的位置,不传则是顺序插入,可用于不刷新整个表格而局部更新数据

getForm

类型:() => FormActionType

说明: 如果开启了搜索区域。可以通过该函数获取表单对象函数进行操作

expandAll

类型:() => void

说明: 展开树形表格

collapseAll

类型:() => void

说明: 折叠树形表格

Props

温馨提醒

  • 除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv table
  • 注意:defaultExpandAllRowsdefaultExpandedRowKeys 属性在basicTable中不受支持,并且在antv table v2.2.0之后也被移除。
属性类型默认值可选值说明版本
clickToRowSelectbooleantrue-点击行是否选中 checkbox 或者 radio。需要开启
sortFn(sortInfo: SorterResult<any>) => any--自定义排序方法。见下方全局配置说明
filterFn(sortInfo: Partial<Recordable<string[]>>) => any--自定义过滤方法。见下方全局配置说明
showTableSettingbooleanfalse-显示表格设置工具
tableSettingTableSetting--表格设置工具配置,见下方 TableSetting
stripedbooleantrue-斑马纹
insetbooleanfalse-取消表格的默认 padding
autoCreateKeybooleantrue-是否自动生成 key
showSummarybooleanfalse-是否显示合计行
summaryDataany[]--自定义合计数据。如果有则显示该数据
emptyDataIsShowTablebooleantrue-在启用搜索表单的前提下,是否在表格没有数据的时候显示表格
summaryFunc(...arg) => any[]--计算合计行的方法
canRowDragbooleanfalse-是否可拖拽行排序
canColDragbooleanfalse-是否可拖拽列
isTreeTablebooleanfalse-是否树表
api(...arg: any) => Promise<any>--请求接口,可以直接将src/api内的函数直接传入
beforeFetch(T)=>T--请求之前对参数进行处理
afterFetch(T)=>T--请求之后对返回值进行处理
handleSearchInfoFn(T)=>T--开启表单后,在请求之前处理搜索条件参数
fetchSettingFetchSetting--接口请求配置,可以配置请求的字段和响应的字段名,见下方全局配置说明
immediatebooleantrue-组件加载后是否立即请求接口,在 api 有传的情况下,如果为 false,需要自行使用 reload 加载表格数据
searchInfoany--额外的请求参数
useSearchFormbooleanfalse-使用搜索表单
formConfigany--表单配置,参考表单组件的 Props
columnsany--表单列信息 BasicColumn[]
showIndexColumnbooleanture-是否显示序号列
indexColumnPropsany--序号列配置 BasicColumn
actionColumnany--表格右侧操作列配置 BasicColumn
ellipsisbooleantrue-文本超过宽度是否显示...
canResizebooleantrue-是否可以自适应高度(如果置于PageWrapper组件内,请勿启用PageWrapper的fixedHeight属性,二者不可同时使用)
clearSelectOnPageChangebooleanfalse-切换页码是否重置勾选状态
resizeHeightOffsetnumber0-表格自适应高度计算结果会减去这个值
rowSelectionany--选择列配置
titlestring--表格标题
titleHelpMessagestring | string[]--表格标题右侧温馨提醒
maxHeightnumber--表格最大高度,超出会显示滚动条
dataSourceany[]--表格数据,非 api 加载情况
borderedbooleanfalse-是否显示表格边框
paginationany--分页信息配置,为 false 不显示分页
loadingbooleanfalse-表格 loading 状态
scrollany--参考官方文档 scroll
beforeEditSubmit({record: Recordable,index: number,key: string | number,value: any}) => Promise<any>--单元格编辑状态提交回调,返回false将阻止单元格提交数据到table。该回调在行编辑模式下无效。2.7.2

TableSetting

{\n  // 是否显示刷新按钮\n  redo?: boolean;\n  // 是否显示尺寸调整按钮\n  size?: boolean;\n  // 是否显示字段调整按钮\n  setting?: boolean;\n  // 是否显示全屏按钮\n  fullScreen?: boolean;\n}\n

BasicColumn

除 参考官方 Column 配置外,扩展以下参数

属性类型默认值可选值说明
defaultHiddenbooleanfalse-默认隐藏,可在列配置显示
helpMessagestring|string[]--列头右侧帮助文本
editboolean--是否开启单元格编辑
editRowboolean--是否开启行编辑
editablebooleanfalse-是否处于编辑状态
editComponentComponentTypeInput-编辑组件
editComponentPropsany--对应编辑组件的 props
editRule((text: string, record: Recordable) => Promise<string>)--对应编辑组件的表单校验
editValueMap(value: any) => string--对应单元格值枚举
onEditRow()=>void--触发行编辑
formatCellFormat--单元格格式化
authRoleEnumRoleEnum[]stringstring[]--根据权限编码来控制当前列是否显示
ifShowboolean | ((action: ActionItem) => boolean)--根据业务状态来控制当前列是否显示

EditComponentType

export type ComponentType =\n  | 'Input'\n  | 'InputNumber'\n  | 'Select'\n  | 'ApiSelect'\n  | 'Checkbox'\n  | 'Switch'\n  | 'DatePicker'  // v2.5.0 以上\n  | 'TimePicker'; // v2.5.0 以上\n

CellFormat

export type CellFormat =\n  | string\n  | ((text: string, record: Recordable, index: number) => string | number)\n  | Map<string | number, any>;\n

事件

温馨提醒

除以下事件外,官方文档内的 event 也都支持,具体可以参考 antv table

事件回调参数说明
fetch-successFunction({items,total})接口请求成功后触发
fetch-errorFunction(error)错误信息
selection-changeFunction({keys,rows})勾选事件触发
row-clickFunction(record, index, event)行点击触发
row-dbClickFunction(record, index, event)行双击触发
row-contextmenuFunction(record, index, event)行右键触发
row-mouseenterFunction(record, index, event)行移入触发
row-mouseleaveFunction(record, index, event)行移出触发
edit-endFunction({record, index, key, value})单元格编辑完成触发
edit-cancelFunction({record, index, key, value})单元格取消编辑触发
edit-row-endFunction()行编辑结束触发
edit-changeFunction({column,value,record})单元格编辑组件的 value 发生变化时触发

edit-change 说明

从版本 2.4.2 起,对于 edit-change 事件,record 中的 editValueRefs 装载了当前行的所有编辑组件(如果有的话)的值的 ref 对象,可用于处理同一行中的编辑组件的联动。请看下面的例子

      function onEditChange({ column, record }) {\n        // 当同一行的单价或者数量发生变化时,更新合计金额(三个数据均为当前行编辑组件的值)\n        if (column.dataIndex === 'qty' || column.dataIndex === 'price') {\n          const { editValueRefs: { total, qty, price } } = record;\n          total.value = unref(qty) * unref(price);\n        }\n      }\n

Slots

温馨提醒

除以下参数外,官方文档内的 slot 也都支持,具体可以参考 antv table

名称说明版本
tableTitle表格顶部左侧区域
toolbar表格顶部右侧区域
expandedRowRender展开行区域
headerTop表格顶部区域(标题上方)2.6.1

Form-Slots

当开启 form 表单后。以form-xxxx为前缀的 slot 会被视为 form 的 slot

xxxx 为 form 组件的 slot。具体参考form 组件文档

e.g

form-submitBefore\n

ColumnSetting组件

字段调整组件

提供了可视化操作表格每一列的是否展示、位置、固定;包括序号列、勾选列。会响应tableMethodssetColumnssetProps方法的更改内容。

值得注意的是

序号列勾选列是在table的props中定义的,对应的字段分别是showIndexColumnrowSelection。因此在动态改变表格列配置的时候,建议使用setProps方法,并显式地设置这两个字段的值来保证达到预期效果

// ...\nconst [registerTable, { setProps }] = useTable({...})\n\nsetProps({\n  columns: [], // 表格的列配置 BasicColumn[]\n  showIndexColumn: false, // 是否展示序号列\n  rowSelection: false // 勾选列配置\n})\n

内置组件(只能用于表格内部)

TableAction

用于表格右侧操作列渲染

Props

属性类型默认值可选值说明版本
actionsActionItem[]--右侧操作列按钮列表
dropDownActionsActionItem[]--右侧操作列更多下拉按钮列表
stopButtonPropagationbooleanfalsetrue/false是否阻止操作按钮的click事件冒泡2.5.0

ActionItem

export interface ActionItem {\n  // 按钮文本\n  label: string;\n  // 是否禁用\n  disabled?: boolean;\n  // 按钮颜色\n  color?: 'success' | 'error' | 'warning';\n  // 按钮类型\n  type?: string;\n  // button组件props\n  props?: any;\n  // 按钮图标\n  icon?: string;\n  // 气泡确认框\n  popConfirm?: PopConfirm;\n  // 是否显示分隔线,v2.0.0+\n  divider?: boolean;\n  // 根据权限编码来控制当前列是否显示,v2.4.0+\n  auth?: RoleEnum | RoleEnum[] | string | string[];\n  // 根据业务状态来控制当前列是否显示,v2.4.0+\n  ifShow?: boolean | ((action: ActionItem) => boolean);\n  // 点击回调\n  onClick?: Fn;\n  // Tooltip配置,2.5.3以上版本支持,可以配置为string,或者完整的tooltip属性\n  tooltip?: string | TooltipProps\n}\n

有关TooltipProps的说明,请参考tooltip

PopConfirm

export interface PopConfirm {\n  title: string;\n  okText?: string;\n  cancelText?: string;\n  confirm: Fn;\n  cancel?: Fn;\n  icon?: string;\n}\n

TableImg

用于渲染单元格图片,支持图片预览

Props

属性类型默认值可选值说明版本
imgListstring[]--图片地址列表
sizenumber--图片大小
simpleShowbooleanfalsetrue/false简单显示模式(只显示第一张图片)2.5.0
showBadgebooleantruetrue/false简单模式下是否显示计数Badge2.5.0
marginnumber4-常规模式下的图片间距2.5.0
srcPrefixstring--在每一个图片src前插入的内容2.5.0

全局配置

componentsSettings 可以配置全局参数。用于统一整个项目的风格。可以通过 props 传值覆盖

',148);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_table.md.3c62f0f9.lean.js b/assets/components_table.md.3c62f0f9.lean.js new file mode 100644 index 00000000..9d83331e --- /dev/null +++ b/assets/components_table.md.3c62f0f9.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Table 表格","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":3,"title":"示例","slug":"示例"},{"level":3,"title":"template 示例","slug":"template-示例"},{"level":3,"title":"BasicColumn 和 tableAction 通过权限和业务控制显示隐藏的示例","slug":"basiccolumn-和-tableaction-通过权限和业务控制显示隐藏的示例"},{"level":2,"title":"useTable","slug":"usetable"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"Props","slug":"props"},{"level":3,"title":"TableSetting","slug":"tablesetting"},{"level":2,"title":"BasicColumn","slug":"basiccolumn"},{"level":3,"title":"EditComponentType","slug":"editcomponenttype"},{"level":3,"title":"CellFormat","slug":"cellformat"},{"level":2,"title":"事件","slug":"事件"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"Form-Slots","slug":"form-slots"},{"level":2,"title":"ColumnSetting组件","slug":"columnsetting组件"},{"level":2,"title":"内置组件(只能用于表格内部)","slug":"内置组件(只能用于表格内部)"},{"level":3,"title":"TableAction","slug":"tableaction"},{"level":3,"title":"TableImg","slug":"tableimg"},{"level":2,"title":"全局配置","slug":"全局配置"}],"relativePath":"components/table.md","lastUpdated":1697592578589}',p={},o=s('',148);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_time.md.059df4f7.js b/assets/components_time.md.059df4f7.js new file mode 100644 index 00000000..1f74d4b4 --- /dev/null +++ b/assets/components_time.md.059df4f7.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Time","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/time.md","lastUpdated":1697592578589}',p={},o=s('

Time

相对时间组件

Usage

<template>\n  <Time :value="time" />\n</template>\n<script lang="ts">\n  import { defineComponent, reactive, toRefs } from 'vue';\n  import { Time } from '/@/components/Time';\n\n  export default defineComponent({\n    components: { Time },\n    setup() {\n      const now = new Date().getTime();\n      const state = reactive({\n        time: now - 60 * 3 * 1000,\n      });\n      return {\n        ...toRefs(state),\n        now,\n      };\n    },\n  });\n</script>\n

Props

属性类型默认值可选值说明
valuestring,Date,number--时间值
stepnumber60-刷新时间
modestringrelative-模式,date:日期,datetime:时间戳,relative:相对时间
',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_time.md.059df4f7.lean.js b/assets/components_time.md.059df4f7.lean.js new file mode 100644 index 00000000..0df44eb8 --- /dev/null +++ b/assets/components_time.md.059df4f7.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Time","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"}],"relativePath":"components/time.md","lastUpdated":1697592578589}',p={},o=s('',6);p.render=function(s,t,p,e,c,u){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_tinymce.md.bb6dd194.js b/assets/components_tinymce.md.bb6dd194.js new file mode 100644 index 00000000..f34d18e7 --- /dev/null +++ b/assets/components_tinymce.md.bb6dd194.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Tinymce","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/tinymce.md","lastUpdated":1697592578589}',p={},e=s('

Tinymce

富文本组件位于 src/components/TinyMce

富文本组件使用的是 CDN 方式引入

可在 /@/components/TinyMce/src/Editor.vue 更改下面 CDN 地址

const CDN_URL = 'https://cdn.bootcdn.net/ajax/libs/tinymce/5.5.1';\n

Usage

<template>\n  <Tinymce v-model="value" @change="handleChange" width="100%" />\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { Tinymce } from '/@/components/Tinymce/index';\n\n  export default defineComponent({\n    components: { Tinymce },\n    setup() {\n      const value = ref('hello world!');\n      function handleChange(value: string) {\n        console.log(value);\n      }\n      return { handleChange, value };\n    },\n  });\n</script>\n

Props

属性类型默认值说明
optionsany{}tinymce 的配置项
value(v-model)string-双向绑定值
heightnumber , string400高度
widthnumber , stringauto宽度
toolbarstring[]-工具栏
pluginsstring[]-插件
showImageUploadbooleantrue是否显示上传按钮

Events

事件回调参数返回值说明
change(str:string)=>{}富文本内容改变触发事件
',9);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_tinymce.md.bb6dd194.lean.js b/assets/components_tinymce.md.bb6dd194.lean.js new file mode 100644 index 00000000..4288da4f --- /dev/null +++ b/assets/components_tinymce.md.bb6dd194.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"Tinymce","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/tinymce.md","lastUpdated":1697592578589}',p={},e=s('',9);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/components_transition.md.3cc0f9ff.js b/assets/components_transition.md.3cc0f9ff.js new file mode 100644 index 00000000..58e162cc --- /dev/null +++ b/assets/components_transition.md.3cc0f9ff.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Transition","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"}],"relativePath":"components/transition.md","lastUpdated":1697592578589}',p={},o=a('

Transition

用于页面/组件切换动画

Usage

<template>\n  <div class="p-4">\n    <div class="flex">\n      <Select\n        :options="options"\n        v-model:value="value"\n        placeholder="选择动画"\n        :style="{ width: '150px' }"\n      />\n      <a-button type="primary" class="ml-4" @click="start"> start </a-button>\n    </div>\n    <component :is="`${value}Transition`">\n      <div class="box" v-show="show"></div>\n    </component>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { Select } from 'ant-design-vue';\n  import {\n    FadeTransition,\n    ScaleTransition,\n    SlideYTransition,\n    ScrollYTransition,\n    SlideYReverseTransition,\n    ScrollYReverseTransition,\n    SlideXTransition,\n    ScrollXTransition,\n    SlideXReverseTransition,\n    ScrollXReverseTransition,\n    ScaleRotateTransition,\n    ExpandXTransition,\n    ExpandTransition,\n  } from '/@/components/Transition/index';\n\n  const transitionList = [\n    'Fade',\n    'Scale',\n    'SlideY',\n    'ScrollY',\n    'SlideYReverse',\n    'ScrollYReverse',\n    'SlideX',\n    'ScrollX',\n    'SlideXReverse',\n    'ScrollXReverse',\n    'ScaleRotate',\n    'ExpandX',\n    'Expand',\n  ];\n  const options = transitionList.map((item) => ({\n    label: item,\n    value: item,\n    key: item,\n  }));\n\n  export default defineComponent({\n    components: {\n      Select,\n      FadeTransition,\n      ScaleTransition,\n      SlideYTransition,\n      ScrollYTransition,\n      SlideYReverseTransition,\n      ScrollYReverseTransition,\n      SlideXTransition,\n      ScrollXTransition,\n      SlideXReverseTransition,\n      ScrollXReverseTransition,\n      ScaleRotateTransition,\n      ExpandXTransition,\n      ExpandTransition,\n    },\n    setup() {\n      const value = ref('Fade');\n      const show = ref(true);\n      function start() {\n        show.value = false;\n        setTimeout(() => {\n          show.value = true;\n        }, 300);\n      }\n      return { options, value, start, show };\n    },\n  });\n</script>\n<style lang="less" scoped>\n  .box {\n    width: 150px;\n    height: 150px;\n    margin-top: 20px;\n    background: pink;\n  }\n</style>\n
',4);p.render=function(a,t,p,c,e,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_transition.md.3cc0f9ff.lean.js b/assets/components_transition.md.3cc0f9ff.lean.js new file mode 100644 index 00000000..49e16b32 --- /dev/null +++ b/assets/components_transition.md.3cc0f9ff.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"Transition","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"}],"relativePath":"components/transition.md","lastUpdated":1697592578589}',p={},o=a('',4);p.render=function(a,t,p,c,e,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_tree.md.8773eb7b.js b/assets/components_tree.md.8773eb7b.js new file mode 100644 index 00000000..b9ff5c70 --- /dev/null +++ b/assets/components_tree.md.8773eb7b.js @@ -0,0 +1 @@ +import{o as n,c as t,a as s}from"./app.8cddb23b.js";const a='{"title":"Tree","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"Methods","slug":"methods"}],"relativePath":"components/tree.md","lastUpdated":1697592578589}',p={},e=s('

Tree

antv 的 tree 组件进行封装

Usage

<template>\n  <BasicTree :treeData="treeData" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicTree } from '/@/components/Tree/index';\n  import { treeData } from './data';\n  import { CollapseContainer } from '/@/components/Container/index';\n  import { TreeItem } from '/@/components/Tree/index';\n\n  export const treeData: TreeItem[] = [\n    {\n      title: 'parent 1',\n      key: '0-0',\n      icon: 'home|svg',\n      children: [\n        { title: 'leaf', key: '0-0-0' },\n        {\n          title: 'leaf',\n          key: '0-0-1',\n          children: [\n            { title: 'leaf', key: '0-0-0-0' },\n            { title: 'leaf', key: '0-0-0-1' },\n          ],\n        },\n      ],\n    },\n    {\n      title: 'parent 2',\n      key: '1-1',\n      icon: 'home|svg',\n      children: [\n        { title: 'leaf', key: '1-1-0' },\n        { title: 'leaf', key: '1-1-1' },\n      ],\n    },\n    {\n      title: 'parent 3',\n      key: '2-2',\n      icon: 'home|svg',\n      children: [\n        { title: 'leaf', key: '2-2-0' },\n        { title: 'leaf', key: '2-2-1' },\n      ],\n    },\n  ];\n  export default defineComponent({\n    components: { BasicTree, CollapseContainer },\n    setup() {\n      return { treeData };\n    },\n  });\n</script>\n

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv tree

属性类型默认值可选值说明版本
treeDataTreeItem[]--树组件数据
rightMenuListContextMenuItem[]--右键菜单列表
checkedKeysstring[]--勾选的节点
selectedKeysstring[]--选中的节点
expandedKeysstring[]--展开的节点
actionListActionItem[]--鼠标移动上去右边操作按钮列表
titlestring--定制标题字符串
toolbarboolean--是否显示工具栏
searchboolean--显示搜索框
clickRowToExpandboolean--是否在点击行时自动展开
beforeRightClick(node, event)=>ContextMenuItem[]--右键点击回调,可返回右键菜单列表数据来生成右键菜单
rightMenuListContextMenuItem[]--右键菜单列表数据
defaultExpandLevelstring | number--初次渲染后默认展开的层级2.4.1
defaultExpandAllbooleanfalsetrue/false初次渲染后默认全部2.4.1
searchValue(v-model)string--当前搜索词2.7.1

注意

defaultExpandLeveldefaultExpandAll 仅在初次渲染时生效。如果basicTree是在创建完毕之后才设置的treeData(如异步数据),需要在更新后自己调用basicTree提供的expandAllfilterByLevel来执行展开

ActionItem

{\n  // 渲染的图标\n  render: (record: any) => any;\n  // 是否显示\n  show?: boolean | ((record: Recordable) => boolean);\n}\n

ContextMenuItem

{\n  // 文本\n  label: string;\n  // 图标\n  icon?: string;\n  // 是否禁用\n  disabled?: boolean;\n  // 事件\n  handler?: (...arg) => any;\n  // 是否显示分隔线\n  divider?: boolean;\n  // 子级菜单数据\n  children?: ContextMenuItem[];\n}\n

Slots

温馨提醒

官方文档内的 slot 都支持,具体可以参考 antv tree

Methods

名称回调参数说明
checkAll(checkAll: boolean) => void选择所有
expandAll(expandAll: boolean) => void展开所有
setExpandedKeys(keys: Keys) => void设置展开节点
getExpandedKeys() => Keys获取展开节点
setSelectedKeys(keys: Keys) => void设置选中节点
getSelectedKeys() => Keys获取选中节点
setCheckedKeys(keys: CheckKeys) => void设置勾选节点
getCheckedKeys() => CheckKeys获取勾选节点
filterByLevel(level: number) => void显示指定等级
insertNodeByKey(opt: InsertNodeParams) => void插入子节点到指定节点内
deleteNodeByKey(key: string) => void根据 key 删除节点
updateNodeByKey(key: string, node: Omit<TreeItem, 'key'>) => void根据 key 更新节点
setSearchValue(value: string) => void设置当前搜索词(v2.7.1)
getSearchValue() => string获取当前搜索词(v2.7.1)
',16);p.render=function(s,a,p,o,c,d){return n(),t("div",null,[e])};export default p;export{a as __pageData}; diff --git a/assets/components_tree.md.8773eb7b.lean.js b/assets/components_tree.md.8773eb7b.lean.js new file mode 100644 index 00000000..325a806e --- /dev/null +++ b/assets/components_tree.md.8773eb7b.lean.js @@ -0,0 +1 @@ +import{o as n,c as t,a as s}from"./app.8cddb23b.js";const a='{"title":"Tree","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"},{"level":2,"title":"Methods","slug":"methods"}],"relativePath":"components/tree.md","lastUpdated":1697592578589}',p={},e=s('',16);p.render=function(s,a,p,o,c,d){return n(),t("div",null,[e])};export default p;export{a as __pageData}; diff --git a/assets/components_upload.md.6a85a24f.js b/assets/components_upload.md.6a85a24f.js new file mode 100644 index 00000000..e1e1fe0b --- /dev/null +++ b/assets/components_upload.md.6a85a24f.js @@ -0,0 +1 @@ +import{o as n,c as t,a}from"./app.8cddb23b.js";const s='{"title":"Upload","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Config","slug":"config"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/upload.md","lastUpdated":1697592578589}',p={},o=a('

Upload

文件上传组件

Usage

<template>\n  <BasicUpload :maxSize="20" :maxNumber="10" @change="handleChange" :api="uploadApi" />\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { BasicUpload } from '/@/components/Upload';\n  import { uploadApi } from '/@/api/sys/upload';\n\n  export default defineComponent({\n    components: { BasicUpload },\n    setup() {\n      return {\n        uploadApi,\n        handleChange: (list: string[]) => {\n          createMessage.info(`已上传文件${JSON.stringify(list)}`);\n        },\n      };\n    },\n  });\n</script>\n

Config

.env.development.env.production 配置开发和生产的文件上传地址

# .env.development\n\nVITE_PROXY=[["/upload","http://localhost:3001/upload"]]\n\n::: tip\nv3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。\n:::\n\n# 如果没有跨域问题,则直接使用真实上传地址\nVITE_GLOB_UPLOAD_URL=/upload\n\n# .env.production\nVITE_GLOB_UPLOAD_URL=/upload\n\n

Props

属性类型默认值可选值说明
valuestring[]--已上传的文件列表,支持v-model
showPreviewNumberbooleantrue-是否显示预览数量
emptyHidePreviewbooleanfalse-没有上传文件时是否隐藏预览
helpTextstring--帮助文本
maxSizenumber2-单个文件最大体积,单位 M
maxNumbernumberInfinity-最大上传数量,Infinity 则不限制
acceptstring[]--限制上传格式,可使用文件后缀名(点号可选)或MIME字符串。例如 ['.doc,','docx','application/msword','image/*']
multipleboolean--开启多文件上传
uploadParamsany--上传携带的参数
apiFn--上传接口,为上面配置的接口

Events

事件回调参数返回值说明版本
change(fileList)=>void文件列表内容改变触发事件
delete(record)=>void在上传列表中删除文件的事件
preview-delete(url:string)=>void在预览列表中删除文件的事件2.5.3
',11);p.render=function(a,s,p,e,c,d){return n(),t("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_upload.md.6a85a24f.lean.js b/assets/components_upload.md.6a85a24f.lean.js new file mode 100644 index 00000000..0e9db446 --- /dev/null +++ b/assets/components_upload.md.6a85a24f.lean.js @@ -0,0 +1 @@ +import{o as n,c as t,a}from"./app.8cddb23b.js";const s='{"title":"Upload","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Config","slug":"config"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Events","slug":"events"}],"relativePath":"components/upload.md","lastUpdated":1697592578589}',p={},o=a('',11);p.render=function(a,s,p,e,c,d){return n(),t("div",null,[o])};export default p;export{s as __pageData}; diff --git a/assets/components_verify.md.688b0bf0.js b/assets/components_verify.md.688b0bf0.js new file mode 100644 index 00000000..5e19328c --- /dev/null +++ b/assets/components_verify.md.688b0bf0.js @@ -0,0 +1 @@ +import{o as t,c as n,a}from"./app.8cddb23b.js";const s='{"title":"BasicDragVerify","description":"","frontmatter":{},"headers":[{"level":2,"title":"BasicDragVerify","slug":"basicdragverify-1"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"RotateDragVerify","slug":"rotatedragverify"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"props","slug":"props-1"},{"level":3,"title":"Methods","slug":"methods-1"}],"relativePath":"components/verify.md","lastUpdated":1697592578589}',p={},e=a('

BasicDragVerify

拖动校验组件

BasicDragVerify

Usage

<template>\n  <div class="p-10">\n    <BasicDragVerify @success="handleSuccess" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent, ref } from 'vue';\n  import { BasicDragVerify, DragVerifyActionType, PassingData } from '/@/components/Verify/index';\n  export default defineComponent({\n    components: { BasicDragVerify },\n    setup() {\n      function handleSuccess(data: PassingData) {\n        const { time } = data;\n        createMessage.success(`校验成功,耗时${time}`);\n      }\n      return {\n        handleSuccess,\n        handleBtnClick,\n      };\n    },\n  });\n</script>\n

Props

属性类型默认值说明
valueboolean-是否通过
textstring请按住滑块拖动未拖动时候显示文字
successTextstring验证通过验证成功后显示文本
heightstring|string40高度
widthstring|string260宽度
circlebooleanfalse是否圆角
wrapStyleany-外层容器样式
contentStyleany-主体内容样式
barStyleany-bar 样式
actionStyleany-拖拽按钮样式

Methods

名称回调参数说明
resume()=>{}还原初始值

RotateDragVerify

图片还原正方向校验组件

Usage

<template>\n  <div class="p-10">\n    <RotateDragVerify :src="img" ref="el" @success="handleSuccess" />\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { RotateDragVerify } from '/@/components/Verify/index';\n\n  import img from '/@/assets/images/header.jpg';\n  export default defineComponent({\n    components: { RotateDragVerify },\n    setup() {\n      const handleSuccess = () => {\n        console.log('success!');\n      };\n      return {\n        handleSuccess,\n        img,\n      };\n    },\n  });\n</script>\n

props

属性类型默认值说明
srcstring-图片地址
imgWidthnumber-图片宽度
imgWrapStyleany-图片外层容器样式
minDegreenumber-最小旋转角度
maxDegreenumber-最大旋转角度
diffDegreenumber-误差角度
valueboolean-是否通过
textstring请按住滑块拖动未拖动时候显示文字
successTextstring验证通过验证成功后显示文本
heightstring|string40高度
widthstring|string260宽度
circlebooleanfalse是否圆角
wrapStyleany-外层容器样式
contentStyleany-主体内容样式
barStyleany-bar 样式
actionStyleany-拖拽按钮样式

Methods

名称回调参数说明
resumeFunction还原初始值
',17);p.render=function(a,s,p,o,c,d){return t(),n("div",null,[e])};export default p;export{s as __pageData}; diff --git a/assets/components_verify.md.688b0bf0.lean.js b/assets/components_verify.md.688b0bf0.lean.js new file mode 100644 index 00000000..63dbc83d --- /dev/null +++ b/assets/components_verify.md.688b0bf0.lean.js @@ -0,0 +1 @@ +import{o as t,c as n,a}from"./app.8cddb23b.js";const s='{"title":"BasicDragVerify","description":"","frontmatter":{},"headers":[{"level":2,"title":"BasicDragVerify","slug":"basicdragverify-1"},{"level":3,"title":"Usage","slug":"usage"},{"level":3,"title":"Props","slug":"props"},{"level":3,"title":"Methods","slug":"methods"},{"level":2,"title":"RotateDragVerify","slug":"rotatedragverify"},{"level":3,"title":"Usage","slug":"usage-1"},{"level":3,"title":"props","slug":"props-1"},{"level":3,"title":"Methods","slug":"methods-1"}],"relativePath":"components/verify.md","lastUpdated":1697592578589}',p={},e=a('',17);p.render=function(a,s,p,o,c,d){return t(),n("div",null,[e])};export default p;export{s as __pageData}; diff --git a/assets/components_virtual-scroll.md.65256e7b.js b/assets/components_virtual-scroll.md.65256e7b.js new file mode 100644 index 00000000..118c7f8d --- /dev/null +++ b/assets/components_virtual-scroll.md.65256e7b.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"VirtualScroll","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/virtual-scroll.md","lastUpdated":1697592578589}',p={},o=s('

VirtualScroll

虚拟滚动组件(用于大量数据纯展示时使用)

Usage

<template>\n  <div class="p-4 virtual-scroll-demo">\n    <Divider>基础滚动示例</Divider>\n    <div class="virtual-scroll-demo-wrap">\n      <VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300">\n        <template v-slot="{ item }">\n          <div class="virtual-scroll-demo__item">{{ item.title }}</div>\n        </template>\n      </VirtualScroll>\n    </div>\n\n    <Divider>即使不可见,也预先加载50条数据,防止空白</Divider>\n    <div class="virtual-scroll-demo-wrap">\n      <VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300" :bench="50">\n        <template v-slot="{ item }">\n          <div class="virtual-scroll-demo__item">{{ item.title }}</div>\n        </template>\n      </VirtualScroll>\n    </div>\n  </div>\n</template>\n<script lang="ts">\n  import { defineComponent } from 'vue';\n  import { VirtualScroll } from '/@/components/VirtualScroll/index';\n\n  import { Divider } from 'ant-design-vue';\n  const data: any[] = (() => {\n    const arr: any[] = [];\n    for (let index = 1; index < 20000; index++) {\n      arr.push({\n        title: '列表项' + index,\n      });\n    }\n    return arr;\n  })();\n  export default defineComponent({\n    components: { VirtualScroll, Divider },\n    setup() {\n      return { data: data };\n    },\n  });\n</script>\n<style lang="less" scoped>\n  .virtual-scroll-demo {\n    &-wrap {\n      display: flex;\n      margin: 0 30%;\n      background: #fff;\n      justify-content: center;\n    }\n\n    /deep/ &__item {\n      height: 40px;\n      padding: 0 20px;\n      line-height: 40px;\n      border-bottom: 1px solid #ddd;\n    }\n  }\n</style>\n

Props

属性类型默认值可选值说明
heightstring|number--高度
widthstring|number--宽度
maxHeightstring|number--最大高度
maxWidthstring|number--最大宽度
minHeightstring|number--最小高度
minWidthstring|number--最小宽度
itemHeightstring|number--每个选项高度,必传
itemsany[]--选项列表

Slots

名称说明
default默认
',8);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/components_virtual-scroll.md.65256e7b.lean.js b/assets/components_virtual-scroll.md.65256e7b.lean.js new file mode 100644 index 00000000..82993aee --- /dev/null +++ b/assets/components_virtual-scroll.md.65256e7b.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"VirtualScroll","description":"","frontmatter":{},"headers":[{"level":2,"title":"Usage","slug":"usage"},{"level":2,"title":"Props","slug":"props"},{"level":2,"title":"Slots","slug":"slots"}],"relativePath":"components/virtual-scroll.md","lastUpdated":1697592578589}',p={},o=s('',8);p.render=function(s,t,p,e,c,l){return n(),a("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/dep_cors.md.37a05889.js b/assets/dep_cors.md.37a05889.js new file mode 100644 index 00000000..c5a9a6f4 --- /dev/null +++ b/assets/dep_cors.md.37a05889.js @@ -0,0 +1 @@ +import{o as l,c as t,a as i}from"./app.8cddb23b.js";const o='{"title":"跨域处理","description":"","frontmatter":{},"headers":[{"level":2,"title":"产生原因","slug":"产生原因"},{"level":2,"title":"解决方式","slug":"解决方式"}],"relativePath":"dep/cors.md","lastUpdated":1697592578589}',r={},e=i('

跨域处理

产生原因

跨域产生的原因是由于前端地址与后台接口不是同源,从而导致 ajax 不能发送

非同源产生的问题

  1. Cookie、LocalStorage 和 IndexDB 无法获取
  2. DOM 无法获得
  3. AJAX 请求不能发送

同源条件

协议端口主机 三者相同即为同源

反之,其中只要 某一个 不一样则为不同源

解决方式

本地开发跨域

本地开发一般使用下面 3 种方式进行处理

  1. vite 的 proxy 进行代理
  2. 后台开启 cors
  3. 使用 nginx 转发请求

项目内部自带第一种方式,具体可以参考服务端交互-本地开发环境接口地址修改

生产环境跨域

生产环境一般使用下面 2 种方式进行处理

  1. 后台开启 cors
  2. 使用 nginx 转发请求

后台开启 cors 不需要前端做任何改动

nginx 配置文件可以查看nginx 配置

',15);r.render=function(i,o,r,s,a,n){return l(),t("div",null,[e])};export default r;export{o as __pageData}; diff --git a/assets/dep_cors.md.37a05889.lean.js b/assets/dep_cors.md.37a05889.lean.js new file mode 100644 index 00000000..ce0310c7 --- /dev/null +++ b/assets/dep_cors.md.37a05889.lean.js @@ -0,0 +1 @@ +import{o as l,c as t,a as i}from"./app.8cddb23b.js";const o='{"title":"跨域处理","description":"","frontmatter":{},"headers":[{"level":2,"title":"产生原因","slug":"产生原因"},{"level":2,"title":"解决方式","slug":"解决方式"}],"relativePath":"dep/cors.md","lastUpdated":1697592578589}',r={},e=i('',15);r.render=function(i,o,r,s,a,n){return l(),t("div",null,[e])};export default r;export{o as __pageData}; diff --git a/assets/dep_dark.md.37147652.js b/assets/dep_dark.md.37147652.js new file mode 100644 index 00000000..99ed73a9 --- /dev/null +++ b/assets/dep_dark.md.37147652.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"黑暗主题","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"原理","slug":"原理"},{"level":2,"title":"配置","slug":"配置"},{"level":2,"title":"切换","slug":"切换"}],"relativePath":"dep/dark.md","lastUpdated":1697592578593}',p={},e=a('

黑暗主题

介绍

项目已经内置了黑暗主题切换,只需配置自己需要的颜色变量,即可在项目中使用

原理

通过 vite-plugin-theme 插件,将所有的颜色变量抽取到独立的 css 文件,并且全部在 html 上面加上 css 选择器。通过改变 html 标签的 data-theme 属性来进行黑暗主题切换

配置

黑暗主题颜色配置通过 vite-plugin-theme 实现,具体代码在 build/vite/plugin/theme

antdDarkThemePlugin({\n  darkModifyVars: {\n    ...generateModifyVars(true),\n    'text-color': '#c9d1d9',\n    'text-color-base': '#c9d1d9',\n    'component-background': '#151515',\n    'text-color-secondary': '#8b949e',\n    'border-color-base': '#303030',\n    'item-active-bg': '#111b26',\n    'app-content-background': 'rgb(255 255 255 / 4%)',\n  },\n});\n

切换

只需要使用 vite-plugin-theme 提供的函数来进行切换即可

import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client';\n\nexport async function updateDarkTheme(mode: string | null = 'light') {\n  const htmlRoot = document.getElementById('htmlRoot');\n  if (mode === 'dark') {\n    if (import.meta.env.PROD && !darkCssIsReady) {\n      await loadDarkThemeCss();\n    }\n    htmlRoot?.setAttribute('data-theme', 'dark');\n  } else {\n    htmlRoot?.setAttribute('data-theme', 'light');\n  }\n}\n
',11);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/dep_dark.md.37147652.lean.js b/assets/dep_dark.md.37147652.lean.js new file mode 100644 index 00000000..02fb6000 --- /dev/null +++ b/assets/dep_dark.md.37147652.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"黑暗主题","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"原理","slug":"原理"},{"level":2,"title":"配置","slug":"配置"},{"level":2,"title":"切换","slug":"切换"}],"relativePath":"dep/dark.md","lastUpdated":1697592578593}',p={},e=a('',11);p.render=function(a,t,p,o,c,l){return n(),s("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/dep_i18n.md.a96f197a.js b/assets/dep_i18n.md.a96f197a.js new file mode 100644 index 00000000..46a18fb9 --- /dev/null +++ b/assets/dep_i18n.md.a96f197a.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const e='{"title":"国际化","description":"","frontmatter":{},"headers":[{"level":2,"title":"I18n-ally 插件","slug":"i18n-ally-插件"},{"level":2,"title":"配置默认语言","slug":"配置默认语言"},{"level":2,"title":"配置","slug":"配置"},{"level":3,"title":"语言文件","slug":"语言文件"},{"level":3,"title":"语言导入逻辑说明","slug":"语言导入逻辑说明"},{"level":2,"title":"使用","slug":"使用"},{"level":2,"title":"切换语言","slug":"切换语言"},{"level":2,"title":"新增","slug":"新增"},{"level":3,"title":"语言文件","slug":"语言文件-1"},{"level":3,"title":"新增语言","slug":"新增语言"},{"level":2,"title":"远程读取语言数据","slug":"远程读取语言数据"},{"level":3,"title":"setupI18n 函数","slug":"setupi18n-函数"},{"level":3,"title":"changeLocale 函数","slug":"changelocale-函数"}],"relativePath":"dep/i18n.md","lastUpdated":1697592578593}',o={},c=a("h1",{id:"国际化"},[a("a",{class:"header-anchor",href:"#国际化","aria-hidden":"true"},"#"),t(" 国际化")],-1),l=a("p",null,[t("如果你使用的 vscode 开发工具,则推荐安装 "),a("a",{href:"https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally",target:"_blank",rel:"noopener noreferrer"},"I18n-ally"),t(" 这个插件")],-1),p=a("h2",{id:"i18n-ally-插件"},[a("a",{class:"header-anchor",href:"#i18n-ally-插件","aria-hidden":"true"},"#"),t(" I18n-ally 插件")],-1),u=a("p",null,"安装了该插件后,你的代码内可以实时看到对应的语言内容",-1),r=a("p",null,[a("img",{src:"/images/i18n.png",alt:""})],-1),i=a("h2",{id:"配置默认语言"},[a("a",{class:"header-anchor",href:"#配置默认语言","aria-hidden":"true"},"#"),t(" 配置默认语言")],-1),k=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/settings/localeSetting.ts",target:"_blank",rel:"noopener noreferrer"},"src/settings/localeSetting.ts"),t(" 内可以配置默认语言")],-1),d=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(),a("span",{class:"token punctuation"},"["),t("key"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token builtin"},"string"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token operator"},":"),t(" LocaleType "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token constant"},"EN_US"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(" localeSetting"),a("span",{class:"token operator"},":"),t(" LocaleSetting "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"// 是否显示语言选择器"),t("\n showPicker"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 当前语言"),t("\n locale"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 默认语言"),t("\n fallback"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 允许的语言"),t("\n availableLocales"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"EN_US"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token comment"},"// 配置语言列表"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(" localeList"),a("span",{class:"token operator"},":"),t(" DropMenu"),a("span",{class:"token punctuation"},"["),a("span",{class:"token punctuation"},"]"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"["),t("\n "),a("span",{class:"token punctuation"},"{"),t("\n text"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'简体中文'"),a("span",{class:"token punctuation"},","),t("\n event"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"{"),t("\n text"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'English'"),a("span",{class:"token punctuation"},","),t("\n event"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),g=a("h2",{id:"配置"},[a("a",{class:"header-anchor",href:"#配置","aria-hidden":"true"},"#"),t(" 配置")],-1),m=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n.ts"),t(" 内引入的 i18n 这个无需修改")],-1),h=a("h3",{id:"语言文件"},[a("a",{class:"header-anchor",href:"#语言文件","aria-hidden":"true"},"#"),t(" 语言文件")],-1),f=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 可以配置具体的语言")],-1),y=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# locales/lang/"),t("\n\n"),a("span",{class:"token comment"},"# 中文语言"),t("\nzh_CN:\n component: 组件相关\n layout: 布局相关\n routes: 路由菜单相关\n sys: 系统页面相关\n\nen: 同上\n\n")])])],-1),b=a("h3",{id:"语言导入逻辑说明"},[a("a",{class:"header-anchor",href:"#语言导入逻辑说明","aria-hidden":"true"},"#"),t(" 语言导入逻辑说明")],-1),v=a("ol",null,[a("li",null,"初始化")],-1),w=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n"),t(" 内的根语言文件可以看到")],-1),L=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"const"),t(" defaultLocal "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),I=a("p",null,[t("这会导入 "),a("code",null,"src/locales/lang/{lang}.ts"),t(" 文件语言包,此文件会导入对应语言下的所有文件。")],-1),_=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" genMessage "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'../helper'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"import"),t(" antdLocale "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'ant-design-vue/es/locale/zh_CN'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"import"),t(" momentLocale "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'moment/dist/locale/zh-cn'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(" modules "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"."),t("meta"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"globEager"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'./zh_CN/**/*.ts'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token punctuation"},"{"),t("\n message"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token operator"},"..."),a("span",{class:"token function"},"genMessage"),a("span",{class:"token punctuation"},"("),t("modules"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n antdLocale"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n momentLocale"),a("span",{class:"token punctuation"},","),t("\n momentLocaleName"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh-cn'"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),N=a("p",null,"并将其按相应的目录结构转化为多层级的",-1),C=a("p",null,"例:",-1),j=a("p",null,[a("code",null,"lang/zh_CN/components/modal.ts"),t(" 的文件内容为")],-1),x=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token punctuation"},"{"),t("\n title"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'标题'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),z=a("p",null,[t("则在使用的使用直接使用 "),a("code",null,"t('components.modal.title')"),t(" 进行获取。")],-1),E=a("p",null,"这样做的好处在于更容易管理大型项目的多语言。如果不需要分模块划分,可以直接自己手动导入即可。",-1),S=a("h2",{id:"使用"},[a("a",{class:"header-anchor",href:"#使用","aria-hidden":"true"},"#"),t(" 使用")],-1),M=a("p",null,[t("引入项目自带的 "),a("code",null,"useI18n"),t(),a("strong",null,"注意不要引入 vue-i18n 的 useI18n")],-1),O=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" useI18n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/hooks/web/useI18n'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" t "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"useI18n"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(" title "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"t"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'components.modal.title'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),A=a("h2",{id:"切换语言"},[a("a",{class:"header-anchor",href:"#切换语言","aria-hidden":"true"},"#"),t(" 切换语言")],-1),P=a("p",null,[t("切换语言需要使用 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/useLocale.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/useLocale.ts")],-1),H=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" useLocale "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/locales/useLocale'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" changeLocale "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"useLocale"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token function"},"changeLocale"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),Z=a("h2",{id:"新增"},[a("a",{class:"header-anchor",href:"#新增","aria-hidden":"true"},"#"),t(" 新增")],-1),T=a("h3",{id:"语言文件-1"},[a("a",{class:"header-anchor",href:"#语言文件-1","aria-hidden":"true"},"#"),t(" 语言文件")],-1),U=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 增加对应语言的文件即可")],-1),W=a("h3",{id:"新增语言"},[a("a",{class:"header-anchor",href:"#新增语言","aria-hidden":"true"},"#"),t(" 新增语言")],-1),$=a("p",null,[t("目前项目自带的语言只有 "),a("code",null,"zh_CN"),t(" 和 "),a("code",null,"en"),t(" 两种")],-1),D=a("p",null,"如果需要新增,按以下操作即可",-1),F=a("ol",null,[a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 下新增相应的语言目录及语言文件并引入 引入 ant-design-vue 和 moment 对应的语言包")]),a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/types/config",target:"_blank",rel:"noopener noreferrer"},"types/config.d.ts"),t(" 内加上预览类型定义")]),a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/settings/localeSetting.ts",target:"_blank",rel:"noopener noreferrer"},"src/settings/localeSetting.ts"),t(" 修改语言配置")])],-1),q=a("h2",{id:"远程读取语言数据"},[a("a",{class:"header-anchor",href:"#远程读取语言数据","aria-hidden":"true"},"#"),t(" 远程读取语言数据")],-1),B=a("p",null,[t("目前项目会在 "),a("code",null,"src/main.ts"),t(" 内等待 "),a("code",null,"setupI18n"),t(" 这个函数执行完之后才会渲染界面,所以只需在 setupI18n 内发送 ajax 请求,将对应的数据设置到 i18n 实例上即可")],-1),G=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"// src/main.ts"),t("\n"),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"setupI18n"),a("span",{class:"token punctuation"},"("),t("app"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\napp"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"mount"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'#app'"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),J=a("h3",{id:"setupi18n-函数"},[a("a",{class:"header-anchor",href:"#setupi18n-函数","aria-hidden":"true"},"#"),t(" setupI18n 函数")],-1),K=a("p",null,[t("代码: "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n/")],-1),Q=a("p",null,"如下所示,这里会先设置一个默认语言,默认语言可以设置在本地,也可以在这里等待接口返回默认语言",-1),R=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"// setup i18n instance with glob"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"setupI18n"),a("span",{class:"token punctuation"},"("),t("app"),a("span",{class:"token operator"},":"),t(" App"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" options "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"createI18nOptions"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n i18n "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"createI18n"),a("span",{class:"token punctuation"},"("),t("options"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"as"),t(" I18n"),a("span",{class:"token punctuation"},";"),t("\n app"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"use"),a("span",{class:"token punctuation"},"("),t("i18n"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n\n"),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"createI18nOptions"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token builtin"},"Promise"),a("span",{class:"token operator"},"<"),t("I18nOptions"),a("span",{class:"token operator"},">"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" locale "),a("span",{class:"token operator"},"="),t(" localeStore"),a("span",{class:"token punctuation"},"."),t("getLocale"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token comment"},"// 这里改成接口获取"),t("\n "),a("span",{class:"token keyword"},"const"),t(" defaultLocal "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" message "),a("span",{class:"token operator"},"="),t(" defaultLocal"),a("span",{class:"token punctuation"},"."),a("span",{class:"token keyword"},"default"),a("span",{class:"token operator"},"?."),t("message "),a("span",{class:"token operator"},"??"),t(),a("span",{class:"token punctuation"},"{"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t("\n legacy"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},","),t("\n locale"),a("span",{class:"token punctuation"},","),t("\n fallbackLocale"),a("span",{class:"token operator"},":"),t(" fallback"),a("span",{class:"token punctuation"},","),t("\n messages"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token punctuation"},"["),t("locale"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token operator"},":"),t(" message"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n availableLocales"),a("span",{class:"token operator"},":"),t(" availableLocales"),a("span",{class:"token punctuation"},","),t("\n sync"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n silentTranslationWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n missingWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},","),t("\n silentFallbackWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),V=a("h3",{id:"changelocale-函数"},[a("a",{class:"header-anchor",href:"#changelocale-函数","aria-hidden":"true"},"#"),t(" changeLocale 函数")],-1),X=a("p",null,[t("代码: "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/useLocale",target:"_blank",rel:"noopener noreferrer"},"src/locales/useLocale/")],-1),Y=a("p",null,[t("当手动切换语言的时候会触发 "),a("code",null,"useLocale"),t(" 函数,useLocale 也是异步函数,只需等待接口返回响应的数据后,再进行设置即可")],-1),nn=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"changeLocale"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token operator"},":"),t(" LocaleType"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" globalI18n "),a("span",{class:"token operator"},"="),t(" i18n"),a("span",{class:"token punctuation"},"."),t("global"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" currentLocale "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("globalI18n"),a("span",{class:"token punctuation"},"."),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("currentLocale "),a("span",{class:"token operator"},"==="),t(" locale"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("loadLocalePool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"includes"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token function"},"setI18nLanguage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token comment"},"// 这里改成接口获取"),t("\n "),a("span",{class:"token keyword"},"const"),t(" langModule "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"as"),t(),a("span",{class:"token builtin"},"any"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},"."),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token keyword"},"as"),t(" LangModule"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("langModule"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" message"),a("span",{class:"token punctuation"},","),t(" momentLocale"),a("span",{class:"token punctuation"},","),t(" momentLocaleName "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(" langModule"),a("span",{class:"token punctuation"},";"),t("\n\n globalI18n"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"setLocaleMessage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},","),t(" message"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n moment"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"updateLocale"),a("span",{class:"token punctuation"},"("),t("momentLocaleName"),a("span",{class:"token punctuation"},","),t(" momentLocale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n loadLocalePool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"push"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"setI18nLanguage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1);o.render=function(a,t,e,o,sn,an){return n(),s("div",null,[c,l,p,u,r,i,k,d,g,m,h,f,y,b,v,w,L,I,_,N,C,j,x,z,E,S,M,O,A,P,H,Z,T,U,W,$,D,F,q,B,G,J,K,Q,R,V,X,Y,nn])};export default o;export{e as __pageData}; diff --git a/assets/dep_i18n.md.a96f197a.lean.js b/assets/dep_i18n.md.a96f197a.lean.js new file mode 100644 index 00000000..46a18fb9 --- /dev/null +++ b/assets/dep_i18n.md.a96f197a.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const e='{"title":"国际化","description":"","frontmatter":{},"headers":[{"level":2,"title":"I18n-ally 插件","slug":"i18n-ally-插件"},{"level":2,"title":"配置默认语言","slug":"配置默认语言"},{"level":2,"title":"配置","slug":"配置"},{"level":3,"title":"语言文件","slug":"语言文件"},{"level":3,"title":"语言导入逻辑说明","slug":"语言导入逻辑说明"},{"level":2,"title":"使用","slug":"使用"},{"level":2,"title":"切换语言","slug":"切换语言"},{"level":2,"title":"新增","slug":"新增"},{"level":3,"title":"语言文件","slug":"语言文件-1"},{"level":3,"title":"新增语言","slug":"新增语言"},{"level":2,"title":"远程读取语言数据","slug":"远程读取语言数据"},{"level":3,"title":"setupI18n 函数","slug":"setupi18n-函数"},{"level":3,"title":"changeLocale 函数","slug":"changelocale-函数"}],"relativePath":"dep/i18n.md","lastUpdated":1697592578593}',o={},c=a("h1",{id:"国际化"},[a("a",{class:"header-anchor",href:"#国际化","aria-hidden":"true"},"#"),t(" 国际化")],-1),l=a("p",null,[t("如果你使用的 vscode 开发工具,则推荐安装 "),a("a",{href:"https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally",target:"_blank",rel:"noopener noreferrer"},"I18n-ally"),t(" 这个插件")],-1),p=a("h2",{id:"i18n-ally-插件"},[a("a",{class:"header-anchor",href:"#i18n-ally-插件","aria-hidden":"true"},"#"),t(" I18n-ally 插件")],-1),u=a("p",null,"安装了该插件后,你的代码内可以实时看到对应的语言内容",-1),r=a("p",null,[a("img",{src:"/images/i18n.png",alt:""})],-1),i=a("h2",{id:"配置默认语言"},[a("a",{class:"header-anchor",href:"#配置默认语言","aria-hidden":"true"},"#"),t(" 配置默认语言")],-1),k=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/settings/localeSetting.ts",target:"_blank",rel:"noopener noreferrer"},"src/settings/localeSetting.ts"),t(" 内可以配置默认语言")],-1),d=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(),a("span",{class:"token punctuation"},"["),t("key"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token builtin"},"string"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token operator"},":"),t(" LocaleType "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token constant"},"EN_US"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(" localeSetting"),a("span",{class:"token operator"},":"),t(" LocaleSetting "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"// 是否显示语言选择器"),t("\n showPicker"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 当前语言"),t("\n locale"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 默认语言"),t("\n fallback"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// 允许的语言"),t("\n availableLocales"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"ZH_CN"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token constant"},"LOCALE"),a("span",{class:"token punctuation"},"."),a("span",{class:"token constant"},"EN_US"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token comment"},"// 配置语言列表"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"const"),t(" localeList"),a("span",{class:"token operator"},":"),t(" DropMenu"),a("span",{class:"token punctuation"},"["),a("span",{class:"token punctuation"},"]"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"["),t("\n "),a("span",{class:"token punctuation"},"{"),t("\n text"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'简体中文'"),a("span",{class:"token punctuation"},","),t("\n event"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"{"),t("\n text"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'English'"),a("span",{class:"token punctuation"},","),t("\n event"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),g=a("h2",{id:"配置"},[a("a",{class:"header-anchor",href:"#配置","aria-hidden":"true"},"#"),t(" 配置")],-1),m=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n.ts"),t(" 内引入的 i18n 这个无需修改")],-1),h=a("h3",{id:"语言文件"},[a("a",{class:"header-anchor",href:"#语言文件","aria-hidden":"true"},"#"),t(" 语言文件")],-1),f=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 可以配置具体的语言")],-1),y=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# locales/lang/"),t("\n\n"),a("span",{class:"token comment"},"# 中文语言"),t("\nzh_CN:\n component: 组件相关\n layout: 布局相关\n routes: 路由菜单相关\n sys: 系统页面相关\n\nen: 同上\n\n")])])],-1),b=a("h3",{id:"语言导入逻辑说明"},[a("a",{class:"header-anchor",href:"#语言导入逻辑说明","aria-hidden":"true"},"#"),t(" 语言导入逻辑说明")],-1),v=a("ol",null,[a("li",null,"初始化")],-1),w=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n"),t(" 内的根语言文件可以看到")],-1),L=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"const"),t(" defaultLocal "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),I=a("p",null,[t("这会导入 "),a("code",null,"src/locales/lang/{lang}.ts"),t(" 文件语言包,此文件会导入对应语言下的所有文件。")],-1),_=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" genMessage "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'../helper'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"import"),t(" antdLocale "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'ant-design-vue/es/locale/zh_CN'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"import"),t(" momentLocale "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'moment/dist/locale/zh-cn'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(" modules "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"."),t("meta"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"globEager"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'./zh_CN/**/*.ts'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token punctuation"},"{"),t("\n message"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token operator"},"..."),a("span",{class:"token function"},"genMessage"),a("span",{class:"token punctuation"},"("),t("modules"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token string"},"'zh_CN'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n antdLocale"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n momentLocale"),a("span",{class:"token punctuation"},","),t("\n momentLocaleName"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'zh-cn'"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),N=a("p",null,"并将其按相应的目录结构转化为多层级的",-1),C=a("p",null,"例:",-1),j=a("p",null,[a("code",null,"lang/zh_CN/components/modal.ts"),t(" 的文件内容为")],-1),x=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token punctuation"},"{"),t("\n title"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'标题'"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),z=a("p",null,[t("则在使用的使用直接使用 "),a("code",null,"t('components.modal.title')"),t(" 进行获取。")],-1),E=a("p",null,"这样做的好处在于更容易管理大型项目的多语言。如果不需要分模块划分,可以直接自己手动导入即可。",-1),S=a("h2",{id:"使用"},[a("a",{class:"header-anchor",href:"#使用","aria-hidden":"true"},"#"),t(" 使用")],-1),M=a("p",null,[t("引入项目自带的 "),a("code",null,"useI18n"),t(),a("strong",null,"注意不要引入 vue-i18n 的 useI18n")],-1),O=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" useI18n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/hooks/web/useI18n'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" t "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"useI18n"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(" title "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"t"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'components.modal.title'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),A=a("h2",{id:"切换语言"},[a("a",{class:"header-anchor",href:"#切换语言","aria-hidden":"true"},"#"),t(" 切换语言")],-1),P=a("p",null,[t("切换语言需要使用 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/useLocale.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/useLocale.ts")],-1),H=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" useLocale "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/locales/useLocale'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" changeLocale "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"useLocale"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token function"},"changeLocale"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'en'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),Z=a("h2",{id:"新增"},[a("a",{class:"header-anchor",href:"#新增","aria-hidden":"true"},"#"),t(" 新增")],-1),T=a("h3",{id:"语言文件-1"},[a("a",{class:"header-anchor",href:"#语言文件-1","aria-hidden":"true"},"#"),t(" 语言文件")],-1),U=a("p",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 增加对应语言的文件即可")],-1),W=a("h3",{id:"新增语言"},[a("a",{class:"header-anchor",href:"#新增语言","aria-hidden":"true"},"#"),t(" 新增语言")],-1),$=a("p",null,[t("目前项目自带的语言只有 "),a("code",null,"zh_CN"),t(" 和 "),a("code",null,"en"),t(" 两种")],-1),D=a("p",null,"如果需要新增,按以下操作即可",-1),F=a("ol",null,[a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/lang",target:"_blank",rel:"noopener noreferrer"},"src/locales/lang/"),t(" 下新增相应的语言目录及语言文件并引入 引入 ant-design-vue 和 moment 对应的语言包")]),a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/types/config",target:"_blank",rel:"noopener noreferrer"},"types/config.d.ts"),t(" 内加上预览类型定义")]),a("li",null,[t("在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/settings/localeSetting.ts",target:"_blank",rel:"noopener noreferrer"},"src/settings/localeSetting.ts"),t(" 修改语言配置")])],-1),q=a("h2",{id:"远程读取语言数据"},[a("a",{class:"header-anchor",href:"#远程读取语言数据","aria-hidden":"true"},"#"),t(" 远程读取语言数据")],-1),B=a("p",null,[t("目前项目会在 "),a("code",null,"src/main.ts"),t(" 内等待 "),a("code",null,"setupI18n"),t(" 这个函数执行完之后才会渲染界面,所以只需在 setupI18n 内发送 ajax 请求,将对应的数据设置到 i18n 实例上即可")],-1),G=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"// src/main.ts"),t("\n"),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"setupI18n"),a("span",{class:"token punctuation"},"("),t("app"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\napp"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"mount"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'#app'"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),J=a("h3",{id:"setupi18n-函数"},[a("a",{class:"header-anchor",href:"#setupi18n-函数","aria-hidden":"true"},"#"),t(" setupI18n 函数")],-1),K=a("p",null,[t("代码: "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/setupI18n.ts",target:"_blank",rel:"noopener noreferrer"},"src/locales/setupI18n/")],-1),Q=a("p",null,"如下所示,这里会先设置一个默认语言,默认语言可以设置在本地,也可以在这里等待接口返回默认语言",-1),R=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"// setup i18n instance with glob"),t("\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"setupI18n"),a("span",{class:"token punctuation"},"("),t("app"),a("span",{class:"token operator"},":"),t(" App"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" options "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"createI18nOptions"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n i18n "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"createI18n"),a("span",{class:"token punctuation"},"("),t("options"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"as"),t(" I18n"),a("span",{class:"token punctuation"},";"),t("\n app"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"use"),a("span",{class:"token punctuation"},"("),t("i18n"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n\n"),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"createI18nOptions"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token builtin"},"Promise"),a("span",{class:"token operator"},"<"),t("I18nOptions"),a("span",{class:"token operator"},">"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" locale "),a("span",{class:"token operator"},"="),t(" localeStore"),a("span",{class:"token punctuation"},"."),t("getLocale"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token comment"},"// 这里改成接口获取"),t("\n "),a("span",{class:"token keyword"},"const"),t(" defaultLocal "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" message "),a("span",{class:"token operator"},"="),t(" defaultLocal"),a("span",{class:"token punctuation"},"."),a("span",{class:"token keyword"},"default"),a("span",{class:"token operator"},"?."),t("message "),a("span",{class:"token operator"},"??"),t(),a("span",{class:"token punctuation"},"{"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t("\n legacy"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},","),t("\n locale"),a("span",{class:"token punctuation"},","),t("\n fallbackLocale"),a("span",{class:"token operator"},":"),t(" fallback"),a("span",{class:"token punctuation"},","),t("\n messages"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token punctuation"},"["),t("locale"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token operator"},":"),t(" message"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n availableLocales"),a("span",{class:"token operator"},":"),t(" availableLocales"),a("span",{class:"token punctuation"},","),t("\n sync"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n silentTranslationWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n missingWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},","),t("\n silentFallbackWarn"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),V=a("h3",{id:"changelocale-函数"},[a("a",{class:"header-anchor",href:"#changelocale-函数","aria-hidden":"true"},"#"),t(" changeLocale 函数")],-1),X=a("p",null,[t("代码: "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/locales/useLocale",target:"_blank",rel:"noopener noreferrer"},"src/locales/useLocale/")],-1),Y=a("p",null,[t("当手动切换语言的时候会触发 "),a("code",null,"useLocale"),t(" 函数,useLocale 也是异步函数,只需等待接口返回响应的数据后,再进行设置即可")],-1),nn=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token keyword"},"function"),t(),a("span",{class:"token function"},"changeLocale"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token operator"},":"),t(" LocaleType"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" globalI18n "),a("span",{class:"token operator"},"="),t(" i18n"),a("span",{class:"token punctuation"},"."),t("global"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" currentLocale "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("globalI18n"),a("span",{class:"token punctuation"},"."),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("currentLocale "),a("span",{class:"token operator"},"==="),t(" locale"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("loadLocalePool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"includes"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token function"},"setI18nLanguage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token comment"},"// 这里改成接口获取"),t("\n "),a("span",{class:"token keyword"},"const"),t(" langModule "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token keyword"},"import"),a("span",{class:"token punctuation"},"("),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token string"},"./lang/"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("locale"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},".ts"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"as"),t(),a("span",{class:"token builtin"},"any"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},"."),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token keyword"},"as"),t(" LangModule"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("langModule"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" message"),a("span",{class:"token punctuation"},","),t(" momentLocale"),a("span",{class:"token punctuation"},","),t(" momentLocaleName "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(" langModule"),a("span",{class:"token punctuation"},";"),t("\n\n globalI18n"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"setLocaleMessage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},","),t(" message"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n moment"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"updateLocale"),a("span",{class:"token punctuation"},"("),t("momentLocaleName"),a("span",{class:"token punctuation"},","),t(" momentLocale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n loadLocalePool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"push"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"setI18nLanguage"),a("span",{class:"token punctuation"},"("),t("locale"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"return"),t(" locale"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1);o.render=function(a,t,e,o,sn,an){return n(),s("div",null,[c,l,p,u,r,i,k,d,g,m,h,f,y,b,v,w,L,I,_,N,C,j,x,z,E,S,M,O,A,P,H,Z,T,U,W,$,D,F,q,B,G,J,K,Q,R,V,X,Y,nn])};export default o;export{e as __pageData}; diff --git a/assets/dep_icon.md.360e0f2b.js b/assets/dep_icon.md.360e0f2b.js new file mode 100644 index 00000000..9eb1480b --- /dev/null +++ b/assets/dep_icon.md.360e0f2b.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const o='{"title":"图标","description":"","frontmatter":{},"headers":[{"level":2,"title":"组件库图标","slug":"组件库图标"},{"level":2,"title":"Svg Sprite 图标","slug":"svg-sprite-图标"},{"level":3,"title":"使用","slug":"使用"},{"level":2,"title":"Iconify 图标","slug":"iconify-图标"},{"level":2,"title":"图标选择器","slug":"图标选择器"},{"level":3,"title":"图标集预生成","slug":"图标集预生成"},{"level":3,"title":"生成","slug":"生成"},{"level":3,"title":"优缺点","slug":"优缺点"}],"relativePath":"dep/icon.md","lastUpdated":1697592578593}',p={},c=a("h1",{id:"图标"},[a("a",{class:"header-anchor",href:"#图标","aria-hidden":"true"},"#"),t(" 图标")],-1),e=a("p",null,"项目中有以下多种图标使用方式。",-1),l=a("h2",{id:"组件库图标"},[a("a",{class:"header-anchor",href:"#组件库图标","aria-hidden":"true"},"#"),t(" 组件库图标")],-1),u=a("p",null,[t("使用 "),a("code",null,"ant-design-vue"),t(" 提供的图标")],-1),k=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarOutlined")]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarFilled")]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarTwoTone")]),t(),a("span",{class:"token attr-name"},"twoToneColor"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("#eb2f96"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" StarOutlined"),a("span",{class:"token punctuation"},","),t(" StarFilled"),a("span",{class:"token punctuation"},","),t(" StarTwoTone "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'@ant-design/icons-vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" StarOutlined"),a("span",{class:"token punctuation"},","),t(" StarFilled"),a("span",{class:"token punctuation"},","),t(" StarTwoTone "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),i=a("h2",{id:"svg-sprite-图标"},[a("a",{class:"header-anchor",href:"#svg-sprite-图标","aria-hidden":"true"},"#"),t(" Svg Sprite 图标")],-1),r=a("h3",{id:"使用"},[a("a",{class:"header-anchor",href:"#使用","aria-hidden":"true"},"#"),t(" 使用")],-1),g=a("p",null,[t("将需要的 svg 图标放到"),a("code",null,"src/assets/icons"),t("内")],-1),d=a("p",null,"例: test.svg",-1),f=a("ol",null,[a("li",null,[t("使用"),a("code",null,"SvgIcon"),t("组件进行展示")])],-1),m=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("SvgIcon")]),t(),a("span",{class:"token attr-name"},"name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("test"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/components/Icon'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),y=a("ol",{start:"2"},[a("li",null,[t("使用"),a("code",null,"Icon"),t("组件进行展示")])],-1),v=a("p",null,[t("以 "),a("code",null,"|svg"),t(" 结尾会自动使用"),a("code",null,"SvgIcon"),t("组件")],-1),w=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("Icon")]),t(),a("span",{class:"token attr-name"},"name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("test|svg"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" Icon "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/components/Icon'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" Icon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),h=a("h2",{id:"iconify-图标"},[a("a",{class:"header-anchor",href:"#iconify-图标","aria-hidden":"true"},"#"),t(" Iconify 图标")],-1),S=a("p",null,[t("使用方式请参考 "),a("a",{href:"./../components/icon.html"},"Icon 组件")],-1),I=a("p",null,[t("项目中使用到的是 "),a("a",{href:"https://github.com/antfu/purge-icons/blob/main/packages/vite-plugin-purge-icons/README.md",target:"_blank",rel:"noopener noreferrer"},"vite-plugin-purge-icons"),t(" 这个插件来进行图标实现。")],-1),b=a("ol",null,[a("li",null,"安装依赖")],-1),T=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("\n"),a("span",{class:"token function"},"yarn"),t(),a("span",{class:"token function"},"add"),t(" @iconify/iconify\n\n"),a("span",{class:"token function"},"yarn"),t(),a("span",{class:"token function"},"add"),t(" @iconify/json @purge-icons/generated -D\n\n")])])],-1),x=a("ol",{start:"2"},[a("li",null,[t("在 "),a("code",null,"vite.config.ts"),t("内引入插件")])],-1),C=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(" PurgeIcons "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vite-plugin-purge-icons'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token punctuation"},"{"),t("\n plugins"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),a("span",{class:"token function"},"PurgeIcons"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),q=a("ol",{start:"3"},[a("li",null,"编写 Icon 组件")],-1),_=a("p",null,[t("完整代码 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/blob/main/src/components/Icon/src/Icon.vue",target:"_blank",rel:"noopener noreferrer"},"src/components/Icon/src/Icon.vue")],-1),z=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("SvgIcon")]),t(),a("span",{class:"token attr-name"},":size"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("size"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("getSvgIcon"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},"v-if"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("isSvgIcon"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":class"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("[$attrs.class]"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":spin"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("spin"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("span")]),t("\n "),a("span",{class:"token attr-name"},"v-else"),t("\n "),a("span",{class:"token attr-name"},"ref"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("elRef"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token attr-name"},":class"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("[$attrs.class, "),a("span",{class:"token punctuation"},"'"),t("app-iconify anticon"),a("span",{class:"token punctuation"},"'"),t(", spin && "),a("span",{class:"token punctuation"},"'"),t("app-iconify-spin"),a("span",{class:"token punctuation"},"'"),t("]"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token attr-name"},":style"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("getWrapStyle"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token punctuation"},">")]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),t(),a("span",{class:"token attr-name"},"lang"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("ts"),a("span",{class:"token punctuation"},'"')]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(" type "),a("span",{class:"token punctuation"},"{"),t(" PropType "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t("\n defineComponent"),a("span",{class:"token punctuation"},","),t("\n ref"),a("span",{class:"token punctuation"},","),t("\n watch"),a("span",{class:"token punctuation"},","),t("\n onMounted"),a("span",{class:"token punctuation"},","),t("\n nextTick"),a("span",{class:"token punctuation"},","),t("\n unref"),a("span",{class:"token punctuation"},","),t("\n computed"),a("span",{class:"token punctuation"},","),t("\n CSSProperties"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"import"),t(" SvgIcon "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'./SvgIcon.vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(" Iconify "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'@purge-icons/generated'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" isString "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/utils/is'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" propTypes "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/utils/propTypes'"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"'|svg'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n name"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'GIcon'"),a("span",{class:"token punctuation"},","),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n props"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"// icon name"),t("\n icon"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// icon color"),t("\n color"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// icon size"),t("\n size"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n type"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),t("String"),a("span",{class:"token punctuation"},","),t(" Number"),a("span",{class:"token punctuation"},"]"),t(),a("span",{class:"token keyword"},"as"),t(" PropType"),a("span",{class:"token operator"},"<"),t("string "),a("span",{class:"token operator"},"|"),t(" number"),a("span",{class:"token operator"},">"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token keyword"},"default"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token number"},"16"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n spin"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("bool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"def"),a("span",{class:"token punctuation"},"("),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n prefix"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"def"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token function"},"setup"),a("span",{class:"token punctuation"},"("),a("span",{class:"token parameter"},"props"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" elRef "),a("span",{class:"token operator"},"="),t(" ref"),a("span",{class:"token operator"},"<"),t("ElRef"),a("span",{class:"token operator"},">"),a("span",{class:"token punctuation"},"("),a("span",{class:"token keyword"},"null"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" isSvgIcon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token operator"},"?."),a("span",{class:"token function"},"endsWith"),a("span",{class:"token punctuation"},"("),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" getSvgIcon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"replace"),a("span",{class:"token punctuation"},"("),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" getIconRef "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("props"),a("span",{class:"token punctuation"},"."),t("prefix "),a("span",{class:"token operator"},"?"),t(" props"),a("span",{class:"token punctuation"},"."),t("prefix "),a("span",{class:"token operator"},"+"),t(),a("span",{class:"token string"},"':'"),t(),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"''"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token function-variable function"},"update"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("isSvgIcon"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" el "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("elRef"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("el"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"nextTick"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" icon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("getIconRef"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("icon"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" svg "),a("span",{class:"token operator"},"="),t(" Iconify"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"renderSVG"),a("span",{class:"token punctuation"},"("),t("icon"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token punctuation"},"{"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("svg"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n el"),a("span",{class:"token punctuation"},"."),t("textContent "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"appendChild"),a("span",{class:"token punctuation"},"("),t("svg"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"else"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" span "),a("span",{class:"token operator"},"="),t(" document"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"createElement"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'span'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n span"),a("span",{class:"token punctuation"},"."),t("className "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"'iconify'"),a("span",{class:"token punctuation"},";"),t("\n span"),a("span",{class:"token punctuation"},"."),t("dataset"),a("span",{class:"token punctuation"},"."),t("icon "),a("span",{class:"token operator"},"="),t(" icon"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),t("textContent "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"appendChild"),a("span",{class:"token punctuation"},"("),t("span"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" getWrapStyle "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token parameter"},"CSSProperties"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" size"),a("span",{class:"token punctuation"},","),t(" color "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(" props"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"let"),t(" fs "),a("span",{class:"token operator"},"="),t(" size"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token function"},"isString"),a("span",{class:"token punctuation"},"("),t("size"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n fs "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"parseInt"),a("span",{class:"token punctuation"},"("),t("size"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token number"},"10"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t("\n fontSize"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("fs"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},"px"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},","),t("\n color"),a("span",{class:"token operator"},":"),t(" color"),a("span",{class:"token punctuation"},","),t("\n display"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'inline-flex'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"watch"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token punctuation"},","),t(" update"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token punctuation"},"{"),t(" flush"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'post'"),t(),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"onMounted"),a("span",{class:"token punctuation"},"("),t("update"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t(" elRef"),a("span",{class:"token punctuation"},","),t(" getWrapStyle"),a("span",{class:"token punctuation"},","),t(" isSvgIcon"),a("span",{class:"token punctuation"},","),t(" getSvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("style")]),t(),a("span",{class:"token attr-name"},"lang"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("less"),a("span",{class:"token punctuation"},'"')]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token style"},[a("span",{class:"token language-css"},[t("\n "),a("span",{class:"token selector"},".app-iconify"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"display"),a("span",{class:"token punctuation"},":"),t(" inline-block"),a("span",{class:"token punctuation"},";"),t("\n // "),a("span",{class:"token property"},"vertical-align"),a("span",{class:"token punctuation"},":"),t(" middle"),a("span",{class:"token selector"},";\n\n &-spin"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token selector"},"svg"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"animation"),a("span",{class:"token punctuation"},":"),t(" loadingCircle 1s infinite linear"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n\n "),a("span",{class:"token selector"},"span.iconify"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"display"),a("span",{class:"token punctuation"},":"),t(" block"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"min-width"),a("span",{class:"token punctuation"},":"),t(" 1em"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"min-height"),a("span",{class:"token punctuation"},":"),t(" 1em"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"background-color"),a("span",{class:"token punctuation"},":"),t(),a("span",{class:"token atrule"},[a("span",{class:"token rule"},"@iconify-bg-color"),a("span",{class:"token punctuation"},";")]),t("\n "),a("span",{class:"token property"},"border-radius"),a("span",{class:"token punctuation"},":"),t(" 100%"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),j=a("h2",{id:"图标选择器"},[a("a",{class:"header-anchor",href:"#图标选择器","aria-hidden":"true"},"#"),t(" 图标选择器")],-1),G=a("h3",{id:"图标集预生成"},[a("a",{class:"header-anchor",href:"#图标集预生成","aria-hidden":"true"},"#"),t(" 图标集预生成")],-1),R=a("p",null,"由于图标选择器这个比较特殊的存在,项目会打包一些比较多的图标,图标选择器的图标需要事先指定并生成相应的文件。",-1),E=a("h3",{id:"生成"},[a("a",{class:"header-anchor",href:"#生成","aria-hidden":"true"},"#"),t(" 生成")],-1),P=a("ul",null,[a("li",null,"执行图标生成命令")],-1),W=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" gen:icon\n")])])],-1),D=a("ul",null,[a("li",null,"这里会让你选择本地还是在线生成,两种方式各有利弊。如下图所示")],-1),F=a("p",null,"local 表示本地,online 表示在线,回车确认",-1),N=a("p",null,[a("img",{src:"/images/genIcon.png",alt:""})],-1),$=a("ul",null,[a("li",null,"选择你要生成的图标集,回车确认")],-1),A=a("p",null,[a("img",{src:"/images/selectIconSet.png",alt:""})],-1),V=a("ul",null,[a("li",null,"选择图标输出的目录(项目默认 src/components/Icon/data),可以直接回车选择默认")],-1),H=a("p",null,[a("img",{src:"/images/outDir.png",alt:""})],-1),L=a("p",null,"到这里图标集已经生成完成了,此时你的图标选择器已经是你所选的的图标集的图标了。",-1),M=a("div",{class:"danger custom-block"},[a("p",{class:"custom-block-title"},"注意不要频繁更新"),a("p",null,"如果前面选择的是本地生成的话,频繁更换图标集,可能会导致图标丢失或者显示不出来")],-1),O=a("h3",{id:"优缺点"},[a("a",{class:"header-anchor",href:"#优缺点","aria-hidden":"true"},"#"),t(" 优缺点")],-1),U=a("ul",null,[a("li",null,[a("strong",null,"在线图标(项目默认,推荐)")])],-1),B=a("p",null,"该方式会在图标选择器使用到图标的时候进行在线请求,然后缓存对应的图标到浏览器。可以有效减少代码打包体积。",-1),J=a("p",null,"如果你的项目可以访问外网,建议可以使用这种方式",-1),K=a("p",null,[a("strong",null,"缺点:"),t(" 在局域网或者无法访问到外网的环境中图标显示不出来")],-1),Q=a("ul",null,[a("li",null,[a("strong",null,"本地图标")])],-1),X=a("p",null,"该方式会在打包的时候将图标选择器的图标全部打包到 js 内。在使用的时候不会额外的请求在线图标",-1),Y=a("p",null,[a("strong",null,"缺点:"),t(" 打包体积会偏大,具体的体积增加得看前面选择图标集的时候选择的图标数量的多少决定")],-1);p.render=function(a,t,o,p,Z,nn){return n(),s("div",null,[c,e,l,u,k,i,r,g,d,f,m,y,v,w,h,S,I,b,T,x,C,q,_,z,j,G,R,E,P,W,D,F,N,$,A,V,H,L,M,O,U,B,J,K,Q,X,Y])};export default p;export{o as __pageData}; diff --git a/assets/dep_icon.md.360e0f2b.lean.js b/assets/dep_icon.md.360e0f2b.lean.js new file mode 100644 index 00000000..9eb1480b --- /dev/null +++ b/assets/dep_icon.md.360e0f2b.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const o='{"title":"图标","description":"","frontmatter":{},"headers":[{"level":2,"title":"组件库图标","slug":"组件库图标"},{"level":2,"title":"Svg Sprite 图标","slug":"svg-sprite-图标"},{"level":3,"title":"使用","slug":"使用"},{"level":2,"title":"Iconify 图标","slug":"iconify-图标"},{"level":2,"title":"图标选择器","slug":"图标选择器"},{"level":3,"title":"图标集预生成","slug":"图标集预生成"},{"level":3,"title":"生成","slug":"生成"},{"level":3,"title":"优缺点","slug":"优缺点"}],"relativePath":"dep/icon.md","lastUpdated":1697592578593}',p={},c=a("h1",{id:"图标"},[a("a",{class:"header-anchor",href:"#图标","aria-hidden":"true"},"#"),t(" 图标")],-1),e=a("p",null,"项目中有以下多种图标使用方式。",-1),l=a("h2",{id:"组件库图标"},[a("a",{class:"header-anchor",href:"#组件库图标","aria-hidden":"true"},"#"),t(" 组件库图标")],-1),u=a("p",null,[t("使用 "),a("code",null,"ant-design-vue"),t(" 提供的图标")],-1),k=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarOutlined")]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarFilled")]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("StarTwoTone")]),t(),a("span",{class:"token attr-name"},"twoToneColor"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("#eb2f96"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" StarOutlined"),a("span",{class:"token punctuation"},","),t(" StarFilled"),a("span",{class:"token punctuation"},","),t(" StarTwoTone "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'@ant-design/icons-vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" StarOutlined"),a("span",{class:"token punctuation"},","),t(" StarFilled"),a("span",{class:"token punctuation"},","),t(" StarTwoTone "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),i=a("h2",{id:"svg-sprite-图标"},[a("a",{class:"header-anchor",href:"#svg-sprite-图标","aria-hidden":"true"},"#"),t(" Svg Sprite 图标")],-1),r=a("h3",{id:"使用"},[a("a",{class:"header-anchor",href:"#使用","aria-hidden":"true"},"#"),t(" 使用")],-1),g=a("p",null,[t("将需要的 svg 图标放到"),a("code",null,"src/assets/icons"),t("内")],-1),d=a("p",null,"例: test.svg",-1),f=a("ol",null,[a("li",null,[t("使用"),a("code",null,"SvgIcon"),t("组件进行展示")])],-1),m=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("SvgIcon")]),t(),a("span",{class:"token attr-name"},"name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("test"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/components/Icon'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),y=a("ol",{start:"2"},[a("li",null,[t("使用"),a("code",null,"Icon"),t("组件进行展示")])],-1),v=a("p",null,[t("以 "),a("code",null,"|svg"),t(" 结尾会自动使用"),a("code",null,"SvgIcon"),t("组件")],-1),w=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("Icon")]),t(),a("span",{class:"token attr-name"},"name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("test|svg"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" defineComponent "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" Icon "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/components/Icon'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" Icon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),h=a("h2",{id:"iconify-图标"},[a("a",{class:"header-anchor",href:"#iconify-图标","aria-hidden":"true"},"#"),t(" Iconify 图标")],-1),S=a("p",null,[t("使用方式请参考 "),a("a",{href:"./../components/icon.html"},"Icon 组件")],-1),I=a("p",null,[t("项目中使用到的是 "),a("a",{href:"https://github.com/antfu/purge-icons/blob/main/packages/vite-plugin-purge-icons/README.md",target:"_blank",rel:"noopener noreferrer"},"vite-plugin-purge-icons"),t(" 这个插件来进行图标实现。")],-1),b=a("ol",null,[a("li",null,"安装依赖")],-1),T=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("\n"),a("span",{class:"token function"},"yarn"),t(),a("span",{class:"token function"},"add"),t(" @iconify/iconify\n\n"),a("span",{class:"token function"},"yarn"),t(),a("span",{class:"token function"},"add"),t(" @iconify/json @purge-icons/generated -D\n\n")])])],-1),x=a("ol",{start:"2"},[a("li",null,[t("在 "),a("code",null,"vite.config.ts"),t("内引入插件")])],-1),C=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(" PurgeIcons "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vite-plugin-purge-icons'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token punctuation"},"{"),t("\n plugins"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),a("span",{class:"token function"},"PurgeIcons"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),q=a("ol",{start:"3"},[a("li",null,"编写 Icon 组件")],-1),_=a("p",null,[t("完整代码 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/blob/main/src/components/Icon/src/Icon.vue",target:"_blank",rel:"noopener noreferrer"},"src/components/Icon/src/Icon.vue")],-1),z=a("div",{class:"language-vue"},[a("pre",null,[a("code",null,[a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("template")]),a("span",{class:"token punctuation"},">")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("SvgIcon")]),t(),a("span",{class:"token attr-name"},":size"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("size"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":name"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("getSvgIcon"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},"v-if"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("isSvgIcon"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":class"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("[$attrs.class]"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token attr-name"},":spin"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("spin"),a("span",{class:"token punctuation"},'"')]),t(),a("span",{class:"token punctuation"},"/>")]),t("\n "),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("span")]),t("\n "),a("span",{class:"token attr-name"},"v-else"),t("\n "),a("span",{class:"token attr-name"},"ref"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("elRef"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token attr-name"},":class"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("[$attrs.class, "),a("span",{class:"token punctuation"},"'"),t("app-iconify anticon"),a("span",{class:"token punctuation"},"'"),t(", spin && "),a("span",{class:"token punctuation"},"'"),t("app-iconify-spin"),a("span",{class:"token punctuation"},"'"),t("]"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token attr-name"},":style"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("getWrapStyle"),a("span",{class:"token punctuation"},'"')]),t("\n "),a("span",{class:"token punctuation"},">")]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("script")]),t(),a("span",{class:"token attr-name"},"lang"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("ts"),a("span",{class:"token punctuation"},'"')]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token script"},[a("span",{class:"token language-javascript"},[t("\n "),a("span",{class:"token keyword"},"import"),t(" type "),a("span",{class:"token punctuation"},"{"),t(" PropType "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t("\n defineComponent"),a("span",{class:"token punctuation"},","),t("\n ref"),a("span",{class:"token punctuation"},","),t("\n watch"),a("span",{class:"token punctuation"},","),t("\n onMounted"),a("span",{class:"token punctuation"},","),t("\n nextTick"),a("span",{class:"token punctuation"},","),t("\n unref"),a("span",{class:"token punctuation"},","),t("\n computed"),a("span",{class:"token punctuation"},","),t("\n CSSProperties"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue'"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"import"),t(" SvgIcon "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'./SvgIcon.vue'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(" Iconify "),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'@purge-icons/generated'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" isString "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/utils/is'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" propTypes "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'/@/utils/propTypes'"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"'|svg'"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"export"),t(),a("span",{class:"token keyword"},"default"),t(),a("span",{class:"token function"},"defineComponent"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n name"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'GIcon'"),a("span",{class:"token punctuation"},","),t("\n components"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t(" SvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n props"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"// icon name"),t("\n icon"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// icon color"),t("\n color"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// icon size"),t("\n size"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"{"),t("\n type"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token punctuation"},"["),t("String"),a("span",{class:"token punctuation"},","),t(" Number"),a("span",{class:"token punctuation"},"]"),t(),a("span",{class:"token keyword"},"as"),t(" PropType"),a("span",{class:"token operator"},"<"),t("string "),a("span",{class:"token operator"},"|"),t(" number"),a("span",{class:"token operator"},">"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token keyword"},"default"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token number"},"16"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n spin"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("bool"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"def"),a("span",{class:"token punctuation"},"("),a("span",{class:"token boolean"},"false"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n prefix"),a("span",{class:"token operator"},":"),t(" propTypes"),a("span",{class:"token punctuation"},"."),t("string"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"def"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token function"},"setup"),a("span",{class:"token punctuation"},"("),a("span",{class:"token parameter"},"props"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" elRef "),a("span",{class:"token operator"},"="),t(" ref"),a("span",{class:"token operator"},"<"),t("ElRef"),a("span",{class:"token operator"},">"),a("span",{class:"token punctuation"},"("),a("span",{class:"token keyword"},"null"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" isSvgIcon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token operator"},"?."),a("span",{class:"token function"},"endsWith"),a("span",{class:"token punctuation"},"("),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" getSvgIcon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"replace"),a("span",{class:"token punctuation"},"("),a("span",{class:"token constant"},"SVG_END_WITH_FLAG"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" getIconRef "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("props"),a("span",{class:"token punctuation"},"."),t("prefix "),a("span",{class:"token operator"},"?"),t(" props"),a("span",{class:"token punctuation"},"."),t("prefix "),a("span",{class:"token operator"},"+"),t(),a("span",{class:"token string"},"':'"),t(),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"''"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token function-variable function"},"update"),t(),a("span",{class:"token operator"},"="),t(),a("span",{class:"token keyword"},"async"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("isSvgIcon"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" el "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("elRef"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("el"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"await"),t(),a("span",{class:"token function"},"nextTick"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"const"),t(" icon "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"unref"),a("span",{class:"token punctuation"},"("),t("getIconRef"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token operator"},"!"),t("icon"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token keyword"},"return"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" svg "),a("span",{class:"token operator"},"="),t(" Iconify"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"renderSVG"),a("span",{class:"token punctuation"},"("),t("icon"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token punctuation"},"{"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),t("svg"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n el"),a("span",{class:"token punctuation"},"."),t("textContent "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"appendChild"),a("span",{class:"token punctuation"},"("),t("svg"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"else"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(" span "),a("span",{class:"token operator"},"="),t(" document"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"createElement"),a("span",{class:"token punctuation"},"("),a("span",{class:"token string"},"'span'"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n span"),a("span",{class:"token punctuation"},"."),t("className "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"'iconify'"),a("span",{class:"token punctuation"},";"),t("\n span"),a("span",{class:"token punctuation"},"."),t("dataset"),a("span",{class:"token punctuation"},"."),t("icon "),a("span",{class:"token operator"},"="),t(" icon"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),t("textContent "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token string"},"''"),a("span",{class:"token punctuation"},";"),t("\n el"),a("span",{class:"token punctuation"},"."),a("span",{class:"token function"},"appendChild"),a("span",{class:"token punctuation"},"("),t("span"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"const"),t(" getWrapStyle "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"computed"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token parameter"},"CSSProperties"),t(),a("span",{class:"token operator"},"=>"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token keyword"},"const"),t(),a("span",{class:"token punctuation"},"{"),t(" size"),a("span",{class:"token punctuation"},","),t(" color "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token operator"},"="),t(" props"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"let"),t(" fs "),a("span",{class:"token operator"},"="),t(" size"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token function"},"isString"),a("span",{class:"token punctuation"},"("),t("size"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n fs "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token function"},"parseInt"),a("span",{class:"token punctuation"},"("),t("size"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token number"},"10"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t("\n fontSize"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token template-string"},[a("span",{class:"token template-punctuation string"},"`"),a("span",{class:"token interpolation"},[a("span",{class:"token interpolation-punctuation punctuation"},"${"),t("fs"),a("span",{class:"token interpolation-punctuation punctuation"},"}")]),a("span",{class:"token string"},"px"),a("span",{class:"token template-punctuation string"},"`")]),a("span",{class:"token punctuation"},","),t("\n color"),a("span",{class:"token operator"},":"),t(" color"),a("span",{class:"token punctuation"},","),t("\n display"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'inline-flex'"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"watch"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token operator"},"=>"),t(" props"),a("span",{class:"token punctuation"},"."),t("icon"),a("span",{class:"token punctuation"},","),t(" update"),a("span",{class:"token punctuation"},","),t(),a("span",{class:"token punctuation"},"{"),t(" flush"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token string"},"'post'"),t(),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token function"},"onMounted"),a("span",{class:"token punctuation"},"("),t("update"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token keyword"},"return"),t(),a("span",{class:"token punctuation"},"{"),t(" elRef"),a("span",{class:"token punctuation"},","),t(" getWrapStyle"),a("span",{class:"token punctuation"},","),t(" isSvgIcon"),a("span",{class:"token punctuation"},","),t(" getSvgIcon "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n"),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"<"),t("style")]),t(),a("span",{class:"token attr-name"},"lang"),a("span",{class:"token attr-value"},[a("span",{class:"token punctuation attr-equals"},"="),a("span",{class:"token punctuation"},'"'),t("less"),a("span",{class:"token punctuation"},'"')]),a("span",{class:"token punctuation"},">")]),a("span",{class:"token style"},[a("span",{class:"token language-css"},[t("\n "),a("span",{class:"token selector"},".app-iconify"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"display"),a("span",{class:"token punctuation"},":"),t(" inline-block"),a("span",{class:"token punctuation"},";"),t("\n // "),a("span",{class:"token property"},"vertical-align"),a("span",{class:"token punctuation"},":"),t(" middle"),a("span",{class:"token selector"},";\n\n &-spin"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token selector"},"svg"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"animation"),a("span",{class:"token punctuation"},":"),t(" loadingCircle 1s infinite linear"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n\n "),a("span",{class:"token selector"},"span.iconify"),t(),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token property"},"display"),a("span",{class:"token punctuation"},":"),t(" block"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"min-width"),a("span",{class:"token punctuation"},":"),t(" 1em"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"min-height"),a("span",{class:"token punctuation"},":"),t(" 1em"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token property"},"background-color"),a("span",{class:"token punctuation"},":"),t(),a("span",{class:"token atrule"},[a("span",{class:"token rule"},"@iconify-bg-color"),a("span",{class:"token punctuation"},";")]),t("\n "),a("span",{class:"token property"},"border-radius"),a("span",{class:"token punctuation"},":"),t(" 100%"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n")])]),a("span",{class:"token tag"},[a("span",{class:"token tag"},[a("span",{class:"token punctuation"},"")]),t("\n")])])],-1),j=a("h2",{id:"图标选择器"},[a("a",{class:"header-anchor",href:"#图标选择器","aria-hidden":"true"},"#"),t(" 图标选择器")],-1),G=a("h3",{id:"图标集预生成"},[a("a",{class:"header-anchor",href:"#图标集预生成","aria-hidden":"true"},"#"),t(" 图标集预生成")],-1),R=a("p",null,"由于图标选择器这个比较特殊的存在,项目会打包一些比较多的图标,图标选择器的图标需要事先指定并生成相应的文件。",-1),E=a("h3",{id:"生成"},[a("a",{class:"header-anchor",href:"#生成","aria-hidden":"true"},"#"),t(" 生成")],-1),P=a("ul",null,[a("li",null,"执行图标生成命令")],-1),W=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" gen:icon\n")])])],-1),D=a("ul",null,[a("li",null,"这里会让你选择本地还是在线生成,两种方式各有利弊。如下图所示")],-1),F=a("p",null,"local 表示本地,online 表示在线,回车确认",-1),N=a("p",null,[a("img",{src:"/images/genIcon.png",alt:""})],-1),$=a("ul",null,[a("li",null,"选择你要生成的图标集,回车确认")],-1),A=a("p",null,[a("img",{src:"/images/selectIconSet.png",alt:""})],-1),V=a("ul",null,[a("li",null,"选择图标输出的目录(项目默认 src/components/Icon/data),可以直接回车选择默认")],-1),H=a("p",null,[a("img",{src:"/images/outDir.png",alt:""})],-1),L=a("p",null,"到这里图标集已经生成完成了,此时你的图标选择器已经是你所选的的图标集的图标了。",-1),M=a("div",{class:"danger custom-block"},[a("p",{class:"custom-block-title"},"注意不要频繁更新"),a("p",null,"如果前面选择的是本地生成的话,频繁更换图标集,可能会导致图标丢失或者显示不出来")],-1),O=a("h3",{id:"优缺点"},[a("a",{class:"header-anchor",href:"#优缺点","aria-hidden":"true"},"#"),t(" 优缺点")],-1),U=a("ul",null,[a("li",null,[a("strong",null,"在线图标(项目默认,推荐)")])],-1),B=a("p",null,"该方式会在图标选择器使用到图标的时候进行在线请求,然后缓存对应的图标到浏览器。可以有效减少代码打包体积。",-1),J=a("p",null,"如果你的项目可以访问外网,建议可以使用这种方式",-1),K=a("p",null,[a("strong",null,"缺点:"),t(" 在局域网或者无法访问到外网的环境中图标显示不出来")],-1),Q=a("ul",null,[a("li",null,[a("strong",null,"本地图标")])],-1),X=a("p",null,"该方式会在打包的时候将图标选择器的图标全部打包到 js 内。在使用的时候不会额外的请求在线图标",-1),Y=a("p",null,[a("strong",null,"缺点:"),t(" 打包体积会偏大,具体的体积增加得看前面选择图标集的时候选择的图标数量的多少决定")],-1);p.render=function(a,t,o,p,Z,nn){return n(),s("div",null,[c,e,l,u,k,i,r,g,d,f,m,y,v,w,h,S,I,b,T,x,C,q,_,z,j,G,R,E,P,W,D,F,N,$,A,V,H,L,M,O,U,B,J,K,Q,X,Y])};export default p;export{o as __pageData}; diff --git a/assets/dep_lint.md.ebbe5471.js b/assets/dep_lint.md.ebbe5471.js new file mode 100644 index 00000000..074090ea --- /dev/null +++ b/assets/dep_lint.md.ebbe5471.js @@ -0,0 +1 @@ +import{o as e,c as s,a as n}from"./app.8cddb23b.js";const a='{"title":"Lint","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"ESLint","slug":"eslint"},{"level":3,"title":"手动校验代码","slug":"手动校验代码"},{"level":3,"title":"配置项","slug":"配置项"},{"level":3,"title":"编辑器配合","slug":"编辑器配合"},{"level":2,"title":"CommitLint","slug":"commitlint"},{"level":3,"title":"配置","slug":"配置"},{"level":3,"title":"Git 提交规范","slug":"git-提交规范"},{"level":3,"title":"如何关闭","slug":"如何关闭"},{"level":3,"title":"示例","slug":"示例"},{"level":2,"title":"Stylelint","slug":"stylelint"},{"level":3,"title":"配置","slug":"配置-1"},{"level":3,"title":"编辑器配合","slug":"编辑器配合-1"},{"level":2,"title":"Prettier","slug":"prettier"},{"level":3,"title":"配置","slug":"配置-2"},{"level":3,"title":"编辑器配合","slug":"编辑器配合-2"},{"level":2,"title":"Git Hook","slug":"git-hook"},{"level":3,"title":"husky","slug":"husky"},{"level":3,"title":"如何关闭","slug":"如何关闭-1"},{"level":3,"title":"如何跳过某一个检查","slug":"如何跳过某一个检查"},{"level":3,"title":"lint-staged","slug":"lint-staged"}],"relativePath":"dep/lint.md","lastUpdated":1697592578593}',t={},i=n('

Lint

介绍

使用 lint 的好处

具备基本工程素养的同学都会注重编码规范,而代码风格检查(Code Linting,简称 Lint)是保障代码规范一致性的重要手段。

遵循相应的代码规范有以下好处

  • 较少 bug 错误率
  • 高效的开发效率
  • 更高的可读性

项目内集成了以下几种代码校验方式

  1. eslint 用于校验代码格式规范
  2. commitlint 用于校验 git 提交信息规范
  3. stylelint 用于校验 css/less 规范
  4. prettier 代码格式化

WARNING

lint 不是必须的,但是很有必要,一个项目做大了以后或者参与人员过多后,就会出现各种风格迥异的代码,对后续的维护造成了一定的麻烦

ESLint

ESLint 是一个代码规范和错误检查工具,有以下几个特性

  • 所有东西都是可以插拔的。你可以调用任意的 rule api 或者 formatter api 去打包或者定义 rule or formatter。
  • 任意的 rule 都是独立的
  • 没有特定的 coding style,你可以自己配置

手动校验代码

# 执行下面代码.能修复的会自动修复,不能修复的需要手动修改\nyarn run lint:eslint\n

配置项

项目的 eslint 配置位于根目录下 .eslintrc.js 内,可以根据团队自行修改代码规范

编辑器配合

推荐使用 vscode 进行开发,vscode 自带 eslint 插件,可以自动修改一些错误。

同时项目内也自带了 vscode eslint 配置,具体在 .vscode/setting.json 文件夹内部。只要使用 vscode 开发不用任何设置即可使用

CommitLint

在一个团队中,每个人的 git 的 commit 信息都不一样,五花八门,没有一个机制很难保证规范化,如何才能规范化呢?可能你想到的是 git 的 hook 机制,去写 shell 脚本去实现。这当然可以,其实 JavaScript 有一个很好的工具可以实现这个模板,它就是 commitlint(用于校验 git 提交信息规范)。

配置

commit-lint 的配置位于项目根目录下 commitlint.config.js

Git 提交规范

  • 参考 vue 规范 (Angular)

    • feat 增加新功能
    • fix 修复问题/BUG
    • style 代码风格相关无影响运行结果的
    • perf 优化/性能提升
    • refactor 重构
    • revert 撤销修改
    • test 测试相关
    • docs 文档/注释
    • chore 依赖更新/脚手架配置修改等
    • workflow 工作流改进
    • ci 持续集成
    • mod 不确定分类的修改
    • wip 开发中
    • types 类型修改

如何关闭

.husky/commit-msg 内注释以下代码即可

# npx --no-install commitlint --edit "$1"\n

示例

\ngit commit -m 'feat(home): add home page'\n\n

Stylelint

stylelint 用于校验项目内部 css 的风格,加上编辑器的自动修复,可以很好的统一项目内部 css 风格

配置

stylelint 配置位于根目录下 stylelint.config.js

编辑器配合

如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 css 样式

插件

StyleLint

Prettier

prettier 可以用于统一项目代码风格,统一的缩进,单双引号,尾逗号等等风格

配置

prettier 配置文件位于项目根目录下 prettier.config.js

编辑器配合

如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 js 格式

插件

Prettier

Git Hook

git hook 一般结合各种 lint,在 git 提交代码的时候进行代码风格校验,如果校验没通过,则不会进行提交。需要开发者自行修改后再次进行提交

husky

有一个问题就是校验会校验全部代码,但是我们只想校验我们自己提交的代码,这个时候就可以使用 husky。

最有效的解决方案就是将 Lint 校验放到本地,常见做法是使用 husky 或者 pre-commit 在本地提交之前先做一次 Lint 校验。

项目在 .husky 内部定义了相应的 hooks

如何关闭

# 删除husky依赖即可\nyarn remove huksy\n\n

如何跳过某一个检查

# 加上 --no-verify即可跳过git hook校验(--no-verify 简写为 -n)\ngit commit -m "xxx" --no-verify\n

lint-staged

用于自动修复提交文件风格问题

lint-staged 配置位于项目 .husky 目录下 lintstagedrc.js

module.exports = {\n  // 对指定格式文件 在提交的时候执行相应的修复命令\n  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],\n  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],\n  'package.json': ['prettier --write'],\n  '*.vue': ['eslint --fix', 'stylelint --fix', 'prettier --write', 'git add .'],\n  '*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write', 'git add .'],\n  '*.md': ['prettier --write'],\n};\n
',57);t.render=function(n,a,t,l,o,r){return e(),s("div",null,[i])};export default t;export{a as __pageData}; diff --git a/assets/dep_lint.md.ebbe5471.lean.js b/assets/dep_lint.md.ebbe5471.lean.js new file mode 100644 index 00000000..2f7a0b42 --- /dev/null +++ b/assets/dep_lint.md.ebbe5471.lean.js @@ -0,0 +1 @@ +import{o as e,c as s,a as n}from"./app.8cddb23b.js";const a='{"title":"Lint","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"ESLint","slug":"eslint"},{"level":3,"title":"手动校验代码","slug":"手动校验代码"},{"level":3,"title":"配置项","slug":"配置项"},{"level":3,"title":"编辑器配合","slug":"编辑器配合"},{"level":2,"title":"CommitLint","slug":"commitlint"},{"level":3,"title":"配置","slug":"配置"},{"level":3,"title":"Git 提交规范","slug":"git-提交规范"},{"level":3,"title":"如何关闭","slug":"如何关闭"},{"level":3,"title":"示例","slug":"示例"},{"level":2,"title":"Stylelint","slug":"stylelint"},{"level":3,"title":"配置","slug":"配置-1"},{"level":3,"title":"编辑器配合","slug":"编辑器配合-1"},{"level":2,"title":"Prettier","slug":"prettier"},{"level":3,"title":"配置","slug":"配置-2"},{"level":3,"title":"编辑器配合","slug":"编辑器配合-2"},{"level":2,"title":"Git Hook","slug":"git-hook"},{"level":3,"title":"husky","slug":"husky"},{"level":3,"title":"如何关闭","slug":"如何关闭-1"},{"level":3,"title":"如何跳过某一个检查","slug":"如何跳过某一个检查"},{"level":3,"title":"lint-staged","slug":"lint-staged"}],"relativePath":"dep/lint.md","lastUpdated":1697592578593}',t={},i=n('',57);t.render=function(n,a,t,l,o,r){return e(),s("div",null,[i])};export default t;export{a as __pageData}; diff --git a/assets/guide_auth.md.912002be.js b/assets/guide_auth.md.912002be.js new file mode 100644 index 00000000..c8189193 --- /dev/null +++ b/assets/guide_auth.md.912002be.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"权限","description":"","frontmatter":{},"headers":[{"level":2,"title":"前端角色权限","slug":"前端角色权限"},{"level":3,"title":"实现","slug":"实现"},{"level":3,"title":"动态更换角色","slug":"动态更换角色"},{"level":3,"title":"细粒度权限","slug":"细粒度权限"},{"level":2,"title":"后台动态获取","slug":"后台动态获取"},{"level":3,"title":"实现","slug":"实现-1"},{"level":3,"title":"动态更换菜单","slug":"动态更换菜单"},{"level":3,"title":"细粒度权限","slug":"细粒度权限-1"},{"level":3,"title":"如何初始化 code","slug":"如何初始化-code"}],"relativePath":"guide/auth.md","lastUpdated":1697592578593}',p={},o=a('

权限

项目中集成了三种权限处理方式:

  1. 通过用户角色来过滤菜单(前端方式控制),菜单和路由分开配置
  2. 通过用户角色来过滤菜单(前端方式控制),菜单由路由配置自动生成
  3. 通过后台来动态生成路由表(后台方式控制)

前端角色权限

实现原理: 在前端固定写死路由的权限,指定路由有哪些权限可以查看。只初始化通用的路由,需要权限才能访问的路由没有被加入路由表内。在登陆后或者其他方式获取用户角色后,通过角色去遍历路由表,获取该角色可以访问的路由表,生成路由表,再通过 router.addRoutes 添加到路由实例,实现权限的过滤。

缺点: 权限相对不自由,如果后台改动角色,前台也需要跟着改动。适合角色较固定的系统

实现

  1. 项目配置将系统内权限模式改为 ROLE 模式
// ! 改动后需要清空浏览器缓存\nconst setting: ProjectConfig = {\n  // 权限模式\n  permissionMode: PermissionModeEnum.ROLE,\n};\n
  1. 在路由表配置路由所需的权限,如果不配置,默认可见(见注释)
import type { AppRouteModule } from '/@/router/types';\n\nimport { getParentLayout, LAYOUT } from '/@/router/constant';\nimport { RoleEnum } from '/@/enums/roleEnum';\nimport { t } from '/@/hooks/web/useI18n';\n\nconst permission: AppRouteModule = {\n  path: '/permission',\n  name: 'Permission',\n  component: LAYOUT,\n  redirect: '/permission/front/page',\n  meta: {\n    icon: 'ion:key-outline',\n    title: t('routes.demo.permission.permission'),\n  },\n\n  children: [\n    {\n      path: 'front',\n      name: 'PermissionFrontDemo',\n      component: getParentLayout('PermissionFrontDemo'),\n      meta: {\n        title: t('routes.demo.permission.front'),\n      },\n      children: [\n        {\n          path: 'auth-pageA',\n          name: 'FrontAuthPageA',\n          component: () => import('/@/views/demo/permission/front/AuthPageA.vue'),\n          meta: {\n            title: t('routes.demo.permission.frontTestA'),\n            roles: [RoleEnum.SUPER],\n          },\n        },\n        {\n          path: 'auth-pageB',\n          name: 'FrontAuthPageB',\n          component: () => import('/@/views/demo/permission/front/AuthPageB.vue'),\n          meta: {\n            title: t('routes.demo.permission.frontTestB'),\n            roles: [RoleEnum.TEST],\n          },\n        },\n      ],\n    },\n  ],\n};\n\nexport default permission;\n
  1. 在路由钩子内动态判断

详细代码见 src/router/guard/permissionGuard.ts

// 这里只列举了主要代码\nconst routes = await permissionStore.buildRoutesAction();\n\nroutes.forEach((route) => {\n  router.addRoute(route as unknown as RouteRecordRaw);\n});\n\nconst redirectPath = (from.query.redirect || to.path) as string;\nconst redirect = decodeURIComponent(redirectPath);\nconst nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };\npermissionStore.setDynamicAddedRoute(true);\nnext(nextData);\n

permissionStore.buildRoutesAction 用于过滤动态路由,详细代码见 src/store/modules/permission.ts

// 主要代码\nif (permissionMode === PermissionModeEnum.ROLE) {\n  const routeFilter = (route: AppRouteRecordRaw) => {\n    const { meta } = route;\n    const { roles } = meta || {};\n    if (!roles) return true;\n    return roleList.some((role) => roles.includes(role));\n  };\n  routes = filter(asyncRoutes, routeFilter);\n  routes = routes.filter(routeFilter);\n  // Convert multi-level routing to level 2 routing\n  routes = flatMultiLevelRoutes(routes);\n}\n

动态更换角色

系统提供 usePermission 方便角色相关操作

import { usePermission } from '/@/hooks/web/usePermission';\nimport { RoleEnum } from '/@/enums/roleEnum';\n\nexport default defineComponent({\n  setup() {\n    const { changeRole } = usePermission();\n    // 更换为test角色\n    // 动态更改角色,传入角色名称,可以是数组\n    changeRole(RoleEnum.TEST);\n    return {};\n  },\n});\n

细粒度权限

函数方式

usePermission 还提供了按钮级别的权限控制。

<template>\n  <a-button v-if="hasPermission([RoleEnum.TEST, RoleEnum.SUPER])" color="error" class="mx-4">\n    拥有[test,super]角色权限可见\n  </a-button>\n</template>\n<script lang="ts">\n  import { usePermission } from '/@/hooks/web/usePermission';\n  import { RoleEnum } from '/@/enums/roleEnum';\n\n  export default defineComponent({\n    setup() {\n      const { hasPermission } = usePermission();\n\n      return { hasPermission };\n    },\n  });\n</script>\n

组件方式

具体查看权限组件使用

指令方式

TIP

指令方式不能动态更改权限

<a-button v-auth="RoleEnum.SUPER" type="primary" class="mx-4"> 拥有super角色权限可见</a-button>\n

后台动态获取

实现原理: 是通过接口动态生成路由表,且遵循一定的数据结构返回。前端根据需要处理该数据为可识别的结构,再通过 router.addRoutes 添加到路由实例,实现权限的动态生成。

实现

  1. 项目配置将系统内权限模式改为 BACK 模式
// ! 改动后需要清空浏览器缓存\nconst setting: ProjectConfig = {\n  // 权限模式\n  permissionMode: PermissionModeEnum.BACK,\n};\n
  1. 路由拦截,与角色权限模式一致

permissionStore.buildRoutesAction 用于过滤动态路由,详细代码见 /@/store/modules/permission.ts

// 主要代码\nif (permissionMode === PermissionModeEnum.BACK) {\n  const { createMessage } = useMessage();\n\n  createMessage.loading({\n    content: t('sys.app.menuLoading'),\n    duration: 1,\n  });\n\n  // !Simulate to obtain permission codes from the background,\n  // this function may only need to be executed once, and the actual project can be put at the right time by itself\n  let routeList: AppRouteRecordRaw[] = [];\n  try {\n    this.changePermissionCode();\n    routeList = (await getMenuList()) as AppRouteRecordRaw[];\n  } catch (error) {\n    console.error(error);\n  }\n\n  // Dynamically introduce components\n  routeList = transformObjToRoute(routeList);\n\n  //  Background routing to menu structure\n  const backMenuList = transformRouteToMenu(routeList);\n  this.setBackMenuList(backMenuList);\n\n  routeList = flatMultiLevelRoutes(routeList);\n  routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];\n}\n

getMenuList 返回值格式

返回值由多个路由模块组成

注意

后端接口返回的数据中必须包含PageEnum.BASE_HOME指定的路由(path定义于src/enums/pageEnum.ts

[\n  {\n    path: '/dashboard',\n    name: 'Dashboard',\n    component: '/dashboard/welcome/index',\n    meta: {\n      title: 'routes.dashboard.welcome',\n      affix: true,\n      icon: 'ant-design:home-outlined',\n    },\n  },\n  {\n    path: '/permission',\n    name: 'Permission',\n    component: 'LAYOUT',\n    redirect: '/permission/front/page',\n    meta: {\n      icon: 'carbon:user-role',\n      title: 'routes.demo.permission.permission',\n    },\n    children: [\n      {\n        path: 'back',\n        name: 'PermissionBackDemo',\n        meta: {\n          title: 'routes.demo.permission.back',\n        },\n\n        children: [\n          {\n            path: 'page',\n            name: 'BackAuthPage',\n            component: '/demo/permission/back/index',\n            meta: {\n              title: 'routes.demo.permission.backPage',\n            },\n          },\n          {\n            path: 'btn',\n            name: 'BackAuthBtn',\n            component: '/demo/permission/back/Btn',\n            meta: {\n              title: 'routes.demo.permission.backBtn',\n            },\n          },\n        ],\n      },\n    ],\n  },\n];\n

动态更换菜单

系统提供 usePermission 方便角色相关操作

import { usePermission } from '/@/hooks/web/usePermission';\nimport { RoleEnum } from '/@/enums/roleEnum';\n\nexport default defineComponent({\n  setup() {\n    const { changeMenu } = usePermission();\n\n    // 更改菜单的实现需要自行去修改\n    changeMenu();\n    return {};\n  },\n});\n

细粒度权限

函数方式

usePermission 还提供了按钮级别的权限控制。

<template>\n  <a-button v-if="hasPermission(['20000', '2000010'])" color="error" class="mx-4">\n    拥有[20000,2000010]code可见\n  </a-button>\n</template>\n<script lang="ts">\n  import { usePermission } from '/@/hooks/web/usePermission';\n  import { RoleEnum } from '/@/enums/roleEnum';\n\n  export default defineComponent({\n    setup() {\n      const { hasPermission } = usePermission();\n      return { hasPermission };\n    },\n  });\n</script>\n

组件方式

具体查看权限组件使用

指令方式

TIP

指令方式不能动态更改权限

<a-button v-auth="'1000'" type="primary" class="mx-4"> 拥有code ['1000']权限可见 </a-button>\n

如何初始化 code

通常,如需做按钮级别权限,后台会提供相应的 code,或者类型的判断标识。这些编码只需要在登录后获取一次即可。

import { getPermCodeByUserId } from '/@/api/sys/user';\nimport { permissionStore } from '/@/store/modules/permission';\nasync function changePermissionCode(userId: string) {\n  // 从后台获取当前用户拥有的编码\n  const codeList = await getPermCodeByUserId({ userId });\n  permissionStore.commitPermCodeListState(codeList);\n}\n
',55);p.render=function(a,t,p,e,c,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_auth.md.912002be.lean.js b/assets/guide_auth.md.912002be.lean.js new file mode 100644 index 00000000..6c0d6dcd --- /dev/null +++ b/assets/guide_auth.md.912002be.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"权限","description":"","frontmatter":{},"headers":[{"level":2,"title":"前端角色权限","slug":"前端角色权限"},{"level":3,"title":"实现","slug":"实现"},{"level":3,"title":"动态更换角色","slug":"动态更换角色"},{"level":3,"title":"细粒度权限","slug":"细粒度权限"},{"level":2,"title":"后台动态获取","slug":"后台动态获取"},{"level":3,"title":"实现","slug":"实现-1"},{"level":3,"title":"动态更换菜单","slug":"动态更换菜单"},{"level":3,"title":"细粒度权限","slug":"细粒度权限-1"},{"level":3,"title":"如何初始化 code","slug":"如何初始化-code"}],"relativePath":"guide/auth.md","lastUpdated":1697592578593}',p={},o=a('',55);p.render=function(a,t,p,e,c,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_component.md.ad92b1a7.js b/assets/guide_component.md.ad92b1a7.js new file mode 100644 index 00000000..d0b2d3d2 --- /dev/null +++ b/assets/guide_component.md.ad92b1a7.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"组件注册","description":"","frontmatter":{},"headers":[{"level":2,"title":"按需引入","slug":"按需引入"},{"level":3,"title":"tsx 文件注册","slug":"tsx-文件注册"},{"level":2,"title":"全局注册","slug":"全局注册"},{"level":3,"title":"全局按需注册","slug":"全局按需注册"},{"level":3,"title":"全量注册","slug":"全量注册"}],"relativePath":"guide/component.md","lastUpdated":1697592578593}',p={},o=a('

组件注册

按需引入

项目目前的组件注册机制是按需注册,是在需要用到的页面才引入。

<template>\n  <Menu>\n    <SubMenu></SubMenu>\n  <Menu>\n\n  <menu>\n    <sub-menu></sub-menu>\n  <menu>\n</template>\n<script>\nimport { Menu } from 'ant-design-vue';\nexport default defineComponent({\n  components: {\n    Menu: Menu,\n    SubMenu: Menu.SubMenu\n  },\n})\n</script>\n

tsx 文件注册

tsx 文件内不能使用全局注册组件

import { Menu } from 'ant-design-vue';\n\nexport default defineComponent({\n  setup() {\n    return () => (\n      <Menu>\n        <Menu.SubMenu></Menu.SubMenu>\n      </Menu>\n    );\n  },\n});\n

全局注册

如果不习惯按需引入方式,可以进行全局注册。全局注册也分两种方式

全局按需注册

只注册需要的组件

代码地址:src/components/registerGlobComp.ts

import {\n  // Need\n  Button as AntButton,\n  Optional,\n  Select,\n  Alert,\n  Checkbox,\n  DatePicker,\n  Radio,\n  Switch,\n  Card,\n  List,\n  Tabs,\n  Descriptions,\n  Tree,\n  Table,\n  Divider,\n  Modal,\n  Drawer,\n  Dropdown,\n  Tag,\n  Tooltip,\n  Badge,\n  Popover,\n  Upload,\n  Transfer,\n  Steps,\n  PageHeader,\n  Result,\n  Empty,\n  Avatar,\n  Menu,\n  Breadcrumb,\n  Form,\n  Input,\n  Row,\n  Col,\n  Spin,\n} from 'ant-design-vue';\n\nexport function registerGlobComp(app: App) {\n  app\n    .use(Select)\n    .use(Alert)\n    .use(Breadcrumb)\n    .use(Checkbox)\n    .use(DatePicker)\n    .use(Radio)\n    .use(Switch)\n    .use(Card)\n    .use(List)\n    .use(Descriptions)\n    .use(Tree)\n    .use(Table)\n    .use(Divider)\n    .use(Modal)\n    .use(Drawer)\n    .use(Dropdown)\n    .use(Tag)\n    .use(Tooltip)\n    .use(Badge)\n    .use(Popover)\n    .use(Upload)\n    .use(Transfer)\n    .use(Steps)\n    .use(PageHeader)\n    .use(Result)\n    .use(Empty)\n    .use(Avatar)\n    .use(Menu)\n    .use(Tabs)\n    .use(Form)\n    .use(Input)\n    .use(Row)\n    .use(Col)\n    .use(Spin);\n}\n

全量注册

  • main.ts
import { createApp } from 'vue';\nimport Antd from 'ant-design-vue';\nimport 'ant-design-vue/dist/antd.less';\nconst app = createApp(App);\napp.use(Antd);\n
  • 删除以下代码
if (import.meta.env.DEV) {\n  import('ant-design-vue/dist/antd.less');\n}\n
',18);p.render=function(a,t,p,c,e,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_component.md.ad92b1a7.lean.js b/assets/guide_component.md.ad92b1a7.lean.js new file mode 100644 index 00000000..4b4d5558 --- /dev/null +++ b/assets/guide_component.md.ad92b1a7.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"组件注册","description":"","frontmatter":{},"headers":[{"level":2,"title":"按需引入","slug":"按需引入"},{"level":3,"title":"tsx 文件注册","slug":"tsx-文件注册"},{"level":2,"title":"全局注册","slug":"全局注册"},{"level":3,"title":"全局按需注册","slug":"全局按需注册"},{"level":3,"title":"全量注册","slug":"全量注册"}],"relativePath":"guide/component.md","lastUpdated":1697592578593}',p={},o=a('',18);p.render=function(a,t,p,c,e,u){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_deploy.md.d904a197.js b/assets/guide_deploy.md.d904a197.js new file mode 100644 index 00000000..d0a43511 --- /dev/null +++ b/assets/guide_deploy.md.d904a197.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const e='{"title":"构建&部署","description":"","frontmatter":{},"headers":[{"level":2,"title":"构建","slug":"构建"},{"level":3,"title":"旧版浏览器兼容","slug":"旧版浏览器兼容"},{"level":3,"title":"预览","slug":"预览"},{"level":3,"title":"分析构建文件体积","slug":"分析构建文件体积"},{"level":2,"title":"压缩","slug":"压缩"},{"level":3,"title":"开启 gzip 压缩","slug":"开启-gzip-压缩"},{"level":3,"title":"开启 brotli 压缩","slug":"开启-brotli-压缩"},{"level":3,"title":"同时开启 gzip 与 brotli","slug":"同时开启-gzip-与-brotli"},{"level":3,"title":"gzip 与 brotli 在 nginx 内的配置","slug":"gzip-与-brotli-在-nginx-内的配置"},{"level":2,"title":"部署","slug":"部署"},{"level":3,"title":"发布","slug":"发布"},{"level":3,"title":"前端路由与服务端的结合","slug":"前端路由与服务端的结合"},{"level":3,"title":"history 路由模式下服务端配置","slug":"history-路由模式下服务端配置"},{"level":3,"title":"使用 nginx 处理跨域","slug":"使用-nginx-处理跨域"}],"relativePath":"guide/deploy.md","lastUpdated":1697592578593}',l={},o=a("h1",{id:"构建-部署"},[a("a",{class:"header-anchor",href:"#构建-部署","aria-hidden":"true"},"#"),t(" 构建&部署")],-1),c=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"前言"),a("p",null,"由于是展示项目,所以打包后相对较大,如果项目中没有用到的插件,可以删除对应的文件或者路由,不引用即可,没有引用就不会打包。"),a("p",null,[t("当然,你也可以使用精简版 "),a("a",{href:"https://github.com/vbenjs/vben-admin-thin-next",target:"_blank",rel:"noopener noreferrer"},"vue-vben-admin-thin"),t(" 进行开发。")])],-1),i=a("h2",{id:"构建"},[a("a",{class:"header-anchor",href:"#构建","aria-hidden":"true"},"#"),t(" 构建")],-1),p=a("p",null,"项目开发完成之后,执行以下命令进行构建",-1),u=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" build\n")])])],-1),r=a("p",null,"构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件",-1),d=a("h3",{id:"旧版浏览器兼容"},[a("a",{class:"header-anchor",href:"#旧版浏览器兼容","aria-hidden":"true"},"#"),t(" 旧版浏览器兼容")],-1),k=a("p",null,[t("在 "),a("strong",null,".env.production"),t(" 内")],-1),h=a("p",null,[t("设置 "),a("code",null,"VITE_LEGACY=true"),t(" 即可打包出兼容旧版浏览器的代码")],-1),g=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("VITE_LEGACY "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token boolean"},"true"),t("\n")])])],-1),m=a("h3",{id:"预览"},[a("a",{class:"header-anchor",href:"#预览","aria-hidden":"true"},"#"),t(" 预览")],-1),b=a("p",null,"发布之前可以在本地进行预览,有多种方式,这里介绍两种",-1),v=a("p",null,[a("strong",null,"不能直接打开构建后的 html 文件")],-1),_=a("ul",null,[a("li",null,"使用项目自定的命令进行预览(推荐)")],-1),x=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 先打包再进行预览"),t("\n"),a("span",{class:"token function"},"yarn"),t(" preview\n"),a("span",{class:"token comment"},"# 直接预览本地 dist 文件目录"),t("\n"),a("span",{class:"token function"},"yarn"),t(" preview:dist\n")])])],-1),f=a("ul",null,[a("li",null,"本地服务器预览(通过 live-server)")],-1),z=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 1.全局安装live-server"),t("\n"),a("span",{class:"token function"},"yarn"),t(" global "),a("span",{class:"token function"},"add"),t(" live-server\n"),a("span",{class:"token comment"},"# 2. 进入打包的后目录"),t("\n"),a("span",{class:"token builtin class-name"},"cd"),t(" ./dist\n"),a("span",{class:"token comment"},"# 本地预览,默认端口8080"),t("\nlive-server\n"),a("span",{class:"token comment"},"# 指定端口"),t("\nlive-server --port "),a("span",{class:"token number"},"9000"),t("\n")])])],-1),y=a("h3",{id:"分析构建文件体积"},[a("a",{class:"header-anchor",href:"#分析构建文件体积","aria-hidden":"true"},"#"),t(" 分析构建文件体积")],-1),I=a("p",null,[t("如果你的构建文件很大,可以通过项目内置 "),a("a",{href:"https://github.com/doesdev/rollup-plugin-analyzer",target:"_blank",rel:"noopener noreferrer"},"rollup-plugin-analyzer"),t(" 插件进行代码体积分析,从而优化你的代码。")],-1),T=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" report\n\n")])])],-1),P=a("p",null,"运行之后,在自动打开的页面可以看到具体的体积分布,以分析哪些依赖有问题。",-1),E=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,"左上角可以切换 显示 gzip 或者 brotli")],-1),w=a("p",null,[a("img",{src:"/images/report.png",alt:""})],-1),C=a("h2",{id:"压缩"},[a("a",{class:"header-anchor",href:"#压缩","aria-hidden":"true"},"#"),t(" 压缩")],-1),j=a("h3",{id:"开启-gzip-压缩"},[a("a",{class:"header-anchor",href:"#开启-gzip-压缩","aria-hidden":"true"},"#"),t(" 开启 gzip 压缩")],-1),A=a("p",null,[t("开启 gzip,并配合 nginx 的 "),a("code",null,"gzip_static"),t(" 功能可以大大加快页面访问速度")],-1),H=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='gzip'"),t(" 即可在打包的同时生成 .gz 文件")])],-1),L=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 例如部署在nginx /next/路径下 则VITE_PUBLIC_PATH=/next/"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n")])])],-1),V=a("h3",{id:"开启-brotli-压缩"},[a("a",{class:"header-anchor",href:"#开启-brotli-压缩","aria-hidden":"true"},"#"),t(" 开启 brotli 压缩")],-1),U=a("p",null,"brotli 是比 gzip 压缩率更高的算法,可以与 gzip 共存不会冲突,需要 nginx 安装指定模块并开启即可。",-1),B=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='brotli'"),t(" 即可在打包的同时生成 .br 文件")])],-1),S=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 例如部署在nginx /next/路径下 则VITE_PUBLIC_PATH=/next/"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n")])])],-1),$=a("h3",{id:"同时开启-gzip-与-brotli"},[a("a",{class:"header-anchor",href:"#同时开启-gzip-与-brotli","aria-hidden":"true"},"#"),t(" 同时开启 gzip 与 brotli")],-1),M=a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='brotli,gzip'"),t(" 即可在打包的同时生成 "),a("code",null,".gz"),t(" 和 "),a("code",null,".br"),t(" 文件。")],-1),O=a("h3",{id:"gzip-与-brotli-在-nginx-内的配置"},[a("a",{class:"header-anchor",href:"#gzip-与-brotli-在-nginx-内的配置","aria-hidden":"true"},"#"),t(" gzip 与 brotli 在 nginx 内的配置")],-1),R=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("http "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 开启gzip"),t("\n "),a("span",{class:"token function"},"gzip"),t(" on"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 开启gzip_static"),t("\n "),a("span",{class:"token comment"},"# gzip_static 开启后可能会报错,需要安装相应的模块, 具体安装方式可以自行查询"),t("\n "),a("span",{class:"token comment"},"# 只有这个开启,vue文件打包的.gz文件才会有效果,否则不需要开启gzip进行打包"),t("\n gzip_static on"),a("span",{class:"token punctuation"},";"),t("\n gzip_proxied any"),a("span",{class:"token punctuation"},";"),t("\n gzip_min_length 1k"),a("span",{class:"token punctuation"},";"),t("\n gzip_buffers "),a("span",{class:"token number"},"4"),t(" 16k"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"#如果nginx中使用了多层代理 必须设置这个才可以开启gzip。"),t("\n gzip_http_version "),a("span",{class:"token number"},"1.0"),a("span",{class:"token punctuation"},";"),t("\n gzip_comp_level "),a("span",{class:"token number"},"2"),a("span",{class:"token punctuation"},";"),t("\n gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png"),a("span",{class:"token punctuation"},";"),t("\n gzip_vary off"),a("span",{class:"token punctuation"},";"),t("\n gzip_disable "),a("span",{class:"token string"},'"MSIE [1-6]\\."'),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token comment"},"# 开启 brotli压缩"),t("\n "),a("span",{class:"token comment"},"# 需要安装对应的nginx模块,具体安装方式可以自行查询"),t("\n "),a("span",{class:"token comment"},"# 可以与gzip共存不会冲突"),t("\n brotli on"),a("span",{class:"token punctuation"},";"),t("\n brotli_comp_level "),a("span",{class:"token number"},"6"),a("span",{class:"token punctuation"},";"),t("\n brotli_buffers "),a("span",{class:"token number"},"16"),t(" 8k"),a("span",{class:"token punctuation"},";"),t("\n brotli_min_length "),a("span",{class:"token number"},"20"),a("span",{class:"token punctuation"},";"),t("\n brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),W=a("h2",{id:"部署"},[a("a",{class:"header-anchor",href:"#部署","aria-hidden":"true"},"#"),t(" 部署")],-1),G=a("div",{class:"danger custom-block"},[a("p",{class:"custom-block-title"},"注意"),a("p",null,"项目默认是在生产环境开启 Mock,这样做非常不好,只是为了演示环境有数据,不建议在生产环境使用 Mock,而应该使用真实的后台接口,并将 Mock 关闭。")],-1),D=a("h3",{id:"发布"},[a("a",{class:"header-anchor",href:"#发布","aria-hidden":"true"},"#"),t(" 发布")],-1),X=a("p",null,"简单的部署只需要将最终生成的静态文件,dist 文件夹的静态文件发布到你的 cdn 或者静态服务器即可,需要注意的是其中的 index.html 通常会是你后台服务的入口页面,在确定了 js 和 css 的静态之后可能需要改变页面的引入路径。",-1),q=a("p",null,"例如上传到 nginx",-1),F=a("p",null,[a("code",null,"/srv/www/project/index.html")],-1),Y=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# nginx配置"),t("\nlocation / "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 不缓存html,防止程序更新后缓存继续生效"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token variable"},"$request_filename"),t(" ~* .*"),a("span",{class:"token punctuation"},"\\"),t("."),a("span",{class:"token punctuation"},"("),t("?:htm"),a("span",{class:"token operator"},"|"),t("html"),a("span",{class:"token punctuation"},")"),t("$"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n add_header Cache-Control "),a("span",{class:"token string"},'"private, no-store, no-cache, must-revalidate, proxy-revalidate"'),a("span",{class:"token punctuation"},";"),t("\n access_log on"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token comment"},"# 这里是vue打包文件dist内的文件的存放路径"),t("\n root /srv/www/project/"),a("span",{class:"token punctuation"},";"),t("\n index index.html index.htm"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n\n")])])],-1),N=a("p",null,[a("strong",null,[t("部署时可能会发现资源路径不对,只需要修改"),a("code",null,".env.production"),t("文件即可。")])],-1),J=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 注意需要以 / 开头和结尾"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/xxx/\n")])])],-1),K=a("h3",{id:"前端路由与服务端的结合"},[a("a",{class:"header-anchor",href:"#前端路由与服务端的结合","aria-hidden":"true"},"#"),t(" 前端路由与服务端的结合")],-1),Q=a("p",null,"项目前端路由使用的是 vue-router,所以你可以选择两种方式:history 和 hash。",-1),Z=a("ul",null,[a("li",null,[a("strong",null,"hash"),t(" 默认会在 url 后面拼接"),a("code",null,"#")]),a("li",null,[a("strong",null,"history"),t(" 则不会,不过 "),a("code",null,"history"),t(" 需要服务器配合")])],-1),nn=a("p",null,[t("可在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/router/index.ts",target:"_blank",rel:"noopener noreferrer"},"src/router/index.ts"),t(" 内进行 mode 修改")],-1),sn=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" createRouter"),a("span",{class:"token punctuation"},","),t(" createWebHashHistory"),a("span",{class:"token punctuation"},","),t(" createWebHistory "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue-router'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token function"},"createRouter"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n history"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token function"},"createWebHashHistory"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// or"),t("\n history"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token function"},"createWebHistory"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),an=a("h3",{id:"history-路由模式下服务端配置"},[a("a",{class:"header-anchor",href:"#history-路由模式下服务端配置","aria-hidden":"true"},"#"),t(" history 路由模式下服务端配置")],-1),tn=a("p",null,[t("开启 history 模式需要服务器配置,更多的服务器配置详情可以看 "),a("a",{href:"https://next.router.vuejs.org/guide/essentials/history-mode.html#html5-mode",target:"_blank",rel:"noopener noreferrer"},"history-mode")],-1),en=a("p",null,"这里以 nginx 配置为例",-1),ln=a("p",null,[a("strong",null,"部署到根目录")],-1),on=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"80"),a("span",{class:"token punctuation"},";"),t("\n location / "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 用于配合 History 使用"),t("\n try_files "),a("span",{class:"token variable"},"$uri"),t(),a("span",{class:"token variable"},"$uri"),t("/ /index.html"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),cn=a("p",null,[a("strong",null,"部署到非根目录")],-1),pn=a("ol",null,[a("li",null,"首先需要在打包的时候更改配置")],-1),un=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 在.env.production内,配置子目录路径"),t("\nVITE_PUBLIC_PATH "),a("span",{class:"token operator"},"="),t(" /sub/\n")])])],-1),rn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"80"),a("span",{class:"token punctuation"},";"),t("\n server_name localhost"),a("span",{class:"token punctuation"},";"),t("\n location /sub/ "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 这里是vue打包文件dist内的文件的存放路径"),t("\n "),a("span",{class:"token builtin class-name"},"alias"),t(" /srv/www/project/"),a("span",{class:"token punctuation"},";"),t("\n index index.html index.htm"),a("span",{class:"token punctuation"},";"),t("\n try_files "),a("span",{class:"token variable"},"$uri"),t(),a("span",{class:"token variable"},"$uri"),t("/ /sub/index.html"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),dn=a("h3",{id:"使用-nginx-处理跨域"},[a("a",{class:"header-anchor",href:"#使用-nginx-处理跨域","aria-hidden":"true"},"#"),t(" 使用 nginx 处理跨域")],-1),kn=a("p",null,"使用 nginx 处理项目部署后的跨域问题",-1),hn=a("ol",null,[a("li",null,"配置前端项目接口地址")],-1),gn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 在.env.production内,配置接口地址"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_GLOB_API_URL"),a("span",{class:"token operator"},"="),t("/api\n")])])],-1),mn=a("ol",{start:"2"},[a("li",null,"在 nginx 配置请求转发到后台")],-1),bn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"8080"),a("span",{class:"token punctuation"},";"),t("\n server_name localhost"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 接口代理,用于解决跨域问题"),t("\n location /api "),a("span",{class:"token punctuation"},"{"),t("\n proxy_set_header Host "),a("span",{class:"token variable"},"$host"),a("span",{class:"token punctuation"},";"),t("\n proxy_set_header X-Real-IP "),a("span",{class:"token variable"},"$remote_addr"),a("span",{class:"token punctuation"},";"),t("\n proxy_set_header X-Forwarded-For "),a("span",{class:"token variable"},"$proxy_add_x_forwarded_for"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 后台接口地址"),t("\n proxy_pass http://110.110.1.1:8080/api"),a("span",{class:"token punctuation"},";"),t("\n proxy_redirect default"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Origin *"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Headers X-Requested-With"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Methods GET,POST,OPTIONS"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1);l.render=function(a,t,e,l,vn,_n){return n(),s("div",null,[o,c,i,p,u,r,d,k,h,g,m,b,v,_,x,f,z,y,I,T,P,E,w,C,j,A,H,L,V,U,B,S,$,M,O,R,W,G,D,X,q,F,Y,N,J,K,Q,Z,nn,sn,an,tn,en,ln,on,cn,pn,un,rn,dn,kn,hn,gn,mn,bn])};export default l;export{e as __pageData}; diff --git a/assets/guide_deploy.md.d904a197.lean.js b/assets/guide_deploy.md.d904a197.lean.js new file mode 100644 index 00000000..d0a43511 --- /dev/null +++ b/assets/guide_deploy.md.d904a197.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,b as a,d as t}from"./app.8cddb23b.js";const e='{"title":"构建&部署","description":"","frontmatter":{},"headers":[{"level":2,"title":"构建","slug":"构建"},{"level":3,"title":"旧版浏览器兼容","slug":"旧版浏览器兼容"},{"level":3,"title":"预览","slug":"预览"},{"level":3,"title":"分析构建文件体积","slug":"分析构建文件体积"},{"level":2,"title":"压缩","slug":"压缩"},{"level":3,"title":"开启 gzip 压缩","slug":"开启-gzip-压缩"},{"level":3,"title":"开启 brotli 压缩","slug":"开启-brotli-压缩"},{"level":3,"title":"同时开启 gzip 与 brotli","slug":"同时开启-gzip-与-brotli"},{"level":3,"title":"gzip 与 brotli 在 nginx 内的配置","slug":"gzip-与-brotli-在-nginx-内的配置"},{"level":2,"title":"部署","slug":"部署"},{"level":3,"title":"发布","slug":"发布"},{"level":3,"title":"前端路由与服务端的结合","slug":"前端路由与服务端的结合"},{"level":3,"title":"history 路由模式下服务端配置","slug":"history-路由模式下服务端配置"},{"level":3,"title":"使用 nginx 处理跨域","slug":"使用-nginx-处理跨域"}],"relativePath":"guide/deploy.md","lastUpdated":1697592578593}',l={},o=a("h1",{id:"构建-部署"},[a("a",{class:"header-anchor",href:"#构建-部署","aria-hidden":"true"},"#"),t(" 构建&部署")],-1),c=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"前言"),a("p",null,"由于是展示项目,所以打包后相对较大,如果项目中没有用到的插件,可以删除对应的文件或者路由,不引用即可,没有引用就不会打包。"),a("p",null,[t("当然,你也可以使用精简版 "),a("a",{href:"https://github.com/vbenjs/vben-admin-thin-next",target:"_blank",rel:"noopener noreferrer"},"vue-vben-admin-thin"),t(" 进行开发。")])],-1),i=a("h2",{id:"构建"},[a("a",{class:"header-anchor",href:"#构建","aria-hidden":"true"},"#"),t(" 构建")],-1),p=a("p",null,"项目开发完成之后,执行以下命令进行构建",-1),u=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" build\n")])])],-1),r=a("p",null,"构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件",-1),d=a("h3",{id:"旧版浏览器兼容"},[a("a",{class:"header-anchor",href:"#旧版浏览器兼容","aria-hidden":"true"},"#"),t(" 旧版浏览器兼容")],-1),k=a("p",null,[t("在 "),a("strong",null,".env.production"),t(" 内")],-1),h=a("p",null,[t("设置 "),a("code",null,"VITE_LEGACY=true"),t(" 即可打包出兼容旧版浏览器的代码")],-1),g=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("VITE_LEGACY "),a("span",{class:"token operator"},"="),t(),a("span",{class:"token boolean"},"true"),t("\n")])])],-1),m=a("h3",{id:"预览"},[a("a",{class:"header-anchor",href:"#预览","aria-hidden":"true"},"#"),t(" 预览")],-1),b=a("p",null,"发布之前可以在本地进行预览,有多种方式,这里介绍两种",-1),v=a("p",null,[a("strong",null,"不能直接打开构建后的 html 文件")],-1),_=a("ul",null,[a("li",null,"使用项目自定的命令进行预览(推荐)")],-1),x=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 先打包再进行预览"),t("\n"),a("span",{class:"token function"},"yarn"),t(" preview\n"),a("span",{class:"token comment"},"# 直接预览本地 dist 文件目录"),t("\n"),a("span",{class:"token function"},"yarn"),t(" preview:dist\n")])])],-1),f=a("ul",null,[a("li",null,"本地服务器预览(通过 live-server)")],-1),z=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 1.全局安装live-server"),t("\n"),a("span",{class:"token function"},"yarn"),t(" global "),a("span",{class:"token function"},"add"),t(" live-server\n"),a("span",{class:"token comment"},"# 2. 进入打包的后目录"),t("\n"),a("span",{class:"token builtin class-name"},"cd"),t(" ./dist\n"),a("span",{class:"token comment"},"# 本地预览,默认端口8080"),t("\nlive-server\n"),a("span",{class:"token comment"},"# 指定端口"),t("\nlive-server --port "),a("span",{class:"token number"},"9000"),t("\n")])])],-1),y=a("h3",{id:"分析构建文件体积"},[a("a",{class:"header-anchor",href:"#分析构建文件体积","aria-hidden":"true"},"#"),t(" 分析构建文件体积")],-1),I=a("p",null,[t("如果你的构建文件很大,可以通过项目内置 "),a("a",{href:"https://github.com/doesdev/rollup-plugin-analyzer",target:"_blank",rel:"noopener noreferrer"},"rollup-plugin-analyzer"),t(" 插件进行代码体积分析,从而优化你的代码。")],-1),T=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token function"},"yarn"),t(" report\n\n")])])],-1),P=a("p",null,"运行之后,在自动打开的页面可以看到具体的体积分布,以分析哪些依赖有问题。",-1),E=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,"左上角可以切换 显示 gzip 或者 brotli")],-1),w=a("p",null,[a("img",{src:"/images/report.png",alt:""})],-1),C=a("h2",{id:"压缩"},[a("a",{class:"header-anchor",href:"#压缩","aria-hidden":"true"},"#"),t(" 压缩")],-1),j=a("h3",{id:"开启-gzip-压缩"},[a("a",{class:"header-anchor",href:"#开启-gzip-压缩","aria-hidden":"true"},"#"),t(" 开启 gzip 压缩")],-1),A=a("p",null,[t("开启 gzip,并配合 nginx 的 "),a("code",null,"gzip_static"),t(" 功能可以大大加快页面访问速度")],-1),H=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='gzip'"),t(" 即可在打包的同时生成 .gz 文件")])],-1),L=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 例如部署在nginx /next/路径下 则VITE_PUBLIC_PATH=/next/"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n")])])],-1),V=a("h3",{id:"开启-brotli-压缩"},[a("a",{class:"header-anchor",href:"#开启-brotli-压缩","aria-hidden":"true"},"#"),t(" 开启 brotli 压缩")],-1),U=a("p",null,"brotli 是比 gzip 压缩率更高的算法,可以与 gzip 共存不会冲突,需要 nginx 安装指定模块并开启即可。",-1),B=a("div",{class:"tip custom-block"},[a("p",{class:"custom-block-title"},"TIP"),a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='brotli'"),t(" 即可在打包的同时生成 .br 文件")])],-1),S=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 例如部署在nginx /next/路径下 则VITE_PUBLIC_PATH=/next/"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n")])])],-1),$=a("h3",{id:"同时开启-gzip-与-brotli"},[a("a",{class:"header-anchor",href:"#同时开启-gzip-与-brotli","aria-hidden":"true"},"#"),t(" 同时开启 gzip 与 brotli")],-1),M=a("p",null,[t("只需开启 "),a("code",null,"VITE_BUILD_COMPRESS='brotli,gzip'"),t(" 即可在打包的同时生成 "),a("code",null,".gz"),t(" 和 "),a("code",null,".br"),t(" 文件。")],-1),O=a("h3",{id:"gzip-与-brotli-在-nginx-内的配置"},[a("a",{class:"header-anchor",href:"#gzip-与-brotli-在-nginx-内的配置","aria-hidden":"true"},"#"),t(" gzip 与 brotli 在 nginx 内的配置")],-1),R=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("http "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 开启gzip"),t("\n "),a("span",{class:"token function"},"gzip"),t(" on"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 开启gzip_static"),t("\n "),a("span",{class:"token comment"},"# gzip_static 开启后可能会报错,需要安装相应的模块, 具体安装方式可以自行查询"),t("\n "),a("span",{class:"token comment"},"# 只有这个开启,vue文件打包的.gz文件才会有效果,否则不需要开启gzip进行打包"),t("\n gzip_static on"),a("span",{class:"token punctuation"},";"),t("\n gzip_proxied any"),a("span",{class:"token punctuation"},";"),t("\n gzip_min_length 1k"),a("span",{class:"token punctuation"},";"),t("\n gzip_buffers "),a("span",{class:"token number"},"4"),t(" 16k"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"#如果nginx中使用了多层代理 必须设置这个才可以开启gzip。"),t("\n gzip_http_version "),a("span",{class:"token number"},"1.0"),a("span",{class:"token punctuation"},";"),t("\n gzip_comp_level "),a("span",{class:"token number"},"2"),a("span",{class:"token punctuation"},";"),t("\n gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png"),a("span",{class:"token punctuation"},";"),t("\n gzip_vary off"),a("span",{class:"token punctuation"},";"),t("\n gzip_disable "),a("span",{class:"token string"},'"MSIE [1-6]\\."'),a("span",{class:"token punctuation"},";"),t("\n\n "),a("span",{class:"token comment"},"# 开启 brotli压缩"),t("\n "),a("span",{class:"token comment"},"# 需要安装对应的nginx模块,具体安装方式可以自行查询"),t("\n "),a("span",{class:"token comment"},"# 可以与gzip共存不会冲突"),t("\n brotli on"),a("span",{class:"token punctuation"},";"),t("\n brotli_comp_level "),a("span",{class:"token number"},"6"),a("span",{class:"token punctuation"},";"),t("\n brotli_buffers "),a("span",{class:"token number"},"16"),t(" 8k"),a("span",{class:"token punctuation"},";"),t("\n brotli_min_length "),a("span",{class:"token number"},"20"),a("span",{class:"token punctuation"},";"),t("\n brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),W=a("h2",{id:"部署"},[a("a",{class:"header-anchor",href:"#部署","aria-hidden":"true"},"#"),t(" 部署")],-1),G=a("div",{class:"danger custom-block"},[a("p",{class:"custom-block-title"},"注意"),a("p",null,"项目默认是在生产环境开启 Mock,这样做非常不好,只是为了演示环境有数据,不建议在生产环境使用 Mock,而应该使用真实的后台接口,并将 Mock 关闭。")],-1),D=a("h3",{id:"发布"},[a("a",{class:"header-anchor",href:"#发布","aria-hidden":"true"},"#"),t(" 发布")],-1),X=a("p",null,"简单的部署只需要将最终生成的静态文件,dist 文件夹的静态文件发布到你的 cdn 或者静态服务器即可,需要注意的是其中的 index.html 通常会是你后台服务的入口页面,在确定了 js 和 css 的静态之后可能需要改变页面的引入路径。",-1),q=a("p",null,"例如上传到 nginx",-1),F=a("p",null,[a("code",null,"/srv/www/project/index.html")],-1),Y=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# nginx配置"),t("\nlocation / "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 不缓存html,防止程序更新后缓存继续生效"),t("\n "),a("span",{class:"token keyword"},"if"),t(),a("span",{class:"token punctuation"},"("),a("span",{class:"token variable"},"$request_filename"),t(" ~* .*"),a("span",{class:"token punctuation"},"\\"),t("."),a("span",{class:"token punctuation"},"("),t("?:htm"),a("span",{class:"token operator"},"|"),t("html"),a("span",{class:"token punctuation"},")"),t("$"),a("span",{class:"token punctuation"},")"),t(),a("span",{class:"token punctuation"},"{"),t("\n add_header Cache-Control "),a("span",{class:"token string"},'"private, no-store, no-cache, must-revalidate, proxy-revalidate"'),a("span",{class:"token punctuation"},";"),t("\n access_log on"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n "),a("span",{class:"token comment"},"# 这里是vue打包文件dist内的文件的存放路径"),t("\n root /srv/www/project/"),a("span",{class:"token punctuation"},";"),t("\n index index.html index.htm"),a("span",{class:"token punctuation"},";"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n\n")])])],-1),N=a("p",null,[a("strong",null,[t("部署时可能会发现资源路径不对,只需要修改"),a("code",null,".env.production"),t("文件即可。")])],-1),J=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 根据自己路径来配置更改"),t("\n"),a("span",{class:"token comment"},"# 注意需要以 / 开头和结尾"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/\n"),a("span",{class:"token assign-left variable"},"VITE_PUBLIC_PATH"),a("span",{class:"token operator"},"="),t("/xxx/\n")])])],-1),K=a("h3",{id:"前端路由与服务端的结合"},[a("a",{class:"header-anchor",href:"#前端路由与服务端的结合","aria-hidden":"true"},"#"),t(" 前端路由与服务端的结合")],-1),Q=a("p",null,"项目前端路由使用的是 vue-router,所以你可以选择两种方式:history 和 hash。",-1),Z=a("ul",null,[a("li",null,[a("strong",null,"hash"),t(" 默认会在 url 后面拼接"),a("code",null,"#")]),a("li",null,[a("strong",null,"history"),t(" 则不会,不过 "),a("code",null,"history"),t(" 需要服务器配合")])],-1),nn=a("p",null,[t("可在 "),a("a",{href:"https://github.com/vbenjs/vue-vben-admin/tree/main/src/router/index.ts",target:"_blank",rel:"noopener noreferrer"},"src/router/index.ts"),t(" 内进行 mode 修改")],-1),sn=a("div",{class:"language-ts"},[a("pre",null,[a("code",null,[a("span",{class:"token keyword"},"import"),t(),a("span",{class:"token punctuation"},"{"),t(" createRouter"),a("span",{class:"token punctuation"},","),t(" createWebHashHistory"),a("span",{class:"token punctuation"},","),t(" createWebHistory "),a("span",{class:"token punctuation"},"}"),t(),a("span",{class:"token keyword"},"from"),t(),a("span",{class:"token string"},"'vue-router'"),a("span",{class:"token punctuation"},";"),t("\n\n"),a("span",{class:"token function"},"createRouter"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},"{"),t("\n history"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token function"},"createWebHashHistory"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n "),a("span",{class:"token comment"},"// or"),t("\n history"),a("span",{class:"token operator"},":"),t(),a("span",{class:"token function"},"createWebHistory"),a("span",{class:"token punctuation"},"("),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},","),t("\n"),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},")"),a("span",{class:"token punctuation"},";"),t("\n")])])],-1),an=a("h3",{id:"history-路由模式下服务端配置"},[a("a",{class:"header-anchor",href:"#history-路由模式下服务端配置","aria-hidden":"true"},"#"),t(" history 路由模式下服务端配置")],-1),tn=a("p",null,[t("开启 history 模式需要服务器配置,更多的服务器配置详情可以看 "),a("a",{href:"https://next.router.vuejs.org/guide/essentials/history-mode.html#html5-mode",target:"_blank",rel:"noopener noreferrer"},"history-mode")],-1),en=a("p",null,"这里以 nginx 配置为例",-1),ln=a("p",null,[a("strong",null,"部署到根目录")],-1),on=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"80"),a("span",{class:"token punctuation"},";"),t("\n location / "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 用于配合 History 使用"),t("\n try_files "),a("span",{class:"token variable"},"$uri"),t(),a("span",{class:"token variable"},"$uri"),t("/ /index.html"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),cn=a("p",null,[a("strong",null,"部署到非根目录")],-1),pn=a("ol",null,[a("li",null,"首先需要在打包的时候更改配置")],-1),un=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 在.env.production内,配置子目录路径"),t("\nVITE_PUBLIC_PATH "),a("span",{class:"token operator"},"="),t(" /sub/\n")])])],-1),rn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"80"),a("span",{class:"token punctuation"},";"),t("\n server_name localhost"),a("span",{class:"token punctuation"},";"),t("\n location /sub/ "),a("span",{class:"token punctuation"},"{"),t("\n "),a("span",{class:"token comment"},"# 这里是vue打包文件dist内的文件的存放路径"),t("\n "),a("span",{class:"token builtin class-name"},"alias"),t(" /srv/www/project/"),a("span",{class:"token punctuation"},";"),t("\n index index.html index.htm"),a("span",{class:"token punctuation"},";"),t("\n try_files "),a("span",{class:"token variable"},"$uri"),t(),a("span",{class:"token variable"},"$uri"),t("/ /sub/index.html"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1),dn=a("h3",{id:"使用-nginx-处理跨域"},[a("a",{class:"header-anchor",href:"#使用-nginx-处理跨域","aria-hidden":"true"},"#"),t(" 使用 nginx 处理跨域")],-1),kn=a("p",null,"使用 nginx 处理项目部署后的跨域问题",-1),hn=a("ol",null,[a("li",null,"配置前端项目接口地址")],-1),gn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[a("span",{class:"token comment"},"# 在.env.production内,配置接口地址"),t("\n"),a("span",{class:"token assign-left variable"},"VITE_GLOB_API_URL"),a("span",{class:"token operator"},"="),t("/api\n")])])],-1),mn=a("ol",{start:"2"},[a("li",null,"在 nginx 配置请求转发到后台")],-1),bn=a("div",{class:"language-bash"},[a("pre",null,[a("code",null,[t("server "),a("span",{class:"token punctuation"},"{"),t("\n listen "),a("span",{class:"token number"},"8080"),a("span",{class:"token punctuation"},";"),t("\n server_name localhost"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 接口代理,用于解决跨域问题"),t("\n location /api "),a("span",{class:"token punctuation"},"{"),t("\n proxy_set_header Host "),a("span",{class:"token variable"},"$host"),a("span",{class:"token punctuation"},";"),t("\n proxy_set_header X-Real-IP "),a("span",{class:"token variable"},"$remote_addr"),a("span",{class:"token punctuation"},";"),t("\n proxy_set_header X-Forwarded-For "),a("span",{class:"token variable"},"$proxy_add_x_forwarded_for"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token comment"},"# 后台接口地址"),t("\n proxy_pass http://110.110.1.1:8080/api"),a("span",{class:"token punctuation"},";"),t("\n proxy_redirect default"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Origin *"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Headers X-Requested-With"),a("span",{class:"token punctuation"},";"),t("\n add_header Access-Control-Allow-Methods GET,POST,OPTIONS"),a("span",{class:"token punctuation"},";"),t("\n "),a("span",{class:"token punctuation"},"}"),t("\n"),a("span",{class:"token punctuation"},"}"),t("\n")])])],-1);l.render=function(a,t,e,l,vn,_n){return n(),s("div",null,[o,c,i,p,u,r,d,k,h,g,m,b,v,_,x,f,z,y,I,T,P,E,w,C,j,A,H,L,V,U,B,S,$,M,O,R,W,G,D,X,q,F,Y,N,J,K,Q,Z,nn,sn,an,tn,en,ln,on,cn,pn,un,rn,dn,kn,hn,gn,mn,bn])};export default l;export{e as __pageData}; diff --git a/assets/guide_design.md.eae80806.js b/assets/guide_design.md.eae80806.js new file mode 100644 index 00000000..f4f166b6 --- /dev/null +++ b/assets/guide_design.md.eae80806.js @@ -0,0 +1 @@ +import{o as s,c as n,a}from"./app.8cddb23b.js";const t='{"title":"样式","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"tailwindcss(2.5.0+)","slug":"tailwindcss-2-5-0"},{"level":2,"title":"windicss(2.5.0 已弃用)","slug":"windicss-2-5-0-已弃用"},{"level":2,"title":"为什么使用 Less","slug":"为什么使用-less"},{"level":2,"title":"开启 scoped","slug":"开启-scoped"},{"level":2,"title":"深度选择器","slug":"深度选择器"},{"level":2,"title":"CSS Modules","slug":"css-modules"},{"level":2,"title":"重复引用问题","slug":"重复引用问题"}],"relativePath":"guide/design.md","lastUpdated":1697592578593}',p={},e=a('

样式

介绍

主要介绍如何在项目中使用和规划样式文件。

默认使用 less 作为预处理语言,建议在使用前或者遇到疑问时学习一下 Less 的相关特性(如果想获取基础的 CSS 知识或查阅属性,请参考 MDN 文档)。

项目中使用的通用样式,都存放于 src/design/ 下面。

.\n├── ant # ant design 一些样式覆盖\n├── color.less # 颜色\n├── index.less # 入口\n├── public.less # 公共类\n├── theme.less # 主题相关\n├── config.less  # 每个组件都会自动引入样式\n├── transition # 动画相关\n└── var # 变量\n\n

全局注入

config.less 这个文件会被全局注入到所有文件,所以在页面内可以直接使用变量而不需要手动引入

<style lang="less" scoped>\n  // 这里已经隐式注入了 config.less\n</style>\n

tailwindcss(2.5.0+)

项目中引用到了 tailwindcss,具体可以见文件使用说明。

语法如下:

<div class="relative w-full h-full px-4"></div>\n

windicss(2.5.0 已弃用)

项目中使用了 windicss,具体参见文件使用说明。

语法如下:

<div class="relative w-full h-full px-4"></div>\n

注意事项

windcss 目前会造成本地开发内存溢出,所以后续可能会考虑切换到 TailwindCss,两者基本相同。

所以尽量少用 Windicss 新增的特性,防止后续切换成本高。

为什么使用 Less

主要是因为 Ant Design 默认使用 less 作为样式语言,使用 Less 可以跟其保持一致。

开启 scoped

没有加 scoped 属性,默认会编译成全局样式,可能会造成全局污染

<style></style>\n\n<style scoped></style>\n

温馨提醒

使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。

深度选择器

有时我们可能想明确地制定一个针对子组件的规则。

如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符。有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

详情可以查看 RFC0023-scoped-styles-changes

使用 scoped 后,父组件的样式将不会渗透到子组件中,所以可以使用以下方式解决:

<style scoped>\n  /* deep selectors */\n  ::v-deep(.foo) {\n  }\n  /* shorthand */\n  :deep(.foo) {\n  }\n\n  /* targeting slot content */\n  ::v-slotted(.foo) {\n  }\n  /* shorthand */\n  :slotted(.foo) {\n  }\n\n  /* one-off global rule */\n  ::v-global(.foo) {\n  }\n  /* shorthand */\n  :global(.foo) {\n  }\n</style>\n

CSS Modules

针对样式覆盖问题,还有一种方案是使用 CSS Modules 模块化方案。使用方式如下。

<template>\n  <span :class="$style.span1">hello</span>\n</template>\n\n<script>\n  import { useCSSModule } from 'vue';\n\n  export default {\n    setup(props, context) {\n      const $style = useCSSModule();\n      const moduleAStyle = useCSSModule('moduleA');\n      return {\n        $style,\n        moduleAStyle,\n      };\n    },\n  };\n</script>\n\n<style lang="less" module>\n  .span1 {\n    color: green;\n    font-size: 30px;\n  }\n</style>\n\n<style lang="less" module="moduleA">\n  .span1 {\n    color: green;\n    font-size: 30px;\n  }\n</style>\n

重复引用问题

加上 reference 可以解决页面内重复引用导致实际生成的 style 样式表重复的问题。

这步已经全局引入了。所以可以不写,直接使用变量

<style lang="less" scoped>\n  /* 该行代码已全局引用。可以不用单独引入 */\n  @import (reference) '../../design/config.less';\n<style>\n
',36);p.render=function(a,t,p,o,c,l){return s(),n("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/guide_design.md.eae80806.lean.js b/assets/guide_design.md.eae80806.lean.js new file mode 100644 index 00000000..56d52a2f --- /dev/null +++ b/assets/guide_design.md.eae80806.lean.js @@ -0,0 +1 @@ +import{o as s,c as n,a}from"./app.8cddb23b.js";const t='{"title":"样式","description":"","frontmatter":{},"headers":[{"level":2,"title":"介绍","slug":"介绍"},{"level":2,"title":"tailwindcss(2.5.0+)","slug":"tailwindcss-2-5-0"},{"level":2,"title":"windicss(2.5.0 已弃用)","slug":"windicss-2-5-0-已弃用"},{"level":2,"title":"为什么使用 Less","slug":"为什么使用-less"},{"level":2,"title":"开启 scoped","slug":"开启-scoped"},{"level":2,"title":"深度选择器","slug":"深度选择器"},{"level":2,"title":"CSS Modules","slug":"css-modules"},{"level":2,"title":"重复引用问题","slug":"重复引用问题"}],"relativePath":"guide/design.md","lastUpdated":1697592578593}',p={},e=a('',36);p.render=function(a,t,p,o,c,l){return s(),n("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/guide_electron.md.1fc6b47b.js b/assets/guide_electron.md.1fc6b47b.js new file mode 100644 index 00000000..98e04bfe --- /dev/null +++ b/assets/guide_electron.md.1fc6b47b.js @@ -0,0 +1 @@ +import{o as e,c as a,a as n}from"./app.8cddb23b.js";const r='{"title":"Electron","description":"","frontmatter":{},"headers":[{"level":2,"title":"URL 模式","slug":"url-模式"},{"level":3,"title":"使用","slug":"使用"},{"level":3,"title":"从 GitHub 获取代码","slug":"从-github-获取代码"},{"level":3,"title":"安装依赖","slug":"安装依赖"},{"level":3,"title":"运行","slug":"运行"},{"level":3,"title":"打包","slug":"打包"},{"level":2,"title":"标准模式","slug":"标准模式"}],"relativePath":"guide/electron.md","lastUpdated":1697592578593}',s={},t=n('

Electron

URL 模式

这种模式会先启动 vite 服务,Electron 使用 Url 地址来进行渲染

使用

从 GitHub 获取代码

Electron 代码在 electron-main 分支

# clone electron-main分支代码\ngit clone -b electron-main https://github.com/vbenjs/vue-vben-admin vben-admin-electron\n

安装依赖

yarn\n

提示

首次下载 Electron 依赖会比较慢,可以在项目根目录下新建.npmrc文件,填入下方内容即可

ELETRON_MIRROR=https://npm.taobao.org/mirrors/electron/\n

运行

yarn dev:app\n

打包

yarn build:app\n

标准模式

TODO: 待适配

',16);s.render=function(n,r,s,l,i,c){return e(),a("div",null,[t])};export default s;export{r as __pageData}; diff --git a/assets/guide_electron.md.1fc6b47b.lean.js b/assets/guide_electron.md.1fc6b47b.lean.js new file mode 100644 index 00000000..6dd8d68a --- /dev/null +++ b/assets/guide_electron.md.1fc6b47b.lean.js @@ -0,0 +1 @@ +import{o as e,c as a,a as n}from"./app.8cddb23b.js";const r='{"title":"Electron","description":"","frontmatter":{},"headers":[{"level":2,"title":"URL 模式","slug":"url-模式"},{"level":3,"title":"使用","slug":"使用"},{"level":3,"title":"从 GitHub 获取代码","slug":"从-github-获取代码"},{"level":3,"title":"安装依赖","slug":"安装依赖"},{"level":3,"title":"运行","slug":"运行"},{"level":3,"title":"打包","slug":"打包"},{"level":2,"title":"标准模式","slug":"标准模式"}],"relativePath":"guide/electron.md","lastUpdated":1697592578593}',s={},t=n('',16);s.render=function(n,r,s,l,i,c){return e(),a("div",null,[t])};export default s;export{r as __pageData}; diff --git a/assets/guide_index.md.bb37fa1c.js b/assets/guide_index.md.bb37fa1c.js new file mode 100644 index 00000000..2db7159e --- /dev/null +++ b/assets/guide_index.md.bb37fa1c.js @@ -0,0 +1 @@ +import{o as n,c as s,a as e}from"./app.8cddb23b.js";const a='{"title":"开始","description":"","frontmatter":{},"headers":[{"level":2,"title":"前言","slug":"前言"},{"level":2,"title":"环境准备","slug":"环境准备"},{"level":2,"title":"工具配置","slug":"工具配置"},{"level":2,"title":"代码获取","slug":"代码获取"},{"level":3,"title":"从 GitHub 获取代码","slug":"从-github-获取代码"},{"level":3,"title":"从 Gitee 获取代码","slug":"从-gitee-获取代码"},{"level":2,"title":"安装","slug":"安装"},{"level":3,"title":"安装 Node.js","slug":"安装-node-js"},{"level":3,"title":"安装依赖","slug":"安装依赖"},{"level":2,"title":"npm script","slug":"npm-script"},{"level":3,"title":"生成图标集","slug":"生成图标集"},{"level":3,"title":"重新安装依赖","slug":"重新安装依赖"},{"level":2,"title":"目录说明","slug":"目录说明"}],"relativePath":"guide/index.md","lastUpdated":1697592578593}',t={},o=e('

开始

本文会帮助你从头启动项目

前言

关于组件

项目虽然二次封装了一些组件,但是可能不能满足大部分的要求。所以,如果组件不满足你的要求,完全可以不用甚至删除代码自己写,不必坚持使用项目自带的组件。

环境准备

本地环境需要安装 pnpmNode.jsGit

注意

  • 推荐使用pnpm,否则依赖可能安装不上。
  • Node.js 版本要求14.x以上,这里推荐 20.x 及以上。
  • 推荐安装 nvm 来管理 Node.js 版本。

工具配置

如果您使用的 IDE 是vscode(推荐)的话,可以安装以下工具来提高开发效率及代码格式化

代码获取

注意

注意存放代码的目录及所有父级目录不能存在中文、韩文、日文以及空格,否则安装依赖后启动会出错。

从 GitHub 获取代码

# clone 代码\ngit clone https://github.com/vbenjs/vue-vben-admin.git\n\n

从 Gitee 获取代码

如果从 github clone 代码较慢的话,可以尝试用 Gitee 同步代码到自己的仓库,再 clone 下来即可。

也可以通过下方地址进行 clone

git clone https://gitee.com/annsion/vue-vben-admin.git\n

注意

Gitee的代码可能不是最新的

安装

安装 Node.js

如果您电脑未安装Node.js,请安装它。

验证

# 出现相应npm版本即可\nnpm -v\n# 出现相应node版本即可\nnode -v\n\n

如果你需要同时存在多个 node 版本,可以使用 Nvm 或者其他工具进行 Node.js 进行版本管理。

安装依赖

pnpm 安装

必须使用 pnpm进行依赖安装(若其他包管理器安装不了需要自行处理)。

如果未安装pnpm,可以用下面命令来进行全局安装

# 全局安装pnpm\nnpm install -g pnpm\n# 验证\npnpm -v # 出现对应版本号即代表安装成功\n

依赖安装命令

在项目根目录下,打开命令窗口执行,耐心等待安装完成即可

# 安装依赖\npnpm i\n

安装依赖时 husky 安装失败

请查看你的源码是否从 github 直接下载的,直接下载是没有 .git 文件夹的,而 husky 需要依赖 git 才能安装。此时需使用 git init 初始化项目,再尝试重新安装即可。

npm script

"scripts": {\n  # 安装依赖\n  "bootstrap": "pnpm install",\n  # 构建项目\n  "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build",\n  # 生成打包分析,在电脑上执行完成后会自动打开界面\n  "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze",\n  # 构建成docker镜像\n  "build:docker": "vite build --mode docker",\n  # 清空缓存后构建项目\n  "build:no-cache": "pnpm clean:cache && npm run build",\n  "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode test",\n  # 用于生成标准化的git commit message\n  "commit": "czg",\n  # 运行项目\n  "dev": "pnpm vite",\n  "preinstall": "npx only-allow pnpm",\n  "postinstall": "turbo run stub",\n  "lint": "turbo run lint",\n  # 执行 eslint 校验,并修复部分问题\n  "lint:eslint": "eslint --cache --max-warnings 0  \\"{src,mock}/**/*.{vue,ts,tsx}\\" --fix",\n  # 执行 prettier 格式化(该命令会对项目所有代码进行 prettier 格式化,请谨慎执行)\n  "lint:prettier": "prettier --write .",\n  # 执行 stylelint 格式化\n  "lint:stylelint": "stylelint \\"**/*.{vue,css,less,scss}\\" --fix --cache --cache-location node_modules/.cache/stylelint/",\n  # 安装git hooks\n  "prepare": "husky install",\n  # 预览打包后的内容(先打包在进行预览)\n  "preview": "npm run build && vite preview",\n  # 重新安装依赖\n  "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",\n  # 运行项目\n  "serve": "npm run dev",\n  # 对打包结果进行 gzip 测试\n  "test:gzip": "npx http-server dist --cors --gzip -c-1",\n  # 类型检查\n  "type:check": "vue-tsc --noEmit --skipLibCheck"\n},\n

生成图标集

该命令会生成所选择的图标集,提供给图标选择器使用。具体使用方式请查看 图标集生成

重新安装依赖

该命令会先删除 node_modulesyarn.lockpackage.lock.json 后再进行依赖重新安装(安装速度会明显变慢)。

接下来你可以修改代码进行业务开发了。我们内建了模拟数据、HMR 实时预览、状态管理、国际化、全局路由等各种实用的功能辅助开发,请阅读其他章节了解更多。

目录说明

\n.\n├── build # 打包脚本相关\n│   ├── config # 配置文件\n│   ├── generate # 生成器\n│   ├── script # 脚本\n│   └── vite # vite配置\n├── mock # mock文件夹\n├── public # 公共静态资源目录\n├── src # 主目录\n│   ├── api # 接口文件\n│   ├── assets # 资源文件\n│   │   ├── icons # icon sprite 图标文件夹\n│   │   ├── images # 项目存放图片的文件夹\n│   │   └── svg # 项目存放svg图片的文件夹\n│   ├── components # 公共组件\n│   ├── design # 样式文件\n│   ├── directives # 指令\n│   ├── enums # 枚举/常量\n│   ├── hooks # hook\n│   │   ├── component # 组件相关hook\n│   │   ├── core # 基础hook\n│   │   ├── event # 事件相关hook\n│   │   ├── setting # 配置相关hook\n│   │   └── web # web相关hook\n│   ├── layouts # 布局文件\n│   │   ├── default # 默认布局\n│   │   ├── iframe # iframe布局\n│   │   └── page # 页面布局\n│   ├── locales # 多语言\n│   ├── logics # 逻辑\n│   ├── main.ts # 主入口\n│   ├── router # 路由配置\n│   ├── settings # 项目配置\n│   │   ├── componentSetting.ts # 组件配置\n│   │   ├── designSetting.ts # 样式配置\n│   │   ├── encryptionSetting.ts # 加密配置\n│   │   ├── localeSetting.ts # 多语言配置\n│   │   ├── projectSetting.ts # 项目配置\n│   │   └── siteSetting.ts # 站点配置\n│   ├── store # 数据仓库\n│   ├── utils # 工具类\n│   └── views # 页面\n├── types # 类型文件\n└── vite.config.ts # vite配置文件\n\n
',43);t.render=function(e,a,t,p,l,c){return n(),s("div",null,[o])};export default t;export{a as __pageData}; diff --git a/assets/guide_index.md.bb37fa1c.lean.js b/assets/guide_index.md.bb37fa1c.lean.js new file mode 100644 index 00000000..c12df29c --- /dev/null +++ b/assets/guide_index.md.bb37fa1c.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a as e}from"./app.8cddb23b.js";const a='{"title":"开始","description":"","frontmatter":{},"headers":[{"level":2,"title":"前言","slug":"前言"},{"level":2,"title":"环境准备","slug":"环境准备"},{"level":2,"title":"工具配置","slug":"工具配置"},{"level":2,"title":"代码获取","slug":"代码获取"},{"level":3,"title":"从 GitHub 获取代码","slug":"从-github-获取代码"},{"level":3,"title":"从 Gitee 获取代码","slug":"从-gitee-获取代码"},{"level":2,"title":"安装","slug":"安装"},{"level":3,"title":"安装 Node.js","slug":"安装-node-js"},{"level":3,"title":"安装依赖","slug":"安装依赖"},{"level":2,"title":"npm script","slug":"npm-script"},{"level":3,"title":"生成图标集","slug":"生成图标集"},{"level":3,"title":"重新安装依赖","slug":"重新安装依赖"},{"level":2,"title":"目录说明","slug":"目录说明"}],"relativePath":"guide/index.md","lastUpdated":1697592578593}',t={},o=e('',43);t.render=function(e,a,t,p,l,c){return n(),s("div",null,[o])};export default t;export{a as __pageData}; diff --git a/assets/guide_introduction.md.e458436d.js b/assets/guide_introduction.md.e458436d.js new file mode 100644 index 00000000..4beea1ec --- /dev/null +++ b/assets/guide_introduction.md.e458436d.js @@ -0,0 +1 @@ +import{o as e,c as r,a as t}from"./app.8cddb23b.js";const n='{"title":"介绍","description":"","frontmatter":{},"headers":[{"level":2,"title":"简介","slug":"简介"},{"level":2,"title":"文档","slug":"文档"},{"level":3,"title":"本地运行文档","slug":"本地运行文档"},{"level":2,"title":"需要掌握的基础知识","slug":"需要掌握的基础知识"},{"level":2,"title":"模版","slug":"模版"},{"level":2,"title":"vite 插件推荐","slug":"vite-插件推荐"},{"level":2,"title":"浏览器支持","slug":"浏览器支持"},{"level":2,"title":"如何加入我们","slug":"如何加入我们"}],"relativePath":"guide/introduction.md","lastUpdated":1697592578593}',a={},o=t('

介绍

简介

Vue-Vben-Admin 是一个基于 Vue3.0ViteAnt-Design-VueTypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3vitets 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。

文档

  • 中文文档地址为 vben-admin-doc,采用 Vitepress 开发。如发现文档有误,欢迎提 pr 帮助我们改进。
  • 英文文档暂时没有时间来写,欢迎有时间的同学来帮忙写英文文档。

本地运行文档

如需本地运行文档,请拉取代码到本地。

# 拉取代码\ngit clone https://github.com/vbenjs/vue-vben-admin-doc\n\n# 安装依赖\nyarn\n\n# 运行项目\nyarn dev\n

需要掌握的基础知识

本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:

模版

该版本主要是提供一些 Demo 示例及插件的使用集成方式,主要用于参考。如果对项目不是很熟悉,不建议在此基础上进行开发,请使用下方提供的精简版本。

vue-vben-admin 精简版本。删除了相关示例、无用文件及功能、依赖。可以根据自身需求安装对应的依赖。因为使用的是 vite,依赖删除不会导致相关组件或者 hook 发出警告。只在需要的时候安装对应的库即可。

vite 插件推荐

如果这些插件对你有帮助,可以给一个 star 支持下

浏览器支持

本地开发推荐使用Chrome 最新版浏览器,不支持Chrome 80以下版本。

生产环境支持现代浏览器,不支持 IE。

IEIE EdgeEdgeFirefoxFirefoxChromeChromeSafariSafari
not supportlast 2 versionslast 2 versionslast 2 versionslast 2 versions

如何加入我们

  • Vue-Vben-Admin 还在持续更新中,本项目欢迎您的参与,共同维护,逐步完善,将项目做得更强。同时整个项目本着一切免费的原则,原则上不会收取任何费用及版权,可以放心使用。
  • 如果你想加入我们,可以多提供一些好的建议或者提交 pr,我们会根据你的活跃度邀请你加入。
',25);a.render=function(t,n,a,i,l,s){return e(),r("div",null,[o])};export default a;export{n as __pageData}; diff --git a/assets/guide_introduction.md.e458436d.lean.js b/assets/guide_introduction.md.e458436d.lean.js new file mode 100644 index 00000000..9e33a093 --- /dev/null +++ b/assets/guide_introduction.md.e458436d.lean.js @@ -0,0 +1 @@ +import{o as e,c as r,a as t}from"./app.8cddb23b.js";const n='{"title":"介绍","description":"","frontmatter":{},"headers":[{"level":2,"title":"简介","slug":"简介"},{"level":2,"title":"文档","slug":"文档"},{"level":3,"title":"本地运行文档","slug":"本地运行文档"},{"level":2,"title":"需要掌握的基础知识","slug":"需要掌握的基础知识"},{"level":2,"title":"模版","slug":"模版"},{"level":2,"title":"vite 插件推荐","slug":"vite-插件推荐"},{"level":2,"title":"浏览器支持","slug":"浏览器支持"},{"level":2,"title":"如何加入我们","slug":"如何加入我们"}],"relativePath":"guide/introduction.md","lastUpdated":1697592578593}',a={},o=t('',25);a.render=function(t,n,a,i,l,s){return e(),r("div",null,[o])};export default a;export{n as __pageData}; diff --git a/assets/guide_lib.md.9e42530e.js b/assets/guide_lib.md.9e42530e.js new file mode 100644 index 00000000..8a909064 --- /dev/null +++ b/assets/guide_lib.md.9e42530e.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"引入外部模块","description":"","frontmatter":{},"headers":[{"level":2,"title":"安装","slug":"安装"},{"level":2,"title":"使用","slug":"使用"},{"level":3,"title":"全局使用","slug":"全局使用"},{"level":3,"title":"局部使用","slug":"局部使用"},{"level":2,"title":"注意","slug":"注意"}],"relativePath":"guide/lib.md","lastUpdated":1697592578593}',p={},e=s('

引入外部模块

除了自带组件以外,有时我们还需要引入其他外部模块。我们以 ant-design-vue 为例:

安装

安装 ant-design-vue

# 在终端输入下面的命令完成安装\nyarn add ant-design-vue\n

使用

全局使用

import { createApp } from 'vue';\nimport App from './App.vue';\nimport Antd from 'ant-design-vue';\nconst app = createApp(App);\napp.use(Antd);\napp.mount('#app');\n

局部使用

<template>\n  <Button>text</Button>\n</template>\n\n<script>\n  import { defineComponent } from 'vue';\n  import { Button } from 'ant-design-vue';\n  export default defineComponent({\n    components: {\n      Button,\n    },\n  });\n</script>\n

注意

  • 如果组件有依赖样式,则需要再引入样式文件
',12);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/guide_lib.md.9e42530e.lean.js b/assets/guide_lib.md.9e42530e.lean.js new file mode 100644 index 00000000..9fb028bd --- /dev/null +++ b/assets/guide_lib.md.9e42530e.lean.js @@ -0,0 +1 @@ +import{o as n,c as a,a as s}from"./app.8cddb23b.js";const t='{"title":"引入外部模块","description":"","frontmatter":{},"headers":[{"level":2,"title":"安装","slug":"安装"},{"level":2,"title":"使用","slug":"使用"},{"level":3,"title":"全局使用","slug":"全局使用"},{"level":3,"title":"局部使用","slug":"局部使用"},{"level":2,"title":"注意","slug":"注意"}],"relativePath":"guide/lib.md","lastUpdated":1697592578593}',p={},e=s('',12);p.render=function(s,t,p,o,c,l){return n(),a("div",null,[e])};export default p;export{t as __pageData}; diff --git a/assets/guide_menu.md.3fefed66.js b/assets/guide_menu.md.3fefed66.js new file mode 100644 index 00000000..ef43a074 --- /dev/null +++ b/assets/guide_menu.md.3fefed66.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"菜单","description":"","frontmatter":{},"headers":[{"level":2,"title":"菜单项类型","slug":"菜单项类型"},{"level":2,"title":"菜单模块","slug":"菜单模块"},{"level":2,"title":"新增菜单","slug":"新增菜单"},{"level":2,"title":"菜单排序","slug":"菜单排序"}],"relativePath":"guide/menu.md","lastUpdated":1697592578593}',p={},o=a('

菜单

项目菜单配置存放于 src/router/menus 下面

提示

菜单必须和路由匹配才能显示

菜单项类型

export interface Menu {\n  //  菜单名\n  name: string;\n  // 菜单图标,如果没有,则会尝试使用route.meta.icon\n  icon?: string;\n  // 菜单图片,如果同时传递了icon和img,则只会显示img\n  img?: string;\n  // 菜单路径\n  path: string;\n  // 是否禁用\n  disabled?: boolean;\n  // 子菜单\n  children?: Menu[];\n  // 菜单标签设置\n  tag: {\n    // 为true则显示小圆点\n    dot: boolean;\n    // 内容\n    content: string';\n    // 类型\n    type: 'error' | 'primary' | 'warn' | 'success';\n  };\n  // 是否隐藏菜单\n  hideMenu?: boolean;\n}\n

菜单模块

一个菜单文件会被当作一个模块

提示

children 的 path 字段不需要以/开头

import type { MenuModule } from '/@/router/types';\nimport { t } from '/@/hooks/web/useI18n';\nconst menu: MenuModule = {\n  orderNo: 10,\n  menu: {\n    name: t('routes.dashboard.dashboard'),\n    path: '/dashboard',\n\n    children: [\n      {\n        path: 'analysis',\n        name: t('routes.dashboard.analysis'),\n      },\n      {\n        path: 'workbench',\n        name: t('routes.dashboard.workbench'),\n      },\n    ],\n  },\n};\nexport default menu;\n

以上模块会转化成以下结构

[\n  path: '/dashboard',\n  name: t('routes.dashboard.dashboard'),\n  children: [\n    {\n      path: 'dashboard/analysis',\n      name: t('routes.dashboard.analysis'),\n    },\n    {\n      path: 'dashboard/workbench',\n      name: t('routes.dashboard.workbench'),\n    },\n  ],\n]\n

新增菜单

直接在 src/router/routes/modules 内新增一个模块文件即可。

不需要手动引入,放在src/router/routes/modules 内的文件会自动被加载。

菜单排序

在菜单模块内,设置 orderNo 变量,数值越大,排序越靠后

',16);p.render=function(a,t,p,e,c,r){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_menu.md.3fefed66.lean.js b/assets/guide_menu.md.3fefed66.lean.js new file mode 100644 index 00000000..a4f79dd5 --- /dev/null +++ b/assets/guide_menu.md.3fefed66.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"菜单","description":"","frontmatter":{},"headers":[{"level":2,"title":"菜单项类型","slug":"菜单项类型"},{"level":2,"title":"菜单模块","slug":"菜单模块"},{"level":2,"title":"新增菜单","slug":"新增菜单"},{"level":2,"title":"菜单排序","slug":"菜单排序"}],"relativePath":"guide/menu.md","lastUpdated":1697592578593}',p={},o=a('',16);p.render=function(a,t,p,e,c,r){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_mock.md.4205a506.js b/assets/guide_mock.md.4205a506.js new file mode 100644 index 00000000..ffe28bfd --- /dev/null +++ b/assets/guide_mock.md.4205a506.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"数据 mock&联调","description":"","frontmatter":{},"headers":[{"level":2,"title":"开发环境","slug":"开发环境"},{"level":3,"title":"配置","slug":"配置"},{"level":3,"title":"跨域处理","slug":"跨域处理"},{"level":3,"title":"没有跨域时的配置","slug":"没有跨域时的配置"},{"level":3,"title":"跨域原理解析","slug":"跨域原理解析"},{"level":2,"title":"生产环境","slug":"生产环境"},{"level":2,"title":"接口请求","slug":"接口请求"},{"level":2,"title":"axios 配置","slug":"axios-配置"},{"level":3,"title":"index.ts 配置说明","slug":"index-ts-配置说明"},{"level":3,"title":"更改参数格式","slug":"更改参数格式"},{"level":3,"title":"多个接口地址","slug":"多个接口地址"},{"level":3,"title":"删除请求 URL 携带的时间戳参数","slug":"删除请求-url-携带的时间戳参数"},{"level":2,"title":"Mock 服务","slug":"mock-服务"},{"level":3,"title":"本地 Mock","slug":"本地-mock"},{"level":3,"title":"线上 mock","slug":"线上-mock"}],"relativePath":"guide/mock.md","lastUpdated":1697592578593}',p={},o=a('

数据 mock&联调

开发环境

如果前端应用和后端接口服务器没有运行在同一个主机上,你需要在开发环境下将接口请求代理到接口服务器。

如果是同一个主机,可以直接请求具体的接口地址。

配置

开发环境时候,接口地址在项目根目录下

.env.development 文件配置

# vite 本地跨域代理\nVITE_PROXY=[["/basic-api","http://localhost:3000"]]\n# 接口地址\nVITE_GLOB_API_URL=/api\n

TIP

  • .env 文件中的字段如果是字符串,则无需加引号,默认全部为字符串
  • VITE_PROXY 不能换行

TIP

v3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。

跨域处理

如果你在 src/api/ 下面的接口为下方代码,且 .env.development 文件配置如下注释,则在控制台看到的地址为 http://localhost:3100/basic-api/login

由于 /basic-api 匹配到了设置的 VITE_PROXY,所以上方实际是请求 http://localhost:3000/login,这样同时也解决了跨域问题。(3100为项目端口号,http://localhost:3000为PROXY代理的目标地址)

// .env.development\n// VITE_PROXY=[["/basic-api","http://localhost:3000"]]\n// VITE_GLOB_API_URL=/basic-api\n\nenum Api {\n  Login = '/login',\n}\n\n/**\n * @description: 用户登陆\n */\nexport function loginApi(params: LoginParams) {\n  return http.request<LoginResultModel>({\n    url: Api.Login,\n    method: 'POST',\n    params,\n  });\n}\n

没有跨域时的配置

如果没有跨域问题,可以直接忽略 VITE_PROXY 配置,直接将接口地址设置在 VITE_GLOB_API_URL

# 例如接口地址为 http://localhost:3000 则\nVITE_GLOB_API_URL=http://localhost:3000\n

如果有跨域问题,将 VITE_GLOB_API_URL 设置为跟 VITE_PROXY 内其中一个数组的第一个项一致的值即可。

下方的接口地址设置为 /basic-api,当请求发出的时候会经过 Vite 的 proxy 代理,匹配到了我们设置的 VITE_PROXY 规则,将 /basic-api 转化为 http://localhost:3000 进行请求

# 例如接口地址为 http://localhost:3000 则\nVITE_PROXY=[["/basic-api","http://localhost:3000"]]\n# 接口地址\nVITE_GLOB_API_URL=/basic-api\n

跨域原理解析

vite.config.ts 配置文件中,提供了 server 的 proxy 功能,用于代理 API 请求。

server: {\n  proxy: {\n    "/basic-api":{\n      target: 'http://localhost:3000',\n      changeOrigin: true,\n      ws: true,\n      rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''),\n    }\n  },\n},\n

注意

从浏览器控制台的 Network 看,请求是 http://localhost:3000/basic-api/xxx,这是因为 proxy 配置不会改变本地请求的 url。

生产环境

生产环境接口地址在项目根目录下 .env.production 文件配置。

生产环境接口地址值需要修改 VITE_GLOB_API_URL,如果出现跨域问题,可以使用 nginx 或者后台开启 cors 进行处理

打包后如何进行地址修改?

VITE_GLOB_* 开头的变量会在打包的时候注入 _app.config.js 文件内。

dist/_app.config.js 修改相应的接口地址后刷新页面即可,不需要在根据不同环境打包多次,一次打包可以用于多个不同接口环境的部署。

接口请求

在 vue-vben-admin 中:

  1. 页面交互操作;
  2. 调用统一管理的 api 请求函数;
  3. 使用封装的 axios.ts 发送请求;
  4. 获取服务端返回数据
  5. 更新 data;

接口统一存放于 src/api/ 下面管理

以登陆接口为例:

src/api/ 内新建模块文件,其中参数与返回值最好定义一下类型,方便校验。虽然麻烦,但是后续维护字段很方便。

TIP

类型定义文件可以抽取出去统一管理,具体参考项目

import { defHttp } from '/@/utils/http/axios';\nimport { LoginParams, LoginResultModel } from './model/userModel';\n\nenum Api {\n  Login = '/login',\n}\n\nexport function loginApi(params: LoginParams) {\n  return defHttp.request<LoginResultModel>({\n    url: Api.Login,\n    method: 'POST',\n    params,\n  });\n}\n

axios 配置

axios 请求封装存放于 src/utils/http/axios 文件夹内部

index.ts 文件内容需要根据项目自行修改外,其余文件无需修改

\n├── Axios.ts // axios实例\n├── axiosCancel.ts // axiosCancel实例,取消重复请求\n├── axiosTransform.ts // 数据转换类\n├── checkStatus.ts // 返回状态值校验\n├── index.ts // 接口返回统一处理\n\n

index.ts 配置说明

const axios = new VAxios({\n  // 认证方案,例如: Bearer\n  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes\n  authenticationScheme: '',\n  // 接口超时时间 单位毫秒\n  timeout: 10 * 1000,\n  // 接口可能会有通用的地址部分,可以统一抽取出来\n  prefixUrl: prefix,\n  headers: { 'Content-Type': ContentTypeEnum.JSON },\n  // 数据处理方式,见下方说明\n  transform,\n  // 配置项,下面的选项都可以在独立的接口请求中覆盖\n  requestOptions: {\n    // 默认将prefix 添加到url\n    joinPrefix: true,\n    // 是否返回原生响应头 比如:需要获取响应头时使用该属性\n    isReturnNativeResponse: false,\n    // 需要对返回数据进行处理\n    isTransformRequestResult: true,\n    // post请求的时候添加参数到url\n    joinParamsToUrl: false,\n    // 格式化提交参数时间\n    formatDate: true,\n    // 消息提示类型\n    errorMessageMode: 'message',\n    // 接口地址\n    apiUrl: globSetting.apiUrl,\n    //  是否加入时间戳\n    joinTime: true,\n    // 忽略重复请求\n    ignoreCancelToken: true,\n  },\n});\n

transform 数据处理说明

类型定义,见 axiosTransform.ts 文件

export abstract class AxiosTransform {\n  /**\n   * @description: 请求之前处理配置\n   */\n  beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig;\n\n  /**\n   * @description: 请求成功处理\n   */\n  transformRequestData?: (res: AxiosResponse<Result>, options: RequestOptions) => any;\n\n  /**\n   * @description: 请求失败处理\n   */\n  requestCatch?: (e: Error) => Promise<any>;\n\n  /**\n   * @description: 请求之前的拦截器\n   */\n  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig;\n\n  /**\n   * @description: 请求之后的拦截器\n   */\n  responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>;\n\n  /**\n   * @description: 请求之前的拦截器错误处理\n   */\n  requestInterceptorsCatch?: (error: Error) => void;\n\n  /**\n   * @description: 请求之后的拦截器错误处理\n   */\n  responseInterceptorsCatch?: (error: Error) => void;\n}\n\n\n

项目默认 transform 处理逻辑,可以根据各自项目进行处理。一般需要更改的部分为下方代码,见代码注释说明

/**\n * @description: 数据处理,方便区分多种处理方式\n */\nconst transform: AxiosTransform = {\n  /**\n   * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误\n   */\n  transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {\n    const { t } = useI18n();\n    const { isTransformResponse, isReturnNativeResponse } = options;\n    // 是否返回原生响应头 比如:需要获取响应头时使用该属性\n    if (isReturnNativeResponse) {\n      return res;\n    }\n    // 不进行任何处理,直接返回\n    // 用于页面代码可能需要直接获取code,data,message这些信息时开启\n    if (!isTransformResponse) {\n      return res.data;\n    }\n    // 错误的时候返回\n\n    const { data } = res;\n    if (!data) {\n      // return '[HTTP] Request has no return value';\n      throw new Error(t('sys.api.apiRequestFailed'));\n    }\n    //  这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式\n    const { code, result, message } = data;\n\n    // 这里逻辑可以根据项目进行修改\n    const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS;\n    if (hasSuccess) {\n      return result;\n    }\n\n    // 在此处根据自己项目的实际情况对不同的code执行不同的操作\n    // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可\n    let timeoutMsg = '';\n    switch (code) {\n      case ResultEnum.TIMEOUT:\n        timeoutMsg = t('sys.api.timeoutMessage');\n      default:\n        if (message) {\n          timeoutMsg = message;\n        }\n    }\n\n    // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误\n    // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示\n    if (options.errorMessageMode === 'modal') {\n      createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });\n    } else if (options.errorMessageMode === 'message') {\n      createMessage.error(timeoutMsg);\n    }\n\n    throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));\n  },\n\n  // 请求之前处理config\n  beforeRequestHook: (config, options) => {\n    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options;\n\n    if (joinPrefix) {\n      config.url = `${urlPrefix}${config.url}`;\n    }\n\n    if (apiUrl && isString(apiUrl)) {\n      config.url = `${apiUrl}${config.url}`;\n    }\n    const params = config.params || {};\n    if (config.method?.toUpperCase() === RequestEnum.GET) {\n      if (!isString(params)) {\n        // 给 get 请求加上时间戳参数,避免从缓存中拿数据。\n        config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));\n      } else {\n        // 兼容restful风格\n        config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;\n        config.params = undefined;\n      }\n    } else {\n      if (!isString(params)) {\n        formatDate && formatRequestDate(params);\n        config.data = params;\n        config.params = undefined;\n        if (joinParamsToUrl) {\n          config.url = setObjToUrlParams(config.url as string, config.data);\n        }\n      } else {\n        // 兼容restful风格\n        config.url = config.url + params;\n        config.params = undefined;\n      }\n    }\n    return config;\n  },\n\n  /**\n   * @description: 请求拦截器处理\n   */\n  requestInterceptors: (config, options) => {\n    // 请求之前处理config\n    const token = getToken();\n    if (token) {\n      // jwt token\n      config.headers.Authorization = options.authenticationScheme\n        ? `${options.authenticationScheme} ${token}`\n        : token;\n    }\n    return config;\n  },\n\n  /**\n   * @description: 响应拦截器处理\n   */\n  responseInterceptors: (res: AxiosResponse<any>) => {\n    return res;\n  },\n\n  /**\n   * @description: 响应错误处理\n   */\n  responseInterceptorsCatch: (error: any) => {\n    const { t } = useI18n();\n    const errorLogStore = useErrorLogStoreWithOut();\n    errorLogStore.addAjaxErrorInfo(error);\n    const { response, code, message, config } = error || {};\n    const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';\n    const msg: string = response?.data?.error?.message ?? '';\n    const err: string = error?.toString?.() ?? '';\n    let errMessage = '';\n\n    try {\n      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {\n        errMessage = t('sys.api.apiTimeoutMessage');\n      }\n      if (err?.includes('Network Error')) {\n        errMessage = t('sys.api.networkExceptionMsg');\n      }\n\n      if (errMessage) {\n        if (errorMessageMode === 'modal') {\n          createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });\n        } else if (errorMessageMode === 'message') {\n          createMessage.error(errMessage);\n        }\n        return Promise.reject(error);\n      }\n    } catch (error) {\n      throw new Error(error);\n    }\n\n    checkStatus(error?.response?.status, msg, errorMessageMode);\n    return Promise.reject(error);\n  },\n};\n

更改参数格式

项目接口默认为 Json 参数格式,即 headers: { 'Content-Type': ContentTypeEnum.JSON },

如果需要更改为 form-data 格式,更改 headers 的 'Content-TypeContentTypeEnum.FORM_URLENCODED 即可

多个接口地址

当项目中需要用到多个接口地址时, 可以在 src/utils/http/axios/index.ts 导出多个 axios 实例

// 目前只导出一个默认实例,接口地址对应的是环境变量中的 VITE_GLOB_API_URL 接口地址\nexport const defHttp = createAxios();\n\n// 需要有其他接口地址的可以在后面添加\n\n// other api url\nexport const otherHttp = createAxios({\n  requestOptions: {\n    apiUrl: 'xxx',\n  },\n});\n

删除请求 URL 携带的时间戳参数

如果不需要 url 上面默认携带的时间戳参数 ?_t=xxx

const axios = new VAxios({\n  requestOptions: {\n    // 是否加入时间戳\n    joinTime: false,\n  },\n});\n

Mock 服务

Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发进程所阻塞。

本项目使用 vite-plugin-mock 来进行 mock 数据处理。项目内 mock 服务分本地和线上

本地 Mock

本地 mock 采用 Node.js 中间件进行参数拦截(不采用 mock.js 的原因是本地开发看不到请求参数和响应结果)。

如何新增 mock 接口

如果你想添加 mock 数据,只要在根目录下找到 mock 文件,添加对应的接口,对其进行拦截和模拟数据。

在 mock 文件夹内新建文件

TIP

文件新增后会自动更新,不需要手动重启,可以在代码控制台查看日志信息 mock 文件夹内会自动注册,排除以_开头的文件夹及文件

例:

import { MockMethod } from 'vite-plugin-mock';\nimport { resultPageSuccess } from '../_util';\n\nconst demoList = (() => {\n  const result: any[] = [];\n  for (let index = 0; index < 60; index++) {\n    result.push({\n      id: `${index}`,\n      beginTime: '@datetime',\n      endTime: '@datetime',\n      address: '@city()',\n      name: '@cname()',\n      'no|100000-10000000': 100000,\n      'status|1': ['正常', '启用', '停用'],\n    });\n  }\n  return result;\n})();\n\nexport default [\n  {\n    url: '/api/table/getDemoList',\n    timeout: 1000,\n    method: 'get',\n    response: ({ query }) => {\n      const { page = 1, pageSize = 20 } = query;\n      return resultPageSuccess(page, pageSize, demoList);\n    },\n  },\n] as MockMethod[];\n

TIP

mock 的值可以直接使用 mockjs 的语法。

接口格式

{\n  url: string; // mock 接口地址\n  method?: MethodType; // 请求方式\n  timeout?: number; // 延时时间\n  statusCode: number; // 响应状态码\n  response: ((opt: { // 响应结果\n      body: any;\n      query: any;\n  }) => any) | object;\n}\n

参数获取

GET 接口: ({ query }) => { }

POST 接口: ({ body }) => { }

util 说明

可在 代码 中查看

TIP

util 只作为服务处理结果数据使用。可以不用,如需使用可自行封装,需要将对应的字段改为接口的返回结构

匹配

src/api 下面,如果接口匹配到 mock,则会优先使用 mock 进行响应

import { defHttp } from '/@/utils/http/axios';\nimport { LoginParams, LoginResultModel } from './model/userModel';\n\nenum Api {\n  Login = '/login',\n}\n\n/**\n * @description: user login api\n */\nexport function loginApi(params: LoginParams) {\n  return defHttp.request<LoginResultModel>(\n    {\n      url: Api.Login,\n      method: 'POST',\n      params,\n    },\n    {\n      errorMessageMode: 'modal',\n    }\n  );\n}\n// 会匹配到上方的\nexport default [\n  {\n    url: '/api/login',\n    timeout: 1000,\n    method: 'POST',\n    response: ({ body }) => {\n      return resultPageSuccess({});\n    },\n  },\n] as MockMethod[];\n

接口有了,如何去掉 mock

当后台接口已经开发完成,只需要将相应的 mock 函数去掉即可。

以上方接口为例,假如后台接口 login 已经开发完成,则只需要删除/注释掉下方代码即可

export default [\n  {\n    url: '/api/login',\n    timeout: 1000,\n    method: 'POST',\n    response: ({ body }) => {\n      return resultPageSuccess({});\n    },\n  },\n] as MockMethod[];\n

线上 mock

由于该项目是一个展示类项目,线上也是用 mock 数据,所以在打包后同时也集成了 mock。通常项目线上一般为正式接口。

项目线上 mock 采用的是 mockjs 进行 mock 数据模拟。

线上如何开启 mock

注意

线上开启 mock 只适用于一些简单的示例网站及预览网站。一定不要在正式的生产环境开启!!!

  1. 修改 .env.production 文件内的 VITE_USE_MOCK 的值为 true
VITE_USE_MOCK = true;\n
  1. mock/_createProductionServer.ts 文件中引入需要的 mock 文件
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';\n\nconst modules = import.meta.globEager('./**/*.ts');\n\nconst mockModules: any[] = [];\nObject.keys(modules).forEach((key) => {\n  if (key.includes('/_')) {\n    return;\n  }\n  mockModules.push(...modules[key].default);\n});\n\nexport function setupProdMockServer() {\n  createProdMockServer(mockModules);\n}\n
  1. build/vite/plugin/mock.ts 里面引入
import { viteMockServe } from 'vite-plugin-mock';\n\nexport function configMockPlugin(isBuild: boolean) {\n  return viteMockServe({\n    injectCode: `\n      import { setupProdMockServer } from '../mock/_createProductionServer';\n\n      setupProdMockServer();\n      `,\n  });\n}\n

为什么通过插件注入代码而不是直接在 main.ts 内插入

在插件内通过 injectCode 插入代码,方便控制 mockjs 是否被打包到最终代码内。如果在 main.ts 内判断,如果关闭了 mock 功能,mockjs 也会打包到构建文件内,这样会增加打包体积。

到这里线上 mock 就配置完成了。线上与本地差异不大,比较大的区别是线上在控制台内看不到接口请求日志。

',96);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_mock.md.4205a506.lean.js b/assets/guide_mock.md.4205a506.lean.js new file mode 100644 index 00000000..b6bea3a0 --- /dev/null +++ b/assets/guide_mock.md.4205a506.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"数据 mock&联调","description":"","frontmatter":{},"headers":[{"level":2,"title":"开发环境","slug":"开发环境"},{"level":3,"title":"配置","slug":"配置"},{"level":3,"title":"跨域处理","slug":"跨域处理"},{"level":3,"title":"没有跨域时的配置","slug":"没有跨域时的配置"},{"level":3,"title":"跨域原理解析","slug":"跨域原理解析"},{"level":2,"title":"生产环境","slug":"生产环境"},{"level":2,"title":"接口请求","slug":"接口请求"},{"level":2,"title":"axios 配置","slug":"axios-配置"},{"level":3,"title":"index.ts 配置说明","slug":"index-ts-配置说明"},{"level":3,"title":"更改参数格式","slug":"更改参数格式"},{"level":3,"title":"多个接口地址","slug":"多个接口地址"},{"level":3,"title":"删除请求 URL 携带的时间戳参数","slug":"删除请求-url-携带的时间戳参数"},{"level":2,"title":"Mock 服务","slug":"mock-服务"},{"level":3,"title":"本地 Mock","slug":"本地-mock"},{"level":3,"title":"线上 mock","slug":"线上-mock"}],"relativePath":"guide/mock.md","lastUpdated":1697592578593}',p={},o=a('',96);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_router.md.31ce5cd8.js b/assets/guide_router.md.31ce5cd8.js new file mode 100644 index 00000000..4e4c2d84 --- /dev/null +++ b/assets/guide_router.md.31ce5cd8.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"路由","description":"","frontmatter":{},"headers":[{"level":2,"title":"配置","slug":"配置"},{"level":3,"title":"模块说明","slug":"模块说明"},{"level":3,"title":"多级路由","slug":"多级路由"},{"level":3,"title":"Meta 配置说明","slug":"meta-配置说明"},{"level":3,"title":"外部页面嵌套","slug":"外部页面嵌套"},{"level":3,"title":"外链","slug":"外链"},{"level":3,"title":"动态路由Tab自动关闭功能","slug":"动态路由tab自动关闭功能"},{"level":2,"title":"图标","slug":"图标"},{"level":2,"title":"新增路由","slug":"新增路由"},{"level":3,"title":"如何新增一个路由模块","slug":"如何新增一个路由模块"},{"level":3,"title":"验证","slug":"验证"},{"level":2,"title":"路由刷新","slug":"路由刷新"},{"level":3,"title":"实现","slug":"实现"},{"level":3,"title":"Redirect","slug":"redirect"},{"level":2,"title":"页面跳转","slug":"页面跳转"},{"level":3,"title":"方式","slug":"方式"},{"level":2,"title":"多标签页","slug":"多标签页"},{"level":3,"title":"如何开启页面缓存","slug":"如何开启页面缓存"},{"level":3,"title":"如何让某个页面不缓存","slug":"如何让某个页面不缓存"},{"level":2,"title":"如何更改首页路由","slug":"如何更改首页路由"}],"relativePath":"guide/router.md","lastUpdated":1697592578593}',p={},o=a('

路由

项目路由配置存放于 src/router/routes 下面。 src/router/routes/modules用于存放路由模块,在该目录下的文件会自动注册。

配置

模块说明

src/router/routes/modules 内的 .ts 文件会被视为一个路由模块。

一个路由模块包含以下结构

import type { AppRouteModule } from '/@/router/types';\n\nimport { LAYOUT } from '/@/router/constant';\nimport { t } from '/@/hooks/web/useI18n';\n\nconst dashboard: AppRouteModule = {\n  path: '/dashboard',\n  name: 'Dashboard',\n  component: LAYOUT,\n  redirect: '/dashboard/analysis',\n  meta: {\n    icon: 'ion:grid-outline',\n    title: t('routes.dashboard.dashboard'),\n  },\n  children: [\n    {\n      path: 'analysis',\n      name: 'Analysis',\n      component: () => import('/@/views/dashboard/analysis/index.vue'),\n      meta: {\n        affix: true,\n        title: t('routes.dashboard.analysis'),\n      },\n    },\n    {\n      path: 'workbench',\n      name: 'Workbench',\n      component: () => import('/@/views/dashboard/workbench/index.vue'),\n      meta: {\n        title: t('routes.dashboard.workbench'),\n      },\n    },\n  ],\n};\nexport default dashboard;\n

多级路由

注意事项

  • 整个项目所有路由 name 不能重复
  • 所有的多级路由最终都会转成二级路由,所以不能内嵌子路由
  • 除了 layout 对应的 path 前面需要加 /,其余子路由都不要以/开头

示例

import type { AppRouteModule } from '/@/router/types';\nimport { getParentLayout, LAYOUT } from '/@/router/constant';\nimport { t } from '/@/hooks/web/useI18n';\nconst permission: AppRouteModule = {\n  path: '/level',\n  name: 'Level',\n  component: LAYOUT,\n  redirect: '/level/menu1/menu1-1/menu1-1-1',\n  meta: {\n    icon: 'ion:menu-outline',\n    title: t('routes.demo.level.level'),\n  },\n\n  children: [\n    {\n      path: 'tabs/:id', \n      name: 'TabsParams',\n      component: getParentLayout('TabsParams'),\n      meta: {\n        carryParam: true,\n        hidePathForChildren: true, // 本级path将会在子级菜单中合成完整path时会忽略这一层级\n      },\n      children: [\n        path: 'tabs/id1', // 其上级有标记hidePathForChildren,所以本级在生成菜单时最终的path为  /level/tabs/id1\n        name: 'TabsParams',\n        component: getParentLayout('TabsParams'),\n        meta: {\n          carryParam: true,\n          ignoreRoute: true,  // 本路由仅用于菜单生成,不会在实际的路由表中出现\n        },\n      ]\n    },\n    {\n      path: 'menu1',\n      name: 'Menu1Demo',\n      component: getParentLayout('Menu1Demo'),\n      meta: {\n        title: 'Menu1',\n      },\n      redirect: '/level/menu1/menu1-1/menu1-1-1',\n      children: [\n        {\n          path: 'menu1-1',\n          name: 'Menu11Demo',\n          component: getParentLayout('Menu11Demo'),\n          meta: {\n            title: 'Menu1-1',\n          },\n          redirect: '/level/menu1/menu1-1/menu1-1-1',\n          children: [\n            {\n              path: 'menu1-1-1',\n              name: 'Menu111Demo',\n              component: () => import('/@/views/demo/level/Menu111.vue'),\n              meta: {\n                title: 'Menu111',\n              },\n            },\n          ],\n        },\n      ],\n    },\n  ],\n};\n\nexport default permission;\n

Meta 配置说明

export interface RouteMeta {\n  // 路由title  一般必填\n  title: string;\n  // 动态路由可打开Tab页数\n  dynamicLevel?: number;\n  // 动态路由的实际Path, 即去除路由的动态部分;\n  realPath?: string;\n  // 是否忽略权限,只在权限模式为Role的时候有效\n  ignoreAuth?: boolean;\n  // 可以访问的角色,只在权限模式为Role的时候有效\n  roles?: RoleEnum[];\n  // 是否忽略KeepAlive缓存\n  ignoreKeepAlive?: boolean;\n  // 是否固定标签\n  affix?: boolean;\n  // 图标,也是菜单图标\n  icon?: string;\n  // 内嵌iframe的地址\n  frameSrc?: string;\n  // 指定该路由切换的动画名\n  transitionName?: string;\n  // 隐藏该路由在面包屑上面的显示\n  hideBreadcrumb?: boolean;\n  // 如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true\n  carryParam?: boolean;\n  // 隐藏所有子菜单\n  hideChildrenInMenu?: boolean;\n  // 当前激活的菜单。用于配置详情页时左侧激活的菜单路径\n  currentActiveMenu?: string;\n  // 当前路由不再标签页显示\n  hideTab?: boolean;\n  // 当前路由不再菜单显示\n  hideMenu?: boolean;\n  // 菜单排序,只对第一级有效\n  orderNo?: number;\n  // 忽略路由。用于在ROUTE_MAPPING以及BACK权限模式下,生成对应的菜单而忽略路由。2.5.3以上版本有效\n  ignoreRoute?: boolean;\n  // 是否在子级菜单的完整path中忽略本级path。2.5.3以上版本有效\n  hidePathForChildren?: boolean;\n}\n

外部页面嵌套

只需要将 frameSrc 设置为需要跳转的地址即可

const IFrame = () => import('/@/views/sys/iframe/FrameBlank.vue');\n{\n  path: 'doc',\n  name: 'Doc',\n  component: IFrame,\n  meta: {\n    frameSrc: 'https://vvbin.cn/doc-next/',\n    title: t('routes.demo.iframe.doc'),\n  },\n},\n

外链

只需要将 path 设置为需要跳转的HTTP 地址即可

{\n  path: 'https://vvbin.cn/doc-next/',\n  name: 'DocExternal',\n  component: IFrame,\n  meta: {\n    title: t('routes.demo.iframe.docExternal'),\n  },\n}\n

动态路由Tab自动关闭功能

若需要开启该功能,需要在动态路由的meta中设置如下两个参数:

  • dynamicLevel 最大能打开的Tab标签页数
  • realPath 动态路由实际路径(考虑到动态路由有时候可能存在N层的情况, 例:/:id/:subId/:...), 为了减少计算开销, 使用配置方式事先规定好路由的实际路径(注意: 该参数若不设置,将无法使用该功能)
{\n  path: 'detail/:id',\n  name: 'TabDetail',\n  component: () => import('/@/views/demo/feat/tabs/TabDetail.vue'),\n  meta: {\n    currentActiveMenu: '/feat/tabs',\n    title: t('routes.demo.feat.tabDetail'),\n    hideMenu: true,\n    dynamicLevel: 3,\n    realPath: '/feat/tabs/detail',\n  },\n}\n

图标

这里的 icon 配置,会同步到 菜单(icon 的值可以查看此处)。

新增路由

如何新增一个路由模块

  1. src/router/routes/modules 内新增一个模块文件。

示例,新增 test.ts 文件

import type { AppRouteModule } from '/@/router/types';\nimport { LAYOUT } from '/@/router/constant';\nimport { t } from '/@/hooks/web/useI18n';\n\nconst dashboard: AppRouteModule = {\n  path: '/about',\n  name: 'About',\n  component: LAYOUT,\n  redirect: '/about/index',\n  meta: {\n    icon: 'simple-icons:about-dot-me',\n    title: t('routes.dashboard.about'),\n  },\n  children: [\n    {\n      path: 'index',\n      name: 'AboutPage',\n      component: () => import('/@/views/sys/about/index.vue'),\n      meta: {\n        title: t('routes.dashboard.about'),\n        icon: 'simple-icons:about-dot-me',\n      },\n    },\n  ],\n};\n\nexport default dashboard;\n

此时路由已添加完成,不需要手动引入,放在src/router/routes/modules 内的文件会自动被加载。

验证

访问 ip:端口/about/index 出现对应组件内容即代表成功

路由刷新

项目中采用的是重定向方式

实现

import { useRedo } from '/@/hooks/web/usePage';\nimport { defineComponent } from 'vue';\nexport default defineComponent({\n  setup() {\n    const redo = useRedo();\n    // 执行刷新\n    redo();\n    return {};\n  },\n});\n

Redirect

src/views/sys/redirect/index.vue

import { defineComponent, unref } from 'vue';\nimport { useRouter } from 'vue-router';\nexport default defineComponent({\n  name: 'Redirect',\n  setup() {\n    const { currentRoute, replace } = useRouter();\n    const { params, query } = unref(currentRoute);\n    const { path } = params;\n    const _path = Array.isArray(path) ? path.join('/') : path;\n    replace({\n      path: '/' + _path,\n      query,\n    });\n    return {};\n  },\n});\n

页面跳转

页面跳转建议采用项目提供的 useGo

方式

import { useGo } from '/@/hooks/web/usePage';\nimport { defineComponent } from 'vue';\nexport default defineComponent({\n  setup() {\n    const go = useGo();\n\n    // 执行刷新\n    go();\n    go(PageEnum.Home);\n    return {};\n  },\n});\n

多标签页

标签页使用的是 keep-aliverouter-view 实现,实现切换 tab 后还能保存切换之前的状态。

如何开启页面缓存

开启缓存有 3 个条件

  1. src/settings/projectSetting.ts 内将openKeepAlive 设置为 true
  2. 路由设置 name,且不能重复
  3. 路由对应的组件加上 name,与路由设置的 name 保持一致
 {\n   ...,\n    // name\n    name: 'Login',\n    // 对应组件组件的name\n    component: () => import('/@/views/sys/login/index.vue'),\n    ...\n  },\n\n  // /@/views/sys/login/index.vue\n  export default defineComponent({\n    // 需要和路由的name一致\n    name:"Login"\n  });\n

注意

keep-alive 生效的前提是:需要将路由的 name 属性及对应的页面的 name 设置成一样。因为:

include - 字符串或正则表达式,只有名称匹配的组件会被缓存

如何让某个页面不缓存

可在 router.meta 下配置

可以将 ignoreKeepAlive 配置成 true 即可关闭缓存。

export interface RouteMeta {\n  // 是否忽略KeepAlive缓存\n  ignoreKeepAlive?: boolean;\n}\n

如何更改首页路由

首页路由指的是应用程序中的默认路由,当不输入其他任何路由时,会自动重定向到该路由下,并且该路由在Tab上是固定的,即使设置affix: false也不允许关闭

例:首页路由配置的是/dashboard/analysis,那么当直接访问 http://localhost:3100/ 会自动跳转到http://localhost:3100/#/dashboard/analysis 上(用户已登录的情况下)

可以将pageEnum.ts中的BASE_HOME更改为需要你想设置的首页即可

export enum PageEnum {\n    // basic home path\n    // 更改此处即可\n    BASE_HOME = '/dashboard',\n}\n\n
',60);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_router.md.31ce5cd8.lean.js b/assets/guide_router.md.31ce5cd8.lean.js new file mode 100644 index 00000000..5dc82807 --- /dev/null +++ b/assets/guide_router.md.31ce5cd8.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"路由","description":"","frontmatter":{},"headers":[{"level":2,"title":"配置","slug":"配置"},{"level":3,"title":"模块说明","slug":"模块说明"},{"level":3,"title":"多级路由","slug":"多级路由"},{"level":3,"title":"Meta 配置说明","slug":"meta-配置说明"},{"level":3,"title":"外部页面嵌套","slug":"外部页面嵌套"},{"level":3,"title":"外链","slug":"外链"},{"level":3,"title":"动态路由Tab自动关闭功能","slug":"动态路由tab自动关闭功能"},{"level":2,"title":"图标","slug":"图标"},{"level":2,"title":"新增路由","slug":"新增路由"},{"level":3,"title":"如何新增一个路由模块","slug":"如何新增一个路由模块"},{"level":3,"title":"验证","slug":"验证"},{"level":2,"title":"路由刷新","slug":"路由刷新"},{"level":3,"title":"实现","slug":"实现"},{"level":3,"title":"Redirect","slug":"redirect"},{"level":2,"title":"页面跳转","slug":"页面跳转"},{"level":3,"title":"方式","slug":"方式"},{"level":2,"title":"多标签页","slug":"多标签页"},{"level":3,"title":"如何开启页面缓存","slug":"如何开启页面缓存"},{"level":3,"title":"如何让某个页面不缓存","slug":"如何让某个页面不缓存"},{"level":2,"title":"如何更改首页路由","slug":"如何更改首页路由"}],"relativePath":"guide/router.md","lastUpdated":1697592578593}',p={},o=a('',60);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_settings.md.560c3ce7.js b/assets/guide_settings.md.560c3ce7.js new file mode 100644 index 00000000..810a21da --- /dev/null +++ b/assets/guide_settings.md.560c3ce7.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"项目配置项","description":"","frontmatter":{},"headers":[{"level":2,"title":"环境变量配置","slug":"环境变量配置"},{"level":3,"title":"配置项说明","slug":"配置项说明"},{"level":3,"title":".env","slug":"env"},{"level":3,"title":".env.development","slug":"env-development"},{"level":3,"title":".env.production","slug":"env-production"},{"level":2,"title":"生产环境动态配置","slug":"生产环境动态配置"},{"level":3,"title":"说明","slug":"说明"},{"level":3,"title":"作用","slug":"作用"},{"level":3,"title":"如何获取全局变量","slug":"如何获取全局变量"},{"level":3,"title":"如何新增(新增一个可动态修改的配置项)","slug":"如何新增-新增一个可动态修改的配置项"},{"level":2,"title":"项目配置","slug":"项目配置"},{"level":3,"title":"配置文件路径","slug":"配置文件路径"},{"level":3,"title":"说明","slug":"说明-1"},{"level":2,"title":"缓存配置","slug":"缓存配置"},{"level":2,"title":"多语言配置","slug":"多语言配置"},{"level":2,"title":"主题色配置","slug":"主题色配置"},{"level":2,"title":"样式配置","slug":"样式配置"},{"level":3,"title":"css 前缀设置","slug":"css-前缀设置"},{"level":3,"title":"前缀使用","slug":"前缀使用"},{"level":2,"title":"颜色配置","slug":"颜色配置"},{"level":2,"title":"组件默认参数配置","slug":"组件默认参数配置"}],"relativePath":"guide/settings.md","lastUpdated":1697592578593}',p={},o=a('

项目配置项

用于修改项目的配色、布局、缓存、多语言、组件默认配置

环境变量配置

项目的环境变量配置位于项目根目录下的 .env.env.development.env.production

具体可以参考 Vite 文档

.env                # 在所有的环境中被载入\n.env.local          # 在所有的环境中被载入,但会被 git 忽略\n.env.[mode]         # 只在指定的模式中被载入\n.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略\n\n

温馨提醒

  • 只有以 VITE_ 开头的变量会被嵌入到客户端侧的包中,你可以在项目代码中这样访问它们:
console.log(import.meta.env.VITE_PROT);\n
  • VITE_GLOB_* 开头的的变量,在打包的时候,会被加入_app.config.js配置文件当中.

配置项说明

.env

所有环境适用

# 端口号\nVITE_PORT=3100\n# 网站标题\nVITE_GLOB_APP_TITLE=vben admin\n# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符\nVITE_GLOB_APP_SHORT_NAME=vben_admin\n

.env.development

开发环境适用

# 是否开启mock数据,关闭时需要自行对接后台接口\nVITE_USE_MOCK=true\n# 资源公共路径,需要以 /开头和结尾\nVITE_PUBLIC_PATH=/\n# 是否删除Console.log\nVITE_DROP_CONSOLE=false\n# 本地开发代理,可以解决跨域及多地址代理\n# 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题\n# 可以有多个,注意多个不能换行,否则代理将会失效\nVITE_PROXY=[["/api","http://localhost:3000"],["api1","http://localhost:3001"],["/upload","http://localhost:3001/upload"]]\n\n::: tip\nv3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。\n:::\n\n# 接口地址\n# 如果没有跨域问题,直接在这里配置即可\nVITE_GLOB_API_URL=/api\n# 文件上传接口  可选\nVITE_GLOB_UPLOAD_URL=/upload\n# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换\nVITE_GLOB_API_URL_PREFIX=\n

注意

这里配置的 VITE_PROXY 以及 VITE_GLOB_API_URL, /api 需要是唯一的,不要和接口有的名字冲突

如果你的接口是 http://localhost:3000/api 之类的,请考虑将 VITE_GLOB_API_URL=/xxxx 换成别的名字

.env.production

生产环境适用

# 是否开启mock\nVITE_USE_MOCK=true\n# 接口地址 可以由nginx做转发或者直接写实际地址\nVITE_GLOB_API_URL=/api\n# 文件上传地址 可以由nginx做转发或者直接写实际地址\nVITE_GLOB_UPLOAD_URL=/upload\n# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换\nVITE_GLOB_API_URL_PREFIX=\n# 是否删除Console.log\nVITE_DROP_CONSOLE=true\n# 资源公共路径,需要以 / 开头和结尾\nVITE_PUBLIC_PATH=/\n# 打包是否输出gz|br文件\n# 可选: gzip | brotli | none\n# 也可以有多个, 例如 ‘gzip’|'brotli',这样会同时生成 .gz和.br文件\nVITE_BUILD_COMPRESS = 'gzip'\n# 打包是否压缩图片\nVITE_USE_IMAGEMIN = false\n# 打包是否开启pwa功能\nVITE_USE_PWA = false\n# 是否兼容旧版浏览器。开启后打包时间会慢一倍左右。会多打出旧浏览器兼容包,且会根据浏览器兼容性自动使用相应的版本\nVITE_LEGACY = false\n

生产环境动态配置

说明

当执行yarn build构建项目之后,会自动生成 _app.config.js 文件并插入 index.html

注意: 开发环境不会生成

// _app.config.js\n// 变量名命名规则  __PRODUCTION__xxx_CONF__   xxx:为.env配置的VITE_GLOB_APP_SHORT_NAME\nwindow.__PRODUCTION__VUE_VBEN_ADMIN__CONF__ = {\n  VITE_GLOB_APP_TITLE: 'vben admin',\n  VITE_GLOB_APP_SHORT_NAME: 'vue_vben_admin',\n  VITE_GLOB_API_URL: '/app',\n  VITE_GLOB_API_URL_PREFIX: '/',\n  VITE_GLOB_UPLOAD_URL: '/upload',\n};\n

作用

_app.config.js 用于项目在打包后,需要动态修改配置的需求,如接口地址。不用重新进行打包,可在打包后修改 /dist/_app.config.js 内的变量,刷新即可更新代码内的局部变量。

如何获取全局变量

想要获取 _app.config.js 内的变量,可以使用 src/hooks/setting/index.ts 提供的函数来进行获取

如何新增(新增一个可动态修改的配置项)

  1. 首先在 .env 或者对应的开发环境配置文件内,新增需要可动态配置的变量,需要以 VITE_GLOB_开头

  2. VITE_GLOB_ 开头的变量会自动加入环境变量,通过在 types/config.d.ts 内修改 GlobEnvConfigGlobConfig 两个环境变量的值来定义新添加的类型

  3. useGlobSetting 函数中添加刚新增的返回值即可

const {\n  VITE_GLOB_APP_TITLE,\n  VITE_GLOB_API_URL,\n  VITE_GLOB_APP_SHORT_NAME,\n  VITE_GLOB_API_URL_PREFIX,\n  VITE_GLOB_UPLOAD_URL,\n} = ENV;\n\nexport const useGlobSetting = (): SettingWrap => {\n  // Take global configuration\n  const glob: Readonly<GlobConfig> = {\n    title: VITE_GLOB_APP_TITLE,\n    apiUrl: VITE_GLOB_API_URL,\n    shortName: VITE_GLOB_APP_SHORT_NAME,\n    urlPrefix: VITE_GLOB_API_URL_PREFIX,\n    uploadUrl: VITE_GLOB_UPLOAD_URL\n  };\n  return glob as Readonly<GlobConfig>;\n};\n\n

项目配置

WARNING

项目配置文件用于配置项目内展示的内容、布局、文本等效果,存于localStorage中。如果更改了项目配置,需要手动清空 localStorage 缓存,刷新重新登录后方可生效。

配置文件路径

src/settings/projectSetting.ts

说明

// ! 改动后需要清空浏览器缓存\nconst setting: ProjectConfig = {\n  // 是否显示SettingButton\n  showSettingButton: true,\n\n  // 是否显示主题切换按钮\n  showDarkModeToggle: true,\n\n  // 设置按钮位置 可选项\n  // SettingButtonPositionEnum.AUTO: 自动选择\n  // SettingButtonPositionEnum.HEADER: 位于头部\n  // SettingButtonPositionEnum.FIXED: 固定在右侧\n  settingButtonPosition: SettingButtonPositionEnum.AUTO,\n\n  // 权限模式,默认前端角色权限模式\n  // ROUTE_MAPPING: 前端模式(菜单由路由生成,默认)\n  // ROLE:前端模式(菜单路由分开)\n  permissionMode: PermissionModeEnum.ROUTE_MAPPING,\n  // 权限缓存存放位置。默认存放于localStorage\n  permissionCacheType: CacheTypeEnum.LOCAL,\n  // 会话超时处理方案\n  // SessionTimeoutProcessingEnum.ROUTE_JUMP: 路由跳转到登录页\n  // SessionTimeoutProcessingEnum.PAGE_COVERAGE: 生成登录弹窗,覆盖当前页面\n  sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP,\n  // 项目主题色\n  themeColor: primaryColor,\n  // 网站灰色模式,用于可能悼念的日期开启\n  grayMode: false,\n  // 色弱模式\n  colorWeak: false,\n  // 是否取消菜单,顶部,多标签页显示, 用于可能内嵌在别的系统内\n  fullContent: false,\n  // 主题内容宽度\n  contentMode: ContentEnum.FULL,\n  // 是否显示logo\n  showLogo: true,\n  // 是否显示底部信息 copyright\n  showFooter: true,\n  // 头部配置\n  headerSetting: {\n    // 背景色\n    bgColor: '#ffffff',\n    // 固定头部\n    fixed: true,\n    // 是否显示顶部\n    show: true,\n    // 主题\n    theme: MenuThemeEnum.LIGHT,\n    // 开启锁屏功能\n    useLockPage: true,\n    // 显示全屏按钮\n    showFullScreen: true,\n    // 显示文档按钮\n    showDoc: true,\n    // 显示消息中心按钮\n    showNotice: true,\n    // 显示菜单搜索按钮\n    showSearch: true,\n  },\n  // 菜单配置\n  menuSetting: {\n    // 背景色\n    bgColor: '#273352',\n    // 是否固定住菜单\n    fixed: true,\n    // 菜单折叠\n    collapsed: false,\n    // 折叠菜单时候是否显示菜单名\n    collapsedShowTitle: false,\n    // 是否可拖拽\n    canDrag: true,\n    // 是否显示\n    show: true,\n    // 菜单宽度\n    menuWidth: 180,\n    // 菜单模式\n    mode: MenuModeEnum.INLINE,\n    // 菜单类型\n    type: MenuTypeEnum.SIDEBAR,\n    // 菜单主题\n    theme: MenuThemeEnum.DARK,\n    // 分割菜单\n    split: false,\n    // 顶部菜单布局\n    topMenuAlign: 'start',\n    // 折叠触发器的位置\n    trigger: TriggerEnum.HEADER,\n    // 手风琴模式,只展示一个菜单\n    accordion: true,\n    // 在路由切换的时候关闭左侧混合菜单展开菜单\n    closeMixSidebarOnChange: false,\n    // 左侧混合菜单模块切换触发方式\n    mixSideTrigger: MixSidebarTriggerEnum.CLICK,\n    // 是否固定左侧混合菜单\n    mixSideFixed: false,\n  },\n  // 多标签\n  multiTabsSetting: {\n    // 刷新后是否保留已经打开的标签页\n    cache: false,\n    // 开启\n    show: true,\n    // 开启快速操作\n    showQuick: true,\n    // 是否可以拖拽\n    canDrag: true,\n    // 是否显示刷新按钮\n    showRedo: true,\n    // 是否显示折叠按钮\n    showFold: true,\n  },\n\n  // 动画配置\n  transitionSetting: {\n    //  是否开启切换动画\n    enable: true,\n    // 动画名\n    basicTransition: RouterTransitionEnum.FADE_SIDE,\n    // 是否打开页面切换loading\n    openPageLoading: true,\n    // 是否打开页面切换顶部进度条\n    openNProgress: false,\n  },\n\n  // 是否开启KeepAlive缓存  开发时候最好关闭,不然每次都需要清除缓存\n  openKeepAlive: true,\n  // 自动锁屏时间,为0不锁屏。 单位分钟 默认1个小时\n  lockTime: 0,\n  // 显示面包屑\n  showBreadCrumb: true,\n  // 显示面包屑图标\n  showBreadCrumbIcon: false,\n  // 是否使用全局错误捕获\n  useErrorHandle: false,\n  // 是否开启回到顶部\n  useOpenBackTop: true,\n  //  是否可以嵌入iframe页面\n  canEmbedIFramePage: true,\n  // 切换界面的时候是否删除未关闭的message及notify\n  closeMessageOnSwitch: true,\n  // 切换界面的时候是否取消已经发送但是未响应的http请求。\n  // 如果开启,想对单独接口覆盖。可以在单独接口设置\n  removeAllHttpPending: true,\n};\n

缓存配置

用于配置缓存内容加密信息,对缓存到浏览器的信息进行 AES 加密

/@/settings/encryptionSetting.ts 内可以配置 localStoragesessionStorage 缓存信息

前提: 使用项目自带的缓存工具类 /@/utils/cache 来进行缓存操作

import { isDevMode } from '/@/utils/env';\n\n// 缓存默认过期时间\nexport const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;\n\n// 开启缓存加密后,加密密钥。采用aes加密\nexport const cacheCipher = {\n  key: '_11111000001111@',\n  iv: '@11111000001111_',\n};\n\n// 是否加密缓存,默认生产环境加密\nexport const enableStorageEncryption = !isDevMode();\n

多语言配置

用于配置多语言信息

src/settings/localeSetting.ts 内配置

export const LOCALE: { [key: string]: LocaleType } = {\n  ZH_CN: 'zh_CN',\n  EN_US: 'en',\n};\n\nexport const localeSetting: LocaleSetting = {\n  // 是否显示语言选择器\n  showPicker: true,\n  // 当前语言\n  locale: LOCALE.ZH_CN,\n  // 默认语言\n  fallback: LOCALE.ZH_CN,\n  // 允许的语言\n  availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US],\n};\n\n// 语言列表\nexport const localeList: DropMenu[] = [\n  {\n    text: '简体中文',\n    event: LOCALE.ZH_CN,\n  },\n  {\n    text: 'English',\n    event: LOCALE.EN_US,\n  },\n];\n

主题色配置

默认全局主题色配置位于 build/config/glob/themeConfig.ts

只需要修改 primaryColor 为您需要的配色,然后重新执行 yarn serve 即可

/**\n * less global variable\n */\nexport const primaryColor = '#0960bd';\n

样式配置

css 前缀设置

用于修改项目内组件 class 的统一前缀

export const prefixCls = 'vben';\n
@namespace: vben;\n

前缀使用

在 css 内

<style lang="less" scoped>\n  /* namespace已经全局注入,不需要额外再引入 */\n  @prefix-cls: ~'@{namespace}-app-logo';\n\n  .@{prefix-cls} {\n    width: 100%;\n  }\n</style>\n

在 vue/ts 内

import { useDesign } from '/@/hooks/web/useDesign';\n\nconst { prefixCls } = useDesign('app-logo');\n\n// prefixCls => vben-app-logo\n

颜色配置

用于预设一些颜色数组

src/settings/designSetting.ts 内配置

//  app主题色预设\nexport const APP_PRESET_COLOR_LIST: string[] = [\n  '#0960bd',\n  '#0084f4',\n  '#009688',\n  '#536dfe',\n  '#ff5c93',\n  '#ee4f12',\n  '#0096c7',\n  '#9c27b0',\n  '#ff9800',\n];\n\n// 顶部背景色预设\nexport const HEADER_PRESET_BG_COLOR_LIST: string[] = [\n  '#ffffff',\n  '#009688',\n  '#5172DC',\n  '#1E9FFF',\n  '#018ffb',\n  '#409eff',\n  '#4e73df',\n  '#e74c3c',\n  '#24292e',\n  '#394664',\n  '#001529',\n  '#383f45',\n];\n\n// 左侧菜单背景色预设\nexport const SIDE_BAR_BG_COLOR_LIST: string[] = [\n  '#001529',\n  '#273352',\n  '#ffffff',\n  '#191b24',\n  '#191a23',\n  '#304156',\n  '#001628',\n  '#28333E',\n  '#344058',\n  '#383f45',\n];\n

组件默认参数配置

src/settings/componentSetting.ts 内配置

// 用于配置某些组件的常规配置,而无需修改组件\nimport type { SorterResult } from '../components/Table';\n\nexport default {\n  // 表格配置\n  table: {\n    // 表格接口请求通用配置,可在组件prop覆盖\n    // 支持 xxx.xxx.xxx格式\n    fetchSetting: {\n      // 传给后台的当前页字段\n      pageField: 'page',\n      // 传给后台的每页显示多少条的字段\n      sizeField: 'pageSize',\n      // 接口返回表格数据的字段\n      listField: 'items',\n      // 接口返回表格总数的字段\n      totalField: 'total',\n    },\n    // 可选的分页选项\n    pageSizeOptions: ['10', '50', '80', '100'],\n    //默认每页显示多少条\n    defaultPageSize: 10,\n    // 默认排序方法\n    defaultSortFn: (sortInfo: SorterResult) => {\n      const { field, order } = sortInfo;\n      return {\n        // 排序字段\n        field,\n        // 排序方式 asc/desc\n        order,\n      };\n    },\n    // 自定义过滤方法\n    defaultFilterFn: (data: Partial<Recordable<string[]>>) => {\n      return data;\n    },\n  },\n  // 滚动组件配置\n  scrollbar: {\n    // 是否使用原生滚动样式\n    // 开启后,菜单,弹窗,抽屉会使用原生滚动条组件\n    native: false,\n  },\n};\n
',68);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/guide_settings.md.560c3ce7.lean.js b/assets/guide_settings.md.560c3ce7.lean.js new file mode 100644 index 00000000..e7c13e03 --- /dev/null +++ b/assets/guide_settings.md.560c3ce7.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"项目配置项","description":"","frontmatter":{},"headers":[{"level":2,"title":"环境变量配置","slug":"环境变量配置"},{"level":3,"title":"配置项说明","slug":"配置项说明"},{"level":3,"title":".env","slug":"env"},{"level":3,"title":".env.development","slug":"env-development"},{"level":3,"title":".env.production","slug":"env-production"},{"level":2,"title":"生产环境动态配置","slug":"生产环境动态配置"},{"level":3,"title":"说明","slug":"说明"},{"level":3,"title":"作用","slug":"作用"},{"level":3,"title":"如何获取全局变量","slug":"如何获取全局变量"},{"level":3,"title":"如何新增(新增一个可动态修改的配置项)","slug":"如何新增-新增一个可动态修改的配置项"},{"level":2,"title":"项目配置","slug":"项目配置"},{"level":3,"title":"配置文件路径","slug":"配置文件路径"},{"level":3,"title":"说明","slug":"说明-1"},{"level":2,"title":"缓存配置","slug":"缓存配置"},{"level":2,"title":"多语言配置","slug":"多语言配置"},{"level":2,"title":"主题色配置","slug":"主题色配置"},{"level":2,"title":"样式配置","slug":"样式配置"},{"level":3,"title":"css 前缀设置","slug":"css-前缀设置"},{"level":3,"title":"前缀使用","slug":"前缀使用"},{"level":2,"title":"颜色配置","slug":"颜色配置"},{"level":2,"title":"组件默认参数配置","slug":"组件默认参数配置"}],"relativePath":"guide/settings.md","lastUpdated":1697592578593}',p={},o=a('',68);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/index.md.4d6d00ec.js b/assets/index.md.4d6d00ec.js new file mode 100644 index 00000000..787f4c64 --- /dev/null +++ b/assets/index.md.4d6d00ec.js @@ -0,0 +1 @@ +import{o as t,c as e}from"./app.8cddb23b.js";const i='{"title":"Home","description":"","frontmatter":{"home":true,"heroImage":"/logo.png","actionText":"快速开始 →","actionLink":"/guide/introduction","altActionText":"在线预览","altActionLink":"https://vben.vvbin.cn/","features":[{"title":"💡 最新技术栈","details":"基于Vue3、Vite、TypeScript等最新技术栈开发"},{"title":"⚡️ 轻量快速的热重载","details":"无论应用程序大小如何,都始终极快的模块热重载(HMR)"},{"title":"🛠️ 丰富的示例","details":"常见的Web端插件示例实现"},{"title":"📦 组件封装","details":"对日常使用频率较高的组件二次封装,满足基础工作需求"},{"title":"🔩 主题配置","details":"丰富的主题配置及黑暗主题适配"},{"title":"🔑 权限管理","details":"完善的前后端权限管理方案"}],"footer":"MIT Licensed | Copyright © 2021-present Vben"},"relativePath":"index.md","lastUpdated":1697592578593}',n={};n.render=function(i,n,o,a,r,d){return t(),e("div")};export default n;export{i as __pageData}; diff --git a/assets/index.md.4d6d00ec.lean.js b/assets/index.md.4d6d00ec.lean.js new file mode 100644 index 00000000..787f4c64 --- /dev/null +++ b/assets/index.md.4d6d00ec.lean.js @@ -0,0 +1 @@ +import{o as t,c as e}from"./app.8cddb23b.js";const i='{"title":"Home","description":"","frontmatter":{"home":true,"heroImage":"/logo.png","actionText":"快速开始 →","actionLink":"/guide/introduction","altActionText":"在线预览","altActionLink":"https://vben.vvbin.cn/","features":[{"title":"💡 最新技术栈","details":"基于Vue3、Vite、TypeScript等最新技术栈开发"},{"title":"⚡️ 轻量快速的热重载","details":"无论应用程序大小如何,都始终极快的模块热重载(HMR)"},{"title":"🛠️ 丰富的示例","details":"常见的Web端插件示例实现"},{"title":"📦 组件封装","details":"对日常使用频率较高的组件二次封装,满足基础工作需求"},{"title":"🔩 主题配置","details":"丰富的主题配置及黑暗主题适配"},{"title":"🔑 权限管理","details":"完善的前后端权限管理方案"}],"footer":"MIT Licensed | Copyright © 2021-present Vben"},"relativePath":"index.md","lastUpdated":1697592578593}',n={};n.render=function(i,n,o,a,r,d){return t(),e("div")};export default n;export{i as __pageData}; diff --git a/assets/other_donate.md.36952460.js b/assets/other_donate.md.36952460.js new file mode 100644 index 00000000..09eae285 --- /dev/null +++ b/assets/other_donate.md.36952460.js @@ -0,0 +1 @@ +import{o as a,c as e,b as t,d as r}from"./app.8cddb23b.js";const n='{"title":"赞助","description":"","frontmatter":{},"relativePath":"other/donate.md","lastUpdated":1697592578593}',p={},l=t("h1",{id:"赞助"},[t("a",{class:"header-anchor",href:"#赞助","aria-hidden":"true"},"#"),r(" 赞助")],-1),d=t("p",null,"如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!",-1),o=t("p",null,[t("img",{src:"https://anncwb.github.io/anncwb/images/sponsor.png",alt:"donate"})],-1),i=t("p",null,[t("a",{style:{display:"block",width:"100px",height:"50px","line-height":"50px",color:"#fff","text-align":"center",background:"#408aed","border-radius":"4px"},href:"https://www.paypal.com/paypalme/cvvben"},"Paypal Me")],-1);p.render=function(t,r,n,p,s,c){return a(),e("div",null,[l,d,o,i])};export default p;export{n as __pageData}; diff --git a/assets/other_donate.md.36952460.lean.js b/assets/other_donate.md.36952460.lean.js new file mode 100644 index 00000000..09eae285 --- /dev/null +++ b/assets/other_donate.md.36952460.lean.js @@ -0,0 +1 @@ +import{o as a,c as e,b as t,d as r}from"./app.8cddb23b.js";const n='{"title":"赞助","description":"","frontmatter":{},"relativePath":"other/donate.md","lastUpdated":1697592578593}',p={},l=t("h1",{id:"赞助"},[t("a",{class:"header-anchor",href:"#赞助","aria-hidden":"true"},"#"),r(" 赞助")],-1),d=t("p",null,"如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!",-1),o=t("p",null,[t("img",{src:"https://anncwb.github.io/anncwb/images/sponsor.png",alt:"donate"})],-1),i=t("p",null,[t("a",{style:{display:"block",width:"100px",height:"50px","line-height":"50px",color:"#fff","text-align":"center",background:"#408aed","border-radius":"4px"},href:"https://www.paypal.com/paypalme/cvvben"},"Paypal Me")],-1);p.render=function(t,r,n,p,s,c){return a(),e("div",null,[l,d,o,i])};export default p;export{n as __pageData}; diff --git a/assets/other_doubt.md.d791cebd.js b/assets/other_doubt.md.d791cebd.js new file mode 100644 index 00000000..83f87f5d --- /dev/null +++ b/assets/other_doubt.md.d791cebd.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"常见疑点说明","description":"","frontmatter":{},"headers":[{"level":2,"title":"项目别名","slug":"项目别名"},{"level":2,"title":"为什么在本地没有按需引入组件库样式,在生产才引入","slug":"为什么在本地没有按需引入组件库样式,在生产才引入"},{"level":2,"title":"为什么单独把 moment 放到 dataUtil 内","slug":"为什么单独把-moment-放到-datautil-内"}],"relativePath":"other/doubt.md","lastUpdated":1697592578593}',p={},o=a('

常见疑点说明

该分类主要说明一些地方为什么这样做,以及原因是什么

项目别名

/@/vite 内配置的别名

/@/settings 等同于 src/settings

为什么是/@/

因为项目是从 vite1.0 过渡过来的,vite1.0 只能以 / 开头,所以有一部分从 webpack 用户转过来的可能不习惯。

为什么在本地没有按需引入组件库样式,在生产才引入

在 main.ts 内可以看到,本地开发会全量引入 antd.less,vite-plugin-style-import 在本地是没有作用的。

这样做的原因主要是加快本地开发刷新速度。如果在本地开发中也按需按需引入,则在浏览器控制台内可以看到,平均一个页面大概增加了 100 次 http 请求。如果全量引入,只增加了一个请求,所以为了减少请求数量,才这样种。

// src/main.ts\nif (import.meta.env.DEV) {\n  import('ant-design-vue/dist/antd.less');\n}\n\n// build/vite/plugin/styleImport\nimport styleImport from 'vite-plugin-style-import';\nexport function configStyleImportPlugin(isBuild: boolean) {\n  if (!isBuild) return [];\n  const styleImportPlugin = styleImport({\n    libs: [\n      {\n        libraryName: 'ant-design-vue',\n        esModule: true,\n        resolveStyle: (name) => {\n          return `ant-design-vue/es/${name}/style/index`;\n        },\n      },\n    ],\n  });\n  return styleImportPlugin;\n}\n

为什么单独把 moment 放到 dataUtil 内

src/utils/dataUtil 内,使用的是 moment,其次在页面中对时间的操作也是使用 dateUtil,而不是直接 import moment from 'moment'

这样做主要是方便后续切换到 dayjs,因为 api 一样,所以在后续切换中,只需更改 dataUtil 内的 import 即可,而不用全部更改。

',13);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/other_doubt.md.d791cebd.lean.js b/assets/other_doubt.md.d791cebd.lean.js new file mode 100644 index 00000000..81efd959 --- /dev/null +++ b/assets/other_doubt.md.d791cebd.lean.js @@ -0,0 +1 @@ +import{o as n,c as s,a}from"./app.8cddb23b.js";const t='{"title":"常见疑点说明","description":"","frontmatter":{},"headers":[{"level":2,"title":"项目别名","slug":"项目别名"},{"level":2,"title":"为什么在本地没有按需引入组件库样式,在生产才引入","slug":"为什么在本地没有按需引入组件库样式,在生产才引入"},{"level":2,"title":"为什么单独把 moment 放到 dataUtil 内","slug":"为什么单独把-moment-放到-datautil-内"}],"relativePath":"other/doubt.md","lastUpdated":1697592578593}',p={},o=a('',13);p.render=function(a,t,p,e,c,l){return n(),s("div",null,[o])};export default p;export{t as __pageData}; diff --git a/assets/other_faq.md.f27f546c.js b/assets/other_faq.md.f27f546c.js new file mode 100644 index 00000000..1b64b3b2 --- /dev/null +++ b/assets/other_faq.md.f27f546c.js @@ -0,0 +1 @@ +import{o as a,c as n,a as s}from"./app.8cddb23b.js";const e='{"title":"常见问题","description":"","frontmatter":{},"headers":[{"level":2,"title":"前言","slug":"前言"},{"level":2,"title":"关于缓存更新问题","slug":"关于缓存更新问题"},{"level":2,"title":"关于修改配置文件的问题","slug":"关于修改配置文件的问题"},{"level":2,"title":"esbuild 模式下开启 LEGACY 打包失败","slug":"esbuild-模式下开启-legacy-打包失败"},{"level":2,"title":"ant-design-vue 控制台警告","slug":"ant-design-vue-控制台警告"},{"level":2,"title":"添加菜单后没显示","slug":"添加菜单后没显示"},{"level":2,"title":"本地运行报错","slug":"本地运行报错"},{"level":2,"title":"tab 页切换后页面空白","slug":"tab-页切换后页面空白"},{"level":2,"title":"组件命名问题","slug":"组件命名问题"},{"level":2,"title":"我的代码本地开发可以,打包就不行了","slug":"我的代码本地开发可以,打包就不行了"},{"level":2,"title":"safari 问题","slug":"safari-问题"},{"level":2,"title":"模版区别","slug":"模版区别"},{"level":2,"title":"环境问题","slug":"环境问题"},{"level":2,"title":"依赖安装问题","slug":"依赖安装问题"},{"level":2,"title":"如何保证我的代码能更新到最新代码","slug":"如何保证我的代码能更新到最新代码"},{"level":2,"title":"打包文件过大","slug":"打包文件过大"},{"level":2,"title":"运行错误","slug":"运行错误"},{"level":2,"title":"为什么是 moment.js","slug":"为什么是-moment-js"},{"level":2,"title":"控制台路由警告问题","slug":"控制台路由警告问题"},{"level":2,"title":"启动报错","slug":"启动报错"},{"level":2,"title":"页面报错","slug":"页面报错"},{"level":2,"title":"跨域问题","slug":"跨域问题"},{"level":2,"title":"接口请求问题","slug":"接口请求问题"},{"level":2,"title":"组件库问题","slug":"组件库问题"},{"level":2,"title":"动态调整菜单问题","slug":"动态调整菜单问题"},{"level":2,"title":"更灵活的菜单路由权限控制","slug":"更灵活的菜单路由权限控制"}],"relativePath":"other/faq.md","lastUpdated":1697592578593}',t={},o=s('

常见问题

TIP

列举了一些常见的问题。有问题可以先来这里寻找,如果没有可以在 issue 提。

前言

遇到问题,可以先从以下几个方面查找

  1. 对应模块的 GitHub 仓库 issue 搜索
  2. google搜索问题
  3. 百度搜索问题
  4. 在下面列表找不到问题可以到 issue 提问 issues
  5. 如果不是问题类型的,需要讨论的,请到 discussions 讨论

关于缓存更新问题

vben-admin 的项目配置默认是缓存在 localStorage 内,所以版本更新后可能有些配置没改变。

解决方式是每次更新代码的时候修改 package.json 内的 version 版本号. 因为 localStorage 的 key 是根据版本号来的。所以更新后版本不同前面的配置会失效。重新登录即可

VUE_VBEN_ADMIN__DEVELOPMENT__2.0.3__COMMON__LOCAL__KEY__ key 的组成是 [项目名]+[开发环境]+[版本号]+[key]

关于修改配置文件的问题

当修改 .env 等环境文件及 vite.config.ts 文件时,vite 会自动重启服务。

自动重启有几率出现问题,请重新运行项目即可解决.

esbuild 模式下开启 LEGACY 打包失败

如果将 \b build.minify 设置为 'esbuild',且不能启用 LEGACY,否则打包将会报错,两者选其一即可打包。

ant-design-vue 控制台警告

在控制台看到以下警告的原因是 ant-design-vue 会检测是否使用了 babel-plugin-import 来判断是否进行了组件库的按需引入。

但是项目使用的是 vite 的插件 vite-plugin-style-import 来进行按需引入。在 vite 内没必要使用 babel 在转换一次代码了。

所以想关闭这个警告,得等 ant-design-vue 提供可以关闭该警告的配置。

You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size. Not support Vite !!!\n

添加菜单后没显示

菜单必须和路由匹配才会显示在界面上,所以得确保菜单和对应的路由存在即可显示.

本地运行报错

由于 vite 在本地没有转换代码,且代码中用到了可选链等比较新的语法。所以本地开发需要使用版本较高的浏览器(Chrome 85+)进行开发

tab 页切换后页面空白

这是由于开启了路由切换动画,且对应的页面组件存在多个根节点导致的,在页面最外层添加<div></div>即可

错误示例

<template>\n  <!-- 注释也算一个节点 -->\n  <h1>text h1</h1>\n  <h2>text h2</h2>\n</template>\n

正确示例

<template>\n  <div>\n    <h1>text h1</h1>\n    <h2>text h2</h2>\n  </div>\n</template>\n

提示

  • 如果想使用多个根标签,可以禁用路由切换动画
  • template 下面的根注释节点也算一个节点

组件命名问题

目前在 vite+vue3.0.5 版本中,如果组件命名携带关键字,则可能会导致内存溢出。例如 ImportExcel excel 导入组件。

我的代码本地开发可以,打包就不行了

目前发现这个原因可能有以下,可以从以下原因来排查,如果还有别的可能,可以提交 pr 来告诉我

  1. 使用了 ctx 这个变量,ctx 本身未暴露出在实例类型内,尤大也是说了不要用这个属性。这个属性只是用于内部使用。
import { getCurrentInstance } from 'vue';\ngetCurrentInstance().ctx.xxxx;\n

safari 问题

目前在 safari 上面本地开发运行样式会有问题,还未找到原因,有知道的也可以告诉我。

模版区别

  • Vue-Vben-Admin - 是包含 Demo 示例的,个人建议不要在这上面进行开发。当然,你如果动手能力强的话可以直接改。
  • Vue-Vben-Admin-Thin-Next 精简了代码后的模版项目。适合在这基础上进行二次开发。

环境问题

如果出现依赖安装报错,启动报错等。先检查电脑环境有没有安装齐全。

  • Node 版本必须大于12.0.0不支持 13, 推荐 14 版本。
  • Git
  • Yarn 最新版

依赖安装问题

  • 如果依赖安装不了或者启动报错可以先尝试 删除 yarn.locknode_modules,然后重新运行 yarn install
  • 如果依赖安装不了或者报错,可以尝试切换手机热点来进行依赖安装。
  • 如果还是不行,可以自行配置国内镜像安装。
  • 也可以在项目根目录创建 .npmrc 文件,内容如下
# .npmrc\nregistry = https://registry.npm.taobao.org\n

然后重新执行yarn run reinstall等待安装完成即可

如何保证我的代码能更新到最新代码

如果你使用了该项目进行项目开发。开发之中想同步最新的代码。你可以设置多个源的方式

  1. 克隆代码
git clone https://github.com/vbenjs/vben-admin-thin-next.git\n
  1. 添加自己的公司 git 源地址
# up 为源名称,可以随意设置\n# gitUrl为开源最新代码\ngit remote add up gitUrl;\n
  1. 提交代码到自己公司 git
# 提交代码到自己公司\n# main为分支名 需要自行根据情况修改\ngit push up main\n\n# 同步公司的代码\n# main为分支名 需要自行根据情况修改\ngit pull up main\n
  1. 如何同步开源最新代码
git pull origin main\n

TIP

同步代码的时候会出现冲突。只需要把冲突解决即可

打包文件过大

  • 首先,完整版由于引用了比较多的库文件,所以打包会比较大。可以使用精简版来进行开发

  • 其次建议开启 gzip,使用之后体积会只有原先 1/3 左右。

gzip 可以由服务器直接开启。如果是这样,前端不需要构建 .gz 格式的文件

如果前端构建了 .gz 文件,以 nginx 为例,nginx 需要开启 gzip_static: on 这个选项。

  • 开启 gzip 的同时还可以同时开启 brotli,比 gzip 更好的压缩。两者可以共存

注意

  • gzip_static: 这个模块需要 nginx 另外安装,默认的 nginx 没有安装这个模块。

  • 开启 brotli 也需要 nginx 另外安装模块

运行错误

如果出现类似以下错误,请检查项目全路径(包含所有父级路径)不能出现中文、日文、韩文。否则将会出现路径访问 404 导致以下问题

[vite] Failed to resolve module import "ant-design-vue/dist/antd.css-vben-adminode_modulesant-design-vuedistantd.css". (imported by /@/setup/ant-design-vue/index.ts)\n

为什么是 moment.js

很多人问为什么不用dayjs。在项目依赖中可以看到,它是 Ant-Design-Vue 内部自带的。

目前还没有基于 Vite 的 dayjs 替换 momentjs 方案,webpack 已经有了。等以后出现了在进行替换。

控制台路由警告问题

如果看到控制台有如下警告,且页面能正常打开 可以忽略该警告。

后续 vue-router 可能会提供配置项来关闭警告

2.6.1 及以上版本已移除此警告

[Vue Router warn]: No match found for location with path "xxxx"\n

启动报错

当出现以下错误信息时,请检查你的 nodejs 版本号是否符合要求

TypeError: str.matchAll is not a function\nat Object.extractor (vue-vben-admin-main\\node_modules@purge-icons\\core\\dist\\index.js:146:27)\nat Extract (vue-vben-admin-main\\node_modules@purge-icons\\core\\dist\\index.js:173:54)\n\n

页面报错

当页面出现以下报错,是因为 /xxx 对应的路由组件内部出现了错误。

 Uncaught (in promise) Error: Couldn't resolve component "default" at "/xxx"\n\n

可以尝试从以下几点排查

  1. 检查对应组件内部 import 的所有文件是否正确
  2. 检查引入方式是否错误。
// 正确的\nimport { cloneDeep } from 'lodash-es';\n\n// 报错\nimport _ from 'lodash-es';\n
  1. 检查样式是否使用变量及有没有引入对应的变量文件
  2. 检查代码明显的语法错误

这样就不会是使用的取值忘记 xxx.value 来进行数据获取

跨域问题

参考跨域问题

接口请求问题

proxy 代理不成功,没有代理到实际地址?

代理只是服务请求代理,这个地址是不会变的。 原理可以简单的理解为,在本地启了一个服务,你先请求了本地的服务,本地的服务转发了你的请求到实际服务器。所以你在浏览器上看到的请求地址还是 http://localhost:8000/xxx。以服务端是否收到请求为准。

组件库问题

跟组件库相关的问题可以查看常见问题

动态调整菜单问题

菜单数据的值被存放在 store/modules/permission store 中, 你可以在这里进行修改

更灵活的菜单路由权限控制

你可以在 store/modules/permission下, 修改 routeFilter 方法来进行更灵活的菜单路由权限控制

 const routeFilter = (route: AppRouteRecordRaw) => {\n    const { meta } = route;\n    // 抽出角色\n    const { roles } = meta || {};\n\n    // 添加你的自定义逻辑来过滤路由和菜单\n    if (xxx) {\n      return false;\n    }\n\n    if (!roles) return true;\n    // 进行角色权限判断\n    return roleList.some((role) => roles.includes(role));\n  };\n\n
',99);t.render=function(s,e,t,p,l,c){return a(),n("div",null,[o])};export default t;export{e as __pageData}; diff --git a/assets/other_faq.md.f27f546c.lean.js b/assets/other_faq.md.f27f546c.lean.js new file mode 100644 index 00000000..a6e18059 --- /dev/null +++ b/assets/other_faq.md.f27f546c.lean.js @@ -0,0 +1 @@ +import{o as a,c as n,a as s}from"./app.8cddb23b.js";const e='{"title":"常见问题","description":"","frontmatter":{},"headers":[{"level":2,"title":"前言","slug":"前言"},{"level":2,"title":"关于缓存更新问题","slug":"关于缓存更新问题"},{"level":2,"title":"关于修改配置文件的问题","slug":"关于修改配置文件的问题"},{"level":2,"title":"esbuild 模式下开启 LEGACY 打包失败","slug":"esbuild-模式下开启-legacy-打包失败"},{"level":2,"title":"ant-design-vue 控制台警告","slug":"ant-design-vue-控制台警告"},{"level":2,"title":"添加菜单后没显示","slug":"添加菜单后没显示"},{"level":2,"title":"本地运行报错","slug":"本地运行报错"},{"level":2,"title":"tab 页切换后页面空白","slug":"tab-页切换后页面空白"},{"level":2,"title":"组件命名问题","slug":"组件命名问题"},{"level":2,"title":"我的代码本地开发可以,打包就不行了","slug":"我的代码本地开发可以,打包就不行了"},{"level":2,"title":"safari 问题","slug":"safari-问题"},{"level":2,"title":"模版区别","slug":"模版区别"},{"level":2,"title":"环境问题","slug":"环境问题"},{"level":2,"title":"依赖安装问题","slug":"依赖安装问题"},{"level":2,"title":"如何保证我的代码能更新到最新代码","slug":"如何保证我的代码能更新到最新代码"},{"level":2,"title":"打包文件过大","slug":"打包文件过大"},{"level":2,"title":"运行错误","slug":"运行错误"},{"level":2,"title":"为什么是 moment.js","slug":"为什么是-moment-js"},{"level":2,"title":"控制台路由警告问题","slug":"控制台路由警告问题"},{"level":2,"title":"启动报错","slug":"启动报错"},{"level":2,"title":"页面报错","slug":"页面报错"},{"level":2,"title":"跨域问题","slug":"跨域问题"},{"level":2,"title":"接口请求问题","slug":"接口请求问题"},{"level":2,"title":"组件库问题","slug":"组件库问题"},{"level":2,"title":"动态调整菜单问题","slug":"动态调整菜单问题"},{"level":2,"title":"更灵活的菜单路由权限控制","slug":"更灵活的菜单路由权限控制"}],"relativePath":"other/faq.md","lastUpdated":1697592578593}',t={},o=s('',99);t.render=function(s,e,t,p,l,c){return a(),n("div",null,[o])};export default t;export{e as __pageData}; diff --git a/assets/other_project.md.dbd0bef8.js b/assets/other_project.md.dbd0bef8.js new file mode 100644 index 00000000..f8701e5f --- /dev/null +++ b/assets/other_project.md.dbd0bef8.js @@ -0,0 +1 @@ +import{o as e,c as r,a as t}from"./app.8cddb23b.js";const o='{"title":"相关项目","description":"","frontmatter":{},"headers":[{"level":2,"title":"golang","slug":"golang"},{"level":2,"title":"php","slug":"php"},{"level":2,"title":"java","slug":"java"},{"level":2,"title":".net","slug":"net"}],"relativePath":"other/project.md","lastUpdated":1697592578593}',n={},a=t('

相关项目

对接vben的项目地址,非官方项目,vben用户开源,开源协议请自行查看

golang

  1. 后端https://github.com/vbenjs/gf-vben 前端https://github.com/vbenjs/gf-vben-admin

php

  1. 后端https://github.com/Joyboo/Joyboo-admin-easyswoole 前端https://github.com/Joyboo/Joyboo-vben-admin-thin
  2. 后端: https://github.com/wcz0/laravel-vben 前端: https://github.com/wcz0/laravel-vben-admin

java

  1. 后端SpringCloudhttps://github.com/zuihou/lamp-cloud 后端SpringBoothttps://github.com/zuihou/lamp-boot 前端https://github.com/zuihou/lamp-web-plus
  2. 后端https://gitee.com/skysong/coffee-boot
  3. 后端https://gitee.com/battcn/wemirr-platform 前端https://gitee.com/battcn/wemirr-platform-ui
  4. 后端https://gitee.com/zsvg/vboot-java 前端https://gitee.com/zsvg/vboot-vben
  5. 后端SpringBoothttps://github.com/uncarbon97/helio-boot 后端SpringCloudhttps://github.com/uncarbon97/helio-cloud 前端https://github.com/uncarbon97/helio-admin-vue-vben
  6. 后端SpringBoothttps://gitee.com/zhijiantianya/ruoyi-vue-pro 后端SpringCloudhttps://gitee.com/zhijiantianya/yudao-cloud 前端https://gitee.com/yudaocode/yudao-ui-admin-vben

.net

  1. 对接Osharp 前端https://github.com/zionLZH/osharp-vben-admin
  2. 后端https://gitee.com/zsvg/vboot-net 前端https://gitee.com/zsvg/vboot-vben
  3. Admin.NET 源码地址https://gitee.com/zuohuaijun/Admin.NET
',10);n.render=function(t,o,n,i,h,g){return e(),r("div",null,[a])};export default n;export{o as __pageData}; diff --git a/assets/other_project.md.dbd0bef8.lean.js b/assets/other_project.md.dbd0bef8.lean.js new file mode 100644 index 00000000..31223e16 --- /dev/null +++ b/assets/other_project.md.dbd0bef8.lean.js @@ -0,0 +1 @@ +import{o as e,c as r,a as t}from"./app.8cddb23b.js";const o='{"title":"相关项目","description":"","frontmatter":{},"headers":[{"level":2,"title":"golang","slug":"golang"},{"level":2,"title":"php","slug":"php"},{"level":2,"title":"java","slug":"java"},{"level":2,"title":".net","slug":"net"}],"relativePath":"other/project.md","lastUpdated":1697592578593}',n={},a=t('',10);n.render=function(t,o,n,i,h,g){return e(),r("div",null,[a])};export default n;export{o as __pageData}; diff --git a/assets/other_server.md.0ae59f36.js b/assets/other_server.md.0ae59f36.js new file mode 100644 index 00000000..e1483813 --- /dev/null +++ b/assets/other_server.md.0ae59f36.js @@ -0,0 +1 @@ +import{o as e,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"测试服务器","description":"","frontmatter":{},"headers":[{"level":2,"title":"使用","slug":"使用"}],"relativePath":"other/server.md","lastUpdated":1697592578593}',t={},r=n('

测试服务器

在项目 /test/server 内有简单的 Node.js 测试后台接口服务,用 Koa2 实现

使用

\ncd ./test/server\n\n# 安装依赖\nyarn\n\n# 运行服务\nyarn start\n\n

服务运行成功之后,就可以访问测试上传接口及 websocket 接口服务

',5);t.render=function(n,s,t,o,c,d){return e(),a("div",null,[r])};export default t;export{s as __pageData}; diff --git a/assets/other_server.md.0ae59f36.lean.js b/assets/other_server.md.0ae59f36.lean.js new file mode 100644 index 00000000..1bbfc25a --- /dev/null +++ b/assets/other_server.md.0ae59f36.lean.js @@ -0,0 +1 @@ +import{o as e,c as a,a as n}from"./app.8cddb23b.js";const s='{"title":"测试服务器","description":"","frontmatter":{},"headers":[{"level":2,"title":"使用","slug":"使用"}],"relativePath":"other/server.md","lastUpdated":1697592578593}',t={},r=n('',5);t.render=function(n,s,t,o,c,d){return e(),a("div",null,[r])};export default t;export{s as __pageData}; diff --git a/assets/style.84beecbd.css b/assets/style.84beecbd.css new file mode 100644 index 00000000..7927bb18 --- /dev/null +++ b/assets/style.84beecbd.css @@ -0,0 +1 @@ +:root{--c-white:#ffffff;--c-white-dark:#f8f8f8;--c-black:#000000;--c-divider-light:rgba(60, 60, 67, 0.12);--c-divider-dark:rgba(84, 84, 88, 0.48);--c-text-light-1:#2c3e50;--c-text-light-2:#476582;--c-text-light-3:#90a4b7;--c-brand:#3eaf7c;--c-brand-light:#4abf8a;--font-family-base:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Fira Sans','Droid Sans','Helvetica Neue',sans-serif;--font-family-mono:source-code-pro,Menlo,Monaco,Consolas,'Courier New',monospace;--z-index-navbar:10;--z-index-sidebar:6;--shadow-1:0 1px 2px rgba(0, 0, 0, 0.04),0 1px 2px rgba(0, 0, 0, 0.06);--shadow-2:0 3px 12px rgba(0, 0, 0, 0.07),0 1px 4px rgba(0, 0, 0, 0.07);--shadow-3:0 12px 32px rgba(0, 0, 0, 0.1),0 2px 6px rgba(0, 0, 0, 0.08);--shadow-4:0 14px 44px rgba(0, 0, 0, 0.12),0 3px 9px rgba(0, 0, 0, 0.12);--shadow-5:0 18px 56px rgba(0, 0, 0, 0.16),0 4px 12px rgba(0, 0, 0, 0.16);--header-height:3.6rem;--c-divider:var(--c-divider-light);--c-text:var(--c-text-light-1);--c-text-light:var(--c-text-light-2);--c-text-lighter:var(--c-text-light-3);--c-bg:var(--c-white);--c-bg-accent:var(--c-white-dark);--code-line-height:24px;--code-font-family:var(--font-family-mono);--code-font-size:14px;--code-inline-bg-color:rgba(27, 31, 35, 0.05);--code-bg-color:#282c34}*,::after,::before{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:1.4;font-family:var(--font-family-base);font-size:16px;font-weight:400;color:var(--c-text);background-color:var(--c-bg);direction:ltr;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:1.25}b,h1,h2,h3,h4,h5,h6,strong{font-weight:600}h1:focus .header-anchor,h1:hover .header-anchor,h2:focus .header-anchor,h2:hover .header-anchor,h3:focus .header-anchor,h3:hover .header-anchor,h4:focus .header-anchor,h4:hover .header-anchor,h5:focus .header-anchor,h5:hover .header-anchor,h6:focus .header-anchor,h6:hover .header-anchor{opacity:1}h1{margin-top:1.5rem;font-size:1.9rem}@media screen and (min-width:420px){h1{font-size:2.2rem}}h2{margin-top:2.25rem;margin-bottom:1.25rem;border-bottom:1px solid var(--c-divider);padding-bottom:.3rem;line-height:1.25;font-size:1.65rem}h2+h3{margin-top:1.5rem}h3{margin-top:2rem;font-size:1.35rem}h4{font-size:1.15rem}ol,p,ul{margin:1rem 0;line-height:1.7}[role=button],a,area,button,input,label,select,summary,textarea{touch-action:manipulation}a{text-decoration:none;color:var(--c-brand)}a:hover{text-decoration:underline}a.header-anchor{float:left;margin-top:.125em;margin-left:-.87em;padding-right:.23em;font-size:.85em;opacity:0}a.header-anchor:focus,a.header-anchor:hover{text-decoration:none}figure{margin:0}img{max-width:100%}ol,ul{padding-left:1.25em}li>ol,li>ul{margin:0}table{display:block;border-collapse:collapse;margin:1rem 0;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}blockquote{margin:1rem 0;border-left:.2rem solid #dfe2e5;padding:.25rem 0 .25rem 1rem;font-size:1rem;color:#999}blockquote>p{margin:0}form{margin:0}.theme.sidebar-open .sidebar-mask{display:block}.theme.no-navbar>h1,.theme.no-navbar>h2,.theme.no-navbar>h3,.theme.no-navbar>h4,.theme.no-navbar>h5,.theme.no-navbar>h6{margin-top:1.5rem;padding-top:0}.theme.no-navbar aside{top:0}@media screen and (min-width:720px){.theme.no-sidebar aside{display:none}.theme.no-sidebar main{margin-left:0}}.sidebar-mask{position:fixed;z-index:2;display:none;width:100vw;height:100vh}code{margin:0;border-radius:3px;padding:.25rem .5rem;font-family:var(--code-font-family);font-size:.85em;color:var(--c-text-light);background-color:var(--code-inline-bg-color)}code .token.deleted{color:#ec5975}code .token.inserted{color:var(--c-brand)}div[class*=language-]{position:relative;margin:1rem -1.5rem;background-color:var(--code-bg-color);overflow-x:auto}li>div[class*=language-]{border-radius:6px 0 0 6px;margin:1rem -1.5rem 1rem -1.25rem}@media (min-width:420px){div[class*=language-]{margin:1rem 0;border-radius:6px}li>div[class*=language-]{margin:1rem 0 1rem 0;border-radius:6px}}[class*=language-] code,[class*=language-] pre{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}[class*=language-] pre{position:relative;z-index:1;margin:0;padding:1.25rem 1.5rem;background:0 0;overflow-x:auto}[class*=language-] code{padding:0;line-height:var(--code-line-height);font-size:var(--code-font-size);color:#eee}.highlight-lines{position:absolute;top:0;bottom:0;left:0;padding:1.25rem 0;width:100%;line-height:var(--code-line-height);font-family:var(--code-font-family);font-size:var(--code-font-size);user-select:none;overflow:hidden}.highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode{padding-left:3.5rem}.line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid rgba(0,0,0,.5);padding:1.25rem 0;width:3.5rem;text-align:center;line-height:var(--code-line-height);font-family:var(--code-font-family);font-size:var(--code-font-size);color:#888}[class*=language-]:before{position:absolute;top:.6em;right:1em;z-index:2;font-size:.8rem;color:#888}[class~=language-html]:before,[class~=language-markup]:before{content:'html'}[class~=language-markdown]:before,[class~=language-md]:before{content:'md'}[class~=language-css]:before{content:'css'}[class~=language-sass]:before{content:'sass'}[class~=language-scss]:before{content:'scss'}[class~=language-less]:before{content:'less'}[class~=language-stylus]:before{content:'styl'}[class~=language-javascript]:before,[class~=language-js]:before{content:'js'}[class~=language-ts]:before,[class~=language-typescript]:before{content:'ts'}[class~=language-json]:before{content:'json'}[class~=language-rb]:before,[class~=language-ruby]:before{content:'rb'}[class~=language-py]:before,[class~=language-python]:before{content:'py'}[class~=language-bash]:before,[class~=language-sh]:before{content:'sh'}[class~=language-php]:before{content:'php'}[class~=language-go]:before{content:'go'}[class~=language-rust]:before{content:'rust'}[class~=language-java]:before{content:'java'}[class~=language-c]:before{content:'c'}[class~=language-yaml]:before{content:'yaml'}[class~=language-dockerfile]:before{content:'dockerfile'}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}.custom-block.danger,.custom-block.tip,.custom-block.warning{margin:1rem 0;border-left:.5rem solid;padding:.1rem 1.5rem;overflow-x:auto}.custom-block.tip{background-color:#f3f5f7;border-color:var(--c-brand)}.custom-block.warning{border-color:#e7c000;color:#6b5900;background-color:rgba(255,229,100,.3)}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:var(--c-text)}.custom-block.danger{border-color:#c00;color:#4d0000;background-color:#ffe6e6}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:var(--c-text)}.custom-block.details{position:relative;display:block;border-radius:2px;margin:1.6em 0;padding:1.6em;background-color:#eee}.custom-block.details h4{margin-top:0}.custom-block.details figure:last-child,.custom-block.details p:last-child{margin-bottom:0;padding-bottom:0}.custom-block.details summary{outline:0;cursor:pointer}.custom-block-title{margin-bottom:-.4rem;font-weight:600}.sidebar-links{margin:0;padding:0;list-style:none}.sidebar-link-item{display:block;margin:0;border-left:.25rem solid transparent;color:var(--c-text)}a.sidebar-link-item:hover{text-decoration:none;color:var(--c-brand)}a.sidebar-link-item.active{color:var(--c-brand)}.sidebar>.sidebar-links{padding:.75rem 0 5rem}@media (min-width:720px){.sidebar>.sidebar-links{padding:1.5rem 0}}.sidebar>.sidebar-links>.sidebar-link+.sidebar-link{padding-top:.5rem}@media (min-width:720px){.sidebar>.sidebar-links>.sidebar-link+.sidebar-link{padding-top:1.25rem}}.sidebar>.sidebar-links>.sidebar-link>.sidebar-link-item{padding:.35rem 1.5rem .35rem 1.25rem;font-size:1.1rem;font-weight:700}.sidebar>.sidebar-links>.sidebar-link>a.sidebar-link-item.active{border-left-color:var(--c-brand);font-weight:600}.sidebar>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-link-item{display:block;padding:.35rem 1.5rem .35rem 2rem;line-height:1.4;font-size:1rem;font-weight:400}.sidebar>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>a.sidebar-link-item.active{border-left-color:var(--c-brand);font-weight:600}.sidebar>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-link-item{display:block;padding:.3rem 1.5rem .3rem 3rem;line-height:1.4;font-size:.9rem;font-weight:400}.sidebar>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-links>.sidebar-link>.sidebar-link-item{display:block;padding:.3rem 1.5rem .3rem 4rem;line-height:1.4;font-size:.9rem;font-weight:400}.debug[data-v-1be840de]{box-sizing:border-box;position:fixed;right:8px;bottom:8px;z-index:9999;border-radius:4px;width:74px;height:32px;color:#eee;overflow:hidden;cursor:pointer;background-color:rgba(0,0,0,.85);transition:all .15s ease}.debug[data-v-1be840de]:hover{background-color:rgba(0,0,0,.75)}.debug.open[data-v-1be840de]{right:0;bottom:0;width:100%;height:100%;margin-top:0;border-radius:0;padding:0 0;overflow:scroll}@media (min-width:512px){.debug.open[data-v-1be840de]{width:512px}}.debug.open[data-v-1be840de]:hover{background-color:rgba(0,0,0,.85)}.title[data-v-1be840de]{margin:0;padding:6px 16px 6px;line-height:20px;font-size:13px}.block[data-v-1be840de]{margin:2px 0 0;border-top:1px solid rgba(255,255,255,.16);padding:8px 16px;font-family:Hack,monospace;font-size:13px}.block+.block[data-v-1be840de]{margin-top:8px}.nav-bar-title[data-v-ffb90d4a]{font-size:1.3rem;font-weight:600;color:var(--c-text)}.nav-bar-title[data-v-ffb90d4a]:hover{text-decoration:none}.logo[data-v-ffb90d4a]{margin-right:.75rem;height:1.3rem;vertical-align:bottom}.icon.outbound{position:relative;top:-1px;display:inline-block;vertical-align:middle;color:var(--c-text-lighter)}.item[data-v-c272f228]{display:block;padding:0 1.5rem;line-height:36px;font-size:1rem;font-weight:600;color:var(--c-text);white-space:nowrap}.item.active[data-v-c272f228],.item[data-v-c272f228]:hover{text-decoration:none;color:var(--c-brand)}.item.external[data-v-c272f228]:hover{border-bottom-color:transparent;color:var(--c-text)}@media (min-width:720px){.item[data-v-c272f228]{border-bottom:2px solid transparent;padding:0;line-height:24px;font-size:.9rem;font-weight:500}.item.active[data-v-c272f228],.item[data-v-c272f228]:hover{border-bottom-color:var(--c-brand);color:var(--c-text)}}.item[data-v-7b16fcd4]{display:block;padding:0 1.5rem 0 2.5rem;line-height:32px;font-size:.9rem;font-weight:500;color:var(--c-text);white-space:nowrap}@media (min-width:720px){.item[data-v-7b16fcd4]{padding:0 24px 0 12px;line-height:32px;font-size:.85rem;font-weight:500;color:var(--c-text);white-space:nowrap}.item.active .arrow[data-v-7b16fcd4]{opacity:1}}.item.active[data-v-7b16fcd4],.item[data-v-7b16fcd4]:hover{text-decoration:none;color:var(--c-brand)}.item.external[data-v-7b16fcd4]:hover{border-bottom-color:transparent;color:var(--c-text)}@media (min-width:720px){.arrow[data-v-7b16fcd4]{display:inline-block;margin-right:8px;border-top:6px solid #ccc;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent;vertical-align:middle;opacity:0;transform:translateY(-2px) rotate(-90deg)}}.nav-dropdown-link[data-v-312de885]{position:relative;height:36px;overflow:hidden;cursor:pointer}@media (min-width:720px){.nav-dropdown-link[data-v-312de885]{height:auto;overflow:visible}.nav-dropdown-link:hover .dialog[data-v-312de885]{display:block}}.nav-dropdown-link.open[data-v-312de885]{height:auto}.button[data-v-312de885]{display:block;border:0;padding:0 1.5rem;width:100%;text-align:left;line-height:36px;font-family:var(--font-family-base);font-size:1rem;font-weight:600;color:var(--c-text);white-space:nowrap;background-color:transparent;cursor:pointer}.button[data-v-312de885]:focus{outline:0}@media (min-width:720px){.button[data-v-312de885]{border-bottom:2px solid transparent;padding:0;line-height:24px;font-size:.9rem;font-weight:500}}.button-arrow[data-v-312de885]{display:inline-block;margin-top:-1px;margin-left:8px;border-top:6px solid #ccc;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent;vertical-align:middle}.button-arrow.right[data-v-312de885]{transform:rotate(-90deg)}@media (min-width:720px){.button-arrow.right[data-v-312de885]{transform:rotate(0)}}.dialog[data-v-312de885]{margin:0;padding:0;list-style:none}@media (min-width:720px){.dialog[data-v-312de885]{display:none;position:absolute;top:26px;right:-8px;border-radius:6px;padding:12px 0;min-width:128px;background-color:var(--c-bg);box-shadow:var(--shadow-3)}}.nav-links[data-v-1e870408]{padding:.75rem 0;border-bottom:1px solid var(--c-divider)}@media (min-width:720px){.nav-links[data-v-1e870408]{display:flex;padding:6px 0 0;align-items:center;border-bottom:0}.item+.item[data-v-1e870408]{padding-left:24px}}.sidebar-button{position:absolute;top:.6rem;left:1rem;display:none;padding:.6rem;cursor:pointer}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media screen and (max-width:719px){.sidebar-button{display:block}}.nav-bar[data-v-2332dbaa]{position:fixed;top:0;right:0;left:0;z-index:var(--z-index-navbar);display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--c-divider);padding:.7rem 1.5rem .7rem 4rem;height:var(--header-height);background-color:var(--c-bg)}@media (min-width:720px){.nav-bar[data-v-2332dbaa]{padding:.7rem 1.5rem}}.flex-grow[data-v-2332dbaa]{flex-grow:1}.nav[data-v-2332dbaa]{display:none}@media (min-width:720px){.nav[data-v-2332dbaa]{display:flex}.navbar__dark-mode[data-v-2332dbaa]{display:none}}.nav-icons[data-v-2332dbaa]{display:flex;padding:2px 0 0;align-items:center;border-bottom:0;margin-left:12px}.nav-icons .item[data-v-2332dbaa]{padding-left:12px}.sidebar[data-v-4668b452]{position:fixed;top:var(--header-height);bottom:0;left:0;z-index:var(--z-index-sidebar);border-right:1px solid var(--c-divider);width:16.4rem;background-color:var(--c-bg);overflow-y:auto;transform:translateX(-100%);transition:transform .25s ease}@media (min-width:720px){.sidebar[data-v-4668b452]{transform:translateX(0)}}@media (min-width:960px){.sidebar[data-v-4668b452]{width:20rem}}.sidebar.open[data-v-4668b452]{transform:translateX(0)}.nav[data-v-4668b452]{display:block}@media (min-width:720px){.nav[data-v-4668b452]{display:none}}.link[data-v-045573c2]{display:inline-block;font-size:1rem;font-weight:500;color:var(--c-text-light)}.link[data-v-045573c2]:hover{text-decoration:none;color:var(--c-brand)}.icon[data-v-045573c2]{margin-left:4px}.last-updated[data-v-03e55a27]{display:inline-block;margin:0;line-height:1.4;font-size:.9rem;color:var(--c-text-light)}@media (min-width:960px){.last-updated[data-v-03e55a27]{font-size:1rem}}.prefix[data-v-03e55a27]{display:inline-block;font-weight:500}.datetime[data-v-03e55a27]{display:inline-block;margin-left:6px;font-weight:400}.page-footer[data-v-22e60b1a]{padding-top:1rem;padding-bottom:1rem;overflow:auto}@media (min-width:960px){.page-footer[data-v-22e60b1a]{display:flex;justify-content:space-between;align-items:center}}.updated[data-v-22e60b1a]{padding-top:4px}@media (min-width:960px){.updated[data-v-22e60b1a]{padding-top:0}}.next-and-prev-link[data-v-0facf926]{padding-top:1rem}.container[data-v-0facf926]{display:flex;justify-content:space-between;border-top:1px solid var(--c-divider);padding-top:1rem}.next[data-v-0facf926],.prev[data-v-0facf926]{display:flex;flex-shrink:0;width:50%}.prev[data-v-0facf926]{justify-content:flex-start;padding-right:12px}.next[data-v-0facf926]{justify-content:flex-end;padding-left:12px}.link[data-v-0facf926]{display:inline-flex;align-items:center;max-width:100%;font-size:1rem;font-weight:500}.text[data-v-0facf926]{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.icon[data-v-0facf926]{display:block;flex-shrink:0;width:16px;height:16px;fill:var(--c-text);transform:translateY(1px)}.icon-prev[data-v-0facf926]{margin-right:8px}.icon-next[data-v-0facf926]{margin-left:8px}.page[data-v-7abc59e6]{padding-top:var(--header-height)}@media (min-width:720px){.page[data-v-7abc59e6]{margin-left:16.4rem}}@media (min-width:960px){.page[data-v-7abc59e6]{margin-left:20rem}}.container[data-v-7abc59e6]{margin:0 auto;padding:0 1.5rem 4rem;padding:.025rem 0 2rem 0;width:calc(100% - var(--slug-width))}.content[data-v-7abc59e6]{padding-bottom:1.5rem}@media (max-width:420px){.content[data-v-7abc59e6]{clear:both}}#ads-container{margin:0 auto}@media (min-width:420px){#ads-container{position:relative;right:0;float:right;margin:-8px -8px 24px 24px;width:146px}}@media (max-width:420px){#ads-container{height:105px;margin:1.75rem 0}}@media (min-width:1400px){#ads-container{position:fixed;right:8px;bottom:8px}}.border{border-width:1px}.flex{display:-webkit-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:-webkit-inline-flex;display:inline-flex}.table{display:table}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.h-full{height:100%}.text-color-base{font-size:1rem;line-height:1.5rem}.m-3{margin:.75rem}.m-4{margin:1rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mt-4{margin-top:1rem}.mr-4{margin-right:1rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-4{margin-left:1rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-10{padding:2.5rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.px-4{padding-left:1rem;padding-right:1rem}.absolute{position:absolute}.relative{position:relative}.content{content:""}.w-full{width:100%}.transition{-webkit-transition-property:background-color,border-color,color,fill,stroke,opacity,-webkit-box-shadow,-webkit-transform,filter,backdrop-filter;-o-transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,-webkit-box-shadow,transform,-webkit-transform,filter,backdrop-filter;-webkit-transition-timing-function:cubic-bezier(.4,0,.2,1);-o-transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-transition-duration:150ms;-o-transition-duration:150ms;transition-duration:150ms}[duration~="8000"]{-webkit-transition-duration:8s;-o-transition-duration:8s;transition-duration:8s}:root{--c-brand:#4569d4;--c-brand-light:#4f73dd;--c-white-dark:#f8f8f8;--c-black:#111827;--c-black-light:#161f32;--c-black-lighter:#262a44;--c-text-dark-1:#d9e6eb;--c-text-dark-2:#c4dde6;--c-text-dark-3:#abc4cc;--c-brand-text:var(--c-white);--c-bg-accent:var(--c-white-dark);--code-bg-color:var(--c-white-dark);--code-inline-bg-color:var(--c-white-dark);--code-font-family:'dm',source-code-pro,Menlo,Monaco,Consolas,'Courier New',monospace;--code-font-size:16px;--slug-width:10rem;--header-height:3.6rem;--sidebar-width:16.4rem}html:not(.light):root{--c-text:var(--c-text-dark-1);--c-text-light:var(--c-text-dark-2);--c-text-lighter:var(--c-text-dark-3);--c-divider:var(--c-divider-dark);--c-bg:var(--c-black);--c-bg-accent:var(--c-black-light);--code-bg-color:var(--c-black-light);--code-inline-bg-color:var(--c-black-light)}html:not(.light) .DocSearch{--docsearch-text-color:var(--c-white-dark);--docsearch-container-background:rgba(9, 10, 17, 0.8);--docsearch-modal-background:var(--c-black);--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:var(--c-black-lighter);--docsearch-searchbox-focus-background:var(--c-black-light);--docsearch-hit-color:var(--c-text-dark-1);--docsearch-hit-active-color:var(--c-brand-text);--docsearch-hit-shadow:none;--docsearch-hit-background:var(--c-black-light);--docsearch-key-gradient:linear-gradient(-26.5deg, #565872, #31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3, 4, 9, 0.3);--docsearch-footer-background:var(--c-black-light);--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73, 76, 106, 0.5),0 -4px 8px 0 rgba(0, 0, 0, 0.2);--docsearch-logo-color:var(--c-white-dark);--docsearch-muted-color:var(--c-text-dark-1)}.home-hero .image{width:100px;height:100px}.nav-bar .logo{height:26px;margin-right:8px}.nav-bar .nav-bar-title{display:flex;align-items:center}.content img{border-radius:10px}.nav-dropdown-link-item .icon{display:none}.action.alt .icon.outbound{color:currentColor}.action .item.item.item{border-color:var(--c-brand);background-color:var(--c-brand)}.action.alt .item.item.item{background-color:transparent;color:var(--c-text);border-color:var(--c-brand);transition:background-color 150ms ease-in-out,border-color 150ms ease-in-out,color 150ms ease-in-out}.action .item.item.item,.action .item.item.item:hover{color:var(--c-brand-text)}html.dark .action.alt .item.item.item{border-color:var(--c-text)}.action.alt .item.item.item:hover{background-color:var(--c-brand-light);border-color:var(--c-brand-light);color:var(--c-brand-text)}.nav-bar.nav-bar{background-color:var(--c-bg)}.custom-block.tip{border-color:var(--c-brand-light);background-color:var(--c-bg-accent)}.carbon-ads{padding:8px}.bsa-cpc,.carbon-ads{background-color:var(--c-bg-accent)!important}html:not(.light) .custom-block.warning{color:var(--c-text)}html:not(.light) .custom-block.warning a{color:var(--c-brand)}.action.alt .item.item,.bsa-cpc,.carbon-ads,.custom-block.tip,.nav-bar,body,code,div[class*=language-]{transition:background-color .3s ease-in-out,color .3s ease-in-out}.DocSearch,.DocSearch-Form,.DocSearch-Search-Icon,.sidebar.sidebar.sidebar{transition:transform 250ms ease,background-color .3s ease-in-out,color .3s ease-in-out}.DocSearch-Button-Key,.DocSearch-Footer,.DocSearch-Modal{transition:background-color .3s ease-in-out,color .3s ease-in-out,box-shadow 250ms ease-in-out}code{font-size:.95em;padding:.175em .35em}input{border:1px solid #d9d9d9;padding:8px 6px;border-radius:4px;color:rgba(0,0,0,.65);outline:0}input:focus{border-color:#40a9ff}button{padding:5px 16px;border-radius:2px;color:rgba(0,0,0,.65);outline:0;border:1px solid #d9d9d9;cursor:pointer;background:#fff}button:hover{border-color:#40a9ff;color:#40a9ff}:-moz-placeholder,:-ms-input-placeholder,::-moz-placeholder,::-webkit-input-placeholder{color:var(--placeholder-color)}.nav-btn{display:flex;font-size:1.05rem;border:0;outline:0;background:0 0;color:var(--c-text);opacity:.8;cursor:pointer}.nav-btn:hover{opacity:1}.nav-btn svg{margin:auto}.slugs{position:fixed;top:var(--header-height);right:0;max-height:calc(100% - var(--header-height) - 10rem);width:var(--slug-width);padding:50px 24px 0 0;border-right:1px solid var(--border-color);background-color:#fff;z-index:3;overflow-y:auto}[class*=language-] code{color:inherit}code[class*=language-],pre[class*=language-]{color:#d6deeb;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:rgba(29,59,83,.99)}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:rgba(29,59,83,.99)}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{color:#fff;background:#011627}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.prolog{color:#637777}.token.punctuation{color:#c792ea}.namespace{color:#b2ccd6}.token.deleted{color:#ef5350}.token.property,.token.symbol{color:#80cbc4}.token.keyword,.token.operator,.token.tag{color:#7fdbca}.token.boolean{color:#ff5874}.token.number{color:#f78c6c}.token.builtin,.token.char,.token.constant,.token.function{color:#82aaff}.token.doctype,.token.function,.token.selector{color:#c792ea}.token.attr-name,.token.inserted,code .token.inserted{color:#addb67}.language-css .token.string,.style .token.string,.token.entity,.token.string,.token.url{color:#addb67}.token.atrule,.token.attr-value,.token.class-name{color:#ffcb8b}.token.important,.token.regex,.token.variable{color:#d6deeb}.token.bold,.token.important{font-weight:700}html.dark tr:nth-child(2n){background-color:transparent!important}html.light code[class*=language-],html.light pre[class*=language-]{color:#403f53;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}html.light code[class*=language-] ::-moz-selection,html.light code[class*=language-]::-moz-selection,html.light pre[class*=language-] ::-moz-selection,html.light pre[class*=language-]::-moz-selection{text-shadow:none;background:#fbfbfb}html.light code[class*=language-] ::selection,html.light code[class*=language-]::selection,html.light pre[class*=language-] ::selection,html.light pre[class*=language-]::selection{text-shadow:none;background:#fbfbfb}@media print{html.light code[class*=language-],html.light pre[class*=language-]{text-shadow:none}}html.light pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}html.light :not(pre)>code[class*=language-],html.light pre[class*=language-]{color:#fff;background:#fbfbfb}html.light :not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}html.light .token.cdata,html.light .token.comment,html.light .token.prolog{color:#989fb1}html.light .token.punctuation{color:#994cc3}html.light .namespace{color:#0c969b}html.light code .token.deleted{color:#ec5975}html.light .token.keyword,html.light .token.operator,html.light .token.property,html.light .token.symbol{color:#0c969b}html.light .token.tag{color:#994cc3}html.light .token.boolean{color:#bc5454}html.light .token.number{color:#aa0982}html.light .language-css .token.string,html.light .style .token.string,html.light .token.builtin,html.light .token.char,html.light .token.constant,html.light .token.entity,html.light .token.string,html.light .token.url{color:#4876d6}html.light .token.doctype,html.light .token.function,html.light .token.selector{color:#994cc3}html.light .token.attr-name,html.light .token.inserted{color:#4876d6}html.light .token.atrule,html.light .token.attr-value,html.light .token.class-name{color:#111}html.light .token.important,html.light .token.regex,html.light .token.variable{color:#c96765}html.light .token.bold,html.light .token.important{font-weight:700}.home-hero[data-v-e065f044]{margin:2.5rem 0 2.75rem;padding:0 1.5rem;text-align:center}@media (min-width:420px){.home-hero[data-v-e065f044]{margin:3.5rem 0}}@media (min-width:720px){.home-hero[data-v-e065f044]{margin:4rem 0 4.25rem}}.figure[data-v-e065f044]{padding:0 1.5rem}.image[data-v-e065f044]{display:block;margin:0 auto;width:auto;max-width:100%;max-height:280px}.title[data-v-e065f044]{margin-top:1.5rem;font-size:2rem}@media (min-width:420px){.title[data-v-e065f044]{font-size:3rem}}@media (min-width:720px){.title[data-v-e065f044]{margin-top:2rem}}.description[data-v-e065f044]{margin:0;margin-top:.25rem;line-height:1.3;font-size:1.2rem;color:var(--c-text-light)}@media (min-width:420px){.description[data-v-e065f044]{line-height:1.2;font-size:1.6rem}}.action[data-v-e065f044]{margin-top:1.5rem;display:inline-block}.action.alt[data-v-e065f044]{margin-left:1.5rem}@media (min-width:420px){.action[data-v-e065f044]{margin-top:2rem;display:inline-block}}.action[data-v-e065f044] .item{display:inline-block;border-radius:6px;padding:0 20px;line-height:44px;font-size:1rem;font-weight:500;color:var(--c-bg);background-color:var(--c-brand);border:2px solid var(--c-brand);transition:background-color .1s ease}.action.alt[data-v-e065f044] .item{background-color:var(--c-bg);color:var(--c-brand)}.action[data-v-e065f044] .item:hover{text-decoration:none;color:var(--c-bg);background-color:var(--c-brand-light)}@media (min-width:420px){.action[data-v-e065f044] .item{padding:0 24px;line-height:52px;font-size:1.2rem;font-weight:500}}.home-features[data-v-9c9c2344]{margin:0 auto;padding:2.5rem 0 2.75rem;max-width:960px}.home-hero+.home-features[data-v-9c9c2344]{padding-top:0}@media (min-width:420px){.home-features[data-v-9c9c2344]{padding:3.25rem 0 3.5rem}.home-hero+.home-features[data-v-9c9c2344]{padding-top:0}}@media (min-width:720px){.home-features[data-v-9c9c2344]{padding-right:1.5rem;padding-left:1.5rem}}.wrapper[data-v-9c9c2344]{padding:0 1.5rem}.home-hero+.home-features .wrapper[data-v-9c9c2344]{border-top:1px solid var(--c-divider);padding-top:2.5rem}@media (min-width:420px){.home-hero+.home-features .wrapper[data-v-9c9c2344]{padding-top:3.25rem}}@media (min-width:720px){.wrapper[data-v-9c9c2344]{padding-right:0;padding-left:0}}.container[data-v-9c9c2344]{margin:0 auto;max-width:392px}@media (min-width:720px){.container[data-v-9c9c2344]{max-width:960px}}.features[data-v-9c9c2344]{display:flex;flex-wrap:wrap;margin:-20px -24px}.feature[data-v-9c9c2344]{flex-shrink:0;padding:20px 24px;width:100%}@media (min-width:720px){.feature[data-v-9c9c2344]{width:calc(100% / 3)}}.title[data-v-9c9c2344]{margin:0;border-bottom:0;line-height:1.4;font-size:1.25rem;font-weight:500}@media (min-width:420px){.title[data-v-9c9c2344]{font-size:1.4rem}}.details[data-v-9c9c2344]{margin:0;line-height:1.6;font-size:1rem;color:var(--c-text-light)}.title+.details[data-v-9c9c2344]{padding-top:.25rem}.footer[data-v-44324124]{margin:0 auto;max-width:960px}@media (min-width:720px){.footer[data-v-44324124]{padding:0 1.5rem}}.container[data-v-44324124]{padding:2rem 1.5rem 2.25rem}.home-content+.footer .container[data-v-44324124],.home-features+.footer .container[data-v-44324124],.home-hero+.footer .container[data-v-44324124]{border-top:1px solid var(--c-divider)}@media (min-width:420px){.container[data-v-44324124]{padding:3rem 1.5rem 3.25rem}}.text[data-v-44324124]{margin:0;text-align:center;line-height:1.4;font-size:.9rem;color:var(--c-text-light)}.home[data-v-1fd43058]{padding-top:var(--header-height)}.home-content[data-v-1fd43058]{max-width:960px;margin:0 auto;padding:0 1.5rem}@media (max-width:720px){.home-content[data-v-1fd43058]{max-width:392px;padding:0}} \ No newline at end of file diff --git a/components/auth.html b/components/auth.html new file mode 100644 index 00000000..dc1820b3 --- /dev/null +++ b/components/auth.html @@ -0,0 +1,45 @@ + + + + + + Authority | Vben Admin + + + + + + + + + + + + + + + + +

Authority

用于项目权限的组件,一般用于按钮级等细粒度权限管理

Usage

<template>
+  <div>
+    <Authority :value="RoleEnum.ADMIN">
+      <a-button type="primary" block> 只有admin角色可见 </a-button>
+    </Authority>
+  </div>
+</template>
+<script>
+  import { Authority } from '/@/components/Authority';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { Authority },
+  });
+</script>
+

Props

属性类型默认值说明
valueRoleEnum,RoleEnum[],string,string[]-角色信息或者权限编码。会自动区分权限模式
+ + + + \ No newline at end of file diff --git a/components/basic.html b/components/basic.html new file mode 100644 index 00000000..c5b39d02 --- /dev/null +++ b/components/basic.html @@ -0,0 +1,69 @@ + + + + + + Basic 基础组件 | Vben Admin + + + + + + + + + + + + + + + + +

Basic 基础组件

一些比较基础的通用组件使用方式

BasicTitle

用于显示标题,可以显示帮助按钮及文本

Usage

<template>
+  <div>
+    <BasicTitle helpMessage="提示1">标题</BasicTitle>
+    <BasicTitle :helpMessage="['提示1', '提示2']">标题</BasicTitle>
+  </div>
+</template>
+<script>
+  import { BasicTitle } from '/@/components/Basic/index';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { BasicTitle },
+  });
+</script>
+

Props

属性类型默认值说明
helpMessagestring|string[]-标题右侧帮助按钮信息
spanbooleanfalse是否显示标题左侧蓝色色块
normalbooleanfalse将文字默认化,不加粗

Slots

名称说明
default标题文本

BasicArrow

带动画的箭头组件

Usage

<template>
+  <div>
+    <BasicArrow :expand="false" />
+  </div>
+</template>
+<script>
+  import { BasicArrow } from '/@/components/Basic/index';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { BasicArrow },
+  });
+</script>
+

Props

属性类型默认值说明
expandbooleanfalse箭头展开状态
topbooleanfalse箭头默认向上
bottombooleanfalse箭头默认向下
insetbooleanfalse取消 padding/margin,用于内嵌

BasicHelp

帮助按钮组件

Usage

<template>
+  <div>
+    <BasicHelp :text="['提示1', '提示2']" />
+    <BasicHelp text="提示" />
+  </div>
+</template>
+<script>
+  import { BasicHelp } from '/@/components/Basic/index';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { BasicHelp },
+  });
+</script>
+

Props

属性类型默认值可选值说明
fontSizestring14px-字体大小
colorstring#fff-颜色
textstring|string[]--文本列表
showIndexbooleantrue-是否显示序号,在 text 为 string[]情况下生效
maxWidthstring600px-最大宽度
placementstringright-显示方向,参考 Tooltip 组件

Slots

名称说明
default默认图标
+ + + + \ No newline at end of file diff --git a/components/click-out-side.html b/components/click-out-side.html new file mode 100644 index 00000000..b0bbfea9 --- /dev/null +++ b/components/click-out-side.html @@ -0,0 +1,53 @@ + + + + + + ClickOutSide | Vben Admin + + + + + + + + + + + + + + + + +

ClickOutSide

用于监听包裹的元素点击外部触发事件

Usage

<template>
+  <div>
+    <ClickOutSide @clickOutside="() => (showRef = false)">
+      <div @click="() => (showRef = true)">
+        {{ showRef ? '鼠标点击那部(点击边框外可以恢复)' : '点击该区域状态(初始状态)' }}
+      </div>
+    </ClickOutSide>
+  </div>
+</template>
+<script>
+  import { defineComponent, ref } from 'vue';
+  import { ClickOutSide } from '/@/components/ClickOutSide/';
+  export default defineComponent({
+    components: { ClickOutSide },
+    setup() {
+      const showRef = ref(false);
+      return {
+        showRef,
+      };
+    },
+  });
+</script>
+

Events

事件回调参数说明
clickOutside()=>void点击包裹元素外部区域触发

Slots

名称说明
default被包裹的元素
+ + + + \ No newline at end of file diff --git a/components/code-editor.html b/components/code-editor.html new file mode 100644 index 00000000..6bd6d0dc --- /dev/null +++ b/components/code-editor.html @@ -0,0 +1,44 @@ + + + + + + CodeEditor | Vben Admin + + + + + + + + + + + + + + + + +

CodeEditor

代码编辑器

Usage

<template>
+  <CodeEditor v-model:value="value" :mode="modeValue" />
+</template>
+<script>
+  import { defineComponent, ref } from 'vue';
+  export default defineComponent({
+    components: { CodeEditor },
+    setup() {
+      const modeValue = ref('application/json');
+      return { value, modeValue };
+    },
+  });
+</script>
+

Props

属性类型默认值可选值说明
value(v-model:value)any--绑定值
modestringapplication/json'application/json','htmlmixed','javascript'代码类型
readonlyboolean--是否只读
+ + + + \ No newline at end of file diff --git a/components/collapse-container.html b/components/collapse-container.html new file mode 100644 index 00000000..45dfdbd2 --- /dev/null +++ b/components/collapse-container.html @@ -0,0 +1,46 @@ + + + + + + CollapseContainer | Vben Admin + + + + + + + + + + + + + + + + +

CollapseContainer

区域折叠卡片容器

Usage

<template>
+  <div>
+    <CollapseContainer> content </CollapseContainer>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+
+  export default defineComponent({
+    components: {
+      CollapseContainer,
+    },
+  });
+</script>
+

Props

属性类型默认值可选值说明
titlestring--标题
canExpanbooleantrue-是否可以展开,为true显示折叠按钮
helpMessagestring[],string--标题右侧温馨提醒
triggerWindowResizebooleanfalse-展开收缩的时候是否触发 window.resize
loadingbooleanfalse-显示加载骨架屏
lazyTimenumber0-延迟加载时间

Slots

名称说明
title自定义标题
action自定义右侧操作按钮
default默认区域
footer自定义底部区域
+ + + + \ No newline at end of file diff --git a/components/count-down.html b/components/count-down.html new file mode 100644 index 00000000..8539b3a8 --- /dev/null +++ b/components/count-down.html @@ -0,0 +1,53 @@ + + + + + + CountDown | Vben Admin + + + + + + + + + + + + + + + + +

CountDown

倒计时组件

CountButton

倒计时按钮组件

Usage

<template>
+  <CountButton />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { CountButton } from '/@/components/CountDown';
+
+  export default defineComponent({
+    components: { CountButton },
+  });
+</script>
+

Props

属性类型默认值可选值说明
valueany--绑定值
countnumber60-倒计时时间
beforeStartFunc()=>promise--倒计时之前执行的函数,返回 true 才会开始执行

CountDownInput

倒计时输入框按钮组件

Usage

<template>
+  <CountdownInput />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { CountdownInput } from '/@/components/CountDown';
+
+  export default defineComponent({
+    components: { CountdownInput },
+  });
+</script>
+

Props

属性类型默认值可选值说明
valueany--绑定值
sizestring'default', 'large', 'small'-输入框即按钮大小
countnumber60-倒计时时间
sendCodeApi()=>promise--倒计时之前执行的函数,返回 true 才会开始执行
+ + + + \ No newline at end of file diff --git a/components/count-to.html b/components/count-to.html new file mode 100644 index 00000000..35809824 --- /dev/null +++ b/components/count-to.html @@ -0,0 +1,44 @@ + + + + + + CountTo | Vben Admin + + + + + + + + + + + + + + + + +

CountTo

数字动画组件

该组件对 vue-countTo 进行了重构,改造成适配 vue3 语法的组件。

Usage

<template>
+  <CountTo prefix="$" :color="'#409EFF'" :startVal="1" :endVal="200000" :duration="8000" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { CountTo } from '/@/components/CountTo/index';
+
+  export default defineComponent({
+    components: {
+      CountTo,
+    },
+  });
+</script>
+

Props

属性类型默认值说明
startValnumber0起始值
endValnumber2021结束值
durationnumber1500动画持续时间
autoplaybooleantrue自动执行
prefixstring-前缀
suffixstring-后缀
separatorstring,分隔符
colorstring-字体颜色
useEasingbooleantrue是否开启动画
transitionstringlinear动画效果
decimalsnumber0保留小数点位数

Methods

名称回调参数说明
start()=>void开始执行动画
reset()=>void重置
+ + + + \ No newline at end of file diff --git a/components/cropper.html b/components/cropper.html new file mode 100644 index 00000000..adbcaf65 --- /dev/null +++ b/components/cropper.html @@ -0,0 +1,97 @@ + + + + + + Cropper | Vben Admin + + + + + + + + + + + + + + + + +

Cropper

图片裁剪组件

CropperImage

图片裁剪组件

Usage

<template>
+  <CropperImage ref="refCropper" :src="img" @cropend="handleCropend" style="width: 40vw" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { CropperImage } from '/@/components/Cropper';
+  import img from '/@/assets/images/header.jpg';
+
+  export default defineComponent({
+    components: {
+      CropperImage,
+    },
+    setup() {
+      const info = ref('');
+      const cropperImg = ref('');
+
+      function handleCropend({ imgBase64, imgInfo }) {
+        info.value = imgInfo;
+        cropperImg.value = imgBase64;
+      }
+
+      return {
+        img,
+        info,
+        cropperImg,
+        handleCropend,
+      };
+    },
+  });
+</script>
+

Props

属性类型默认值说明
srcstring-图片源
altstring-图片 alt
circledbooleanfalse圆形裁剪框
realTimePreviewbooleantrue实时触发预览
heightstring360px高度
crossoriginstring-crossorigin
imageStyleobject``图片样式
optionsobjectDefaultOptionscorpperjs 配置项

DefaultOptions

{
+  aspectRatio: 1,
+  zoomable: true,
+  zoomOnTouch: true,
+  zoomOnWheel: true,
+  cropBoxMovable: true,
+  cropBoxResizable: true,
+  toggleDragModeOnDblclick: true,
+  autoCrop: true,
+  background: true,
+  highlight: true,
+  center: true,
+  responsive: true,
+  restore: true,
+  checkCrossOrigin: true,
+  checkOrientation: true,
+  scalable: true,
+  modal: true,
+  guides: true,
+  movable: true,
+  rotatable: true,
+}
+

CropperAvatar

头像裁剪组件

Usage

<template>
+  <CropperAvatar :uploadApi="uploadApi" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { CropperAvatar } from '/@/components/Cropper';
+  import { uploadApi } from '/@/api/sys/upload';
+
+  export default defineComponent({
+    components: {
+      CropperAvatar,
+    },
+  });
+</script>
+

Props

属性类型默认值说明版本
widthstring,number200px图片源
uploadApi({ file: Blob, name: string }) => Promise<void>-图片上传接口
valueString-当前头像地址(v-model)2.5.3
showBtnBooleantrue是否显示按钮2.5.3
btnTextString-按钮文案2.5.3
btnPropsButtonProps-按钮的其它属性2.5.3

Events

名称参数说明版本
changevalue: String当头像上传完成时触发2.5.3

Methods

名称定义说明版本
openModal()=>void打开上传Modal2.5.3
closeModal()=>void关闭上传Modal2.5.3
+ + + + \ No newline at end of file diff --git a/components/desc.html b/components/desc.html new file mode 100644 index 00000000..035cbd75 --- /dev/null +++ b/components/desc.html @@ -0,0 +1,96 @@ + + + + + + Description 详情组件 | Vben Admin + + + + + + + + + + + + + + + + +

Description 详情组件

antv 的 Descriptions 组件进行封装

Usage

<template>
+  <div class="p-4">
+    <Description
+      title="基础示例"
+      :collapseOptions="{ canExpand: true, helpMessage: 'help me' }"
+      :column="3"
+      :data="mockData"
+      :schema="schema"
+    />
+    <Description @register="register" class="mt-4" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { Alert } from 'ant-design-vue';
+  import { Description, DescItem, useDescription } from '/@/components/Description/index';
+  const mockData: any = {
+    username: 'test',
+    nickName: 'VB',
+    age: 123,
+    phone: '15695909xxx',
+    email: '190848757@qq.com',
+    addr: '厦门市思明区',
+    sex: '男',
+    certy: '3504256199xxxxxxxxx',
+    tag: 'orange',
+  };
+  const schema: DescItem[] = [
+    {
+      field: 'username',
+      label: '用户名',
+    },
+    {
+      field: 'nickName',
+      label: '昵称',
+      render: (curVal, data) => {
+        return `${data.username}-${curVal}`;
+      },
+    },
+    {
+      field: 'phone',
+      label: '联系电话',
+    },
+    {
+      field: 'email',
+      label: '邮箱',
+    },
+    {
+      field: 'addr',
+      label: '地址',
+    },
+  ];
+  export default defineComponent({
+    components: { Description, Alert },
+    setup() {
+      const [register] = useDescription({
+        title: 'useDescription',
+        data: mockData,
+        schema: schema,
+      });
+      return { mockData, schema, register };
+    },
+  });
+</script>
+

useDescription

参考以上示例

const [register] = useDescription(Props);
+

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv Description

属性类型默认值可选值说明
titlestring--标题
sizestringsmall-大小
borderedbooleantrue-是否展示边框
columnNumber, Object{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }-一行的 DescriptionItems 数量
useCollapseboolean--是否包裹 CollapseContainer 组件
collapseOptionsObject--CollapseContainer 组件属性
schemaDescItem[]--详情项配置,见下方 DescItem 配置
dataobject--数据源

DescItem

属性类型默认值可选值说明
fieldstring--字段名
labelstring--标签名
labelMinWidthnumber--label 最小宽度
contentMinWidthnumber--content 最小宽度
labelStyleany--label 样式
spannumber--和并列数量
show(data)=>boolean--动态判断当前组件是否显示
render(val: string, data: any)=>VNode,undefined,Element,string,number--自定义渲染 content
+ + + + \ No newline at end of file diff --git a/components/drawer.html b/components/drawer.html new file mode 100644 index 00000000..5c398a9f --- /dev/null +++ b/components/drawer.html @@ -0,0 +1,96 @@ + + + + + + Drawer 抽屉组件 | Vben Admin + + + + + + + + + + + + + + + + +

Drawer 抽屉组件

antv 的 drawer 组件进行封装,扩展拖拽,全屏,自适应高度等功能。

Usage

由于 drawer 内部代码一般独立成单独文件,推荐独立成组件来进行开发,所以示例都是以独立的文件来进行说明

独立组件代码,用于写组件内部的内容

<template>
+  <BasicDrawer v-bind="$attrs" title="Drawer Title" width="50%"> Drawer Info. </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicDrawer } from '/@/components/Drawer';
+  export default defineComponent({
+    components: { BasicDrawer },
+  });
+</script>
+

页面引用弹窗

<template>
+  <div>
+    <Drawer @register="register" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { Alert } from 'ant-design-vue';
+  import { useDrawer } from '/@/components/Drawer';
+  import Drawer from './Drawer.vue';
+
+  export default defineComponent({
+    components: { Drawer },
+    setup() {
+      const [register, { openDrawer }] = useDrawer();
+      return {
+        register,
+        openDrawer,
+      };
+    },
+  });
+</script>
+

useDrawer

useDrawer 用于操作组件

const [register, { openDrawer, setDrawerProps }] = useDrawer();
+

register

register 用于注册 useDrawer,如果需要使用 useDrawer 提供的 api,必须将 register 传入组件的 onRegister

原理其实很简单,就是 vue 的组件子传父通信,内部通过 emit("register",instance) 实现。

同时,独立出去的组件需要将 attrs 绑定到 Drawer 的上面。

<BasicDrawer v-bind="$attrs"> Drawer Info. </BasicDrawer>
+

openDrawer

用于打开/关闭弹窗

// true/false: 打开关闭弹窗
+// data: 传递到子组件的数据
+openDrawer(true, data);
+

closeDrawer

用于关闭弹窗

closeDrawer();
+

setDrawerProps

用于更改 drawer 的 props 参数因为 drawer 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setDrawerProps 方便更改内部 drawer 的 props

Props 内容可以见下方

setDrawerProps(props);
+

useDrawerInner

用于独立的 Drawer 内部调用

<template>
+  <BasicDrawer v-bind="$attrs" @register="register" title="Drawer Title" width="50%">
+    Drawer Info.
+    <a-button type="primary" @click="closeDrawer">内部关闭drawer</a-button>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  export default defineComponent({
+    components: { BasicDrawer },
+    setup() {
+      const [register, { closeDrawer }] = useDrawerInner();
+      return { register, closeDrawer };
+    },
+  });
+</script>
+

useModalInner用于操作独立组件

const [register, { closeModal, setModalProps }] = useModalInner(callback);
+

callback

type: (data:any)=>void

回调函数用于接收 openDrawer 第二个参数传递的值

openDrawer((data: any) => {
+  console.log(data);
+});
+

closeDrawer

用于关闭抽屉

closeDrawer();
+

changeOkLoading

用于修改确认按钮的 loading 状态

// true or false
+changeOkLoading(true);
+

changeLoading

用于修改 modal 的 loading 状态

// true or false
+changeLoading(true);
+

setDrawerProps

用于更改 drawer 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供setDrawerProps 方便更改内部 drawer 的 props

Props 内容可以见下方

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv drawer

属性类型默认值可选值说明
isDetailbooleanfalse-是否为详情模式
loadingbooleanfalse-loading 状态
loadingTextstring``-loading 文本 s
showDetailBackbooleantrue-isDetail=true 状态下是否显示返回按钮
closeFunc() => Promise<boolean>--自定义关闭函数,返回true关闭,否则不关闭
showFooterboolean--是否显示底部
footerHeightnumber60-底部区域高度

Events

事件回调参数说明
close(e)=>void点击关闭回调
visible-change(visible:boolean)=>void弹窗打开关闭时触发
ok(e)=>void点击确定回调
+ + + + \ No newline at end of file diff --git a/components/excel.html b/components/excel.html new file mode 100644 index 00000000..4b8c6891 --- /dev/null +++ b/components/excel.html @@ -0,0 +1,106 @@ + + + + + + Excel 组件 | Vben Admin + + + + + + + + + + + + + + + + +

Excel 组件

excel 导入导出操作

项目中使用到的是 XLSX,具体文档可以参考XLSX 文档

Import

Usage

<template>
+  <ImpExcel @success="loadDataSuccess">
+    <a-button class="m-3">导入Excel</a-button>
+  </ImpExcel>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { ImpExcel, ExcelData } from '/@/components/Excel';
+  export default defineComponent({
+    components: { ImpExcel },
+    setup() {
+      function loadDataSuccess(excelDataList: ExcelData[]) {
+        tableListRef.value = [];
+        console.log(excelDataList);
+        for (const excelData of excelDataList) {
+          const {
+            header,
+            results,
+            meta: { sheetName },
+          } = excelData;
+          const columns: BasicColumn[] = [];
+          for (const title of header) {
+            columns.push({ title, dataIndex: title });
+          }
+          tableListRef.value.push({ title: sheetName, dataSource: results, columns });
+        }
+      }
+      return {
+        loadDataSuccess,
+      };
+    },
+  });
+</script>
+

Events

事件回调参数说明
success(res:ExcelData)=>void导入成功回调
error()=>void导出错误

ExcelData

属性类型默认值说明
header:string[];table 表头
results:T[];table 数据
meta:{ sheetName: string };table title

Export

具体详情可以参考完整版示例

import { jsonToSheetXlsx, aoaToSheetXlsx } from '/@/components/Excel';
+

数组格式数据导出

import { aoaToSheetXlsx } from '/@/components/Excel';
+// 保证data顺序与header一致
+aoaToSheetXlsx({
+  data: [],
+  header: [],
+  filename: '二维数组方式导出excel.xlsx',
+});
+

自定义导出格式

import { jsonToSheetXlsx } from '/@/components/Excel';
+
+jsonToSheetXlsx({
+  data,
+  filename,
+  write2excelOpts: {
+    // 可以是 xlsx/html/csv/txt
+    bookType,
+  },
+});
+

json 格式导出

import { jsonToSheetXlsx } from '/@/components/Excel';
+
+jsonToSheetXlsx({
+  data,
+  filename: '使用key作为默认头部.xlsx',
+});
+
+jsonToSheetXlsx({
+  data,
+  header: {
+    id: 'ID',
+    name: '姓名',
+    age: '年龄',
+    no: '编号',
+    address: '地址',
+    beginTime: '开始时间',
+    endTime: '结束时间',
+  },
+  filename: '自定义头部.xlsx',
+  json2sheetOpts: {
+    // 指定顺序
+    header: ['name', 'id'],
+  },
+});
+

Function

方法回调参数返回值说明
jsonToSheetXlsxFunction(JsonToSheet)json 格式数据,导出到 excel
aoaToSheetXlsxFunction(AoAToSheet)数组格式,导出到 excel

JsonToSheet Type

属性类型默认值说明
dataT[]JSON 对象数组
header?:T;表头未设置则取 JSON 对象的 key 作为 header
filename?:stringexcel-list.xlsx导出的文件名
json2sheetOpts?:JSON2SheetOpts调用 XLSX.utils.json_to_sheet 的可选参数
write2excelOpts?:WritingOptions{ bookType: 'xlsx' }调用 XLSX.writeFile 的可选参数,具体参 XLSX 文档

AoAToSheet Type

属性类型默认值说明
dataT[][];二维数组
header?:T;表头 ;未设置则没有表头
filename?:string;excel-list.xlsx导出的文件名
write2excelOpts?:WritingOptions;{ bookType: 'xlsx' }调用 XLSX.writeFile 的可选参数
+ + + + \ No newline at end of file diff --git a/components/flow-chart.html b/components/flow-chart.html new file mode 100644 index 00000000..5c09c582 --- /dev/null +++ b/components/flow-chart.html @@ -0,0 +1,47 @@ + + + + + + FlowChart | Vben Admin + + + + + + + + + + + + + + + + +

FlowChart

流程图组件,基于 didi/LogicFlow 的简单封装。详细配置请参考文档 FlowChart

Usage

<template>
+  <FlowChart :data="demoData" />
+</template>
+
+<script lang="ts">
+  import { FlowChart } from '/@/components/FlowChart';
+  import { PageWrapper } from '/@/components/Page';
+
+  import demoData from './dataTurbo.json';
+  export default {
+    components: { FlowChart, PageWrapper },
+    setup() {
+      return { demoData };
+    },
+  };
+</script>
+

Props

属性类型默认值可选值说明
flowOptionsobject--FlowCharts 配置项
dataobject--流程数据
toolbarbooleantrue-是否显示工具栏
patternItems[]--左侧拖拽列表数据
+ + + + \ No newline at end of file diff --git a/components/form.html b/components/form.html new file mode 100644 index 00000000..0d4d4dd9 --- /dev/null +++ b/components/form.html @@ -0,0 +1,463 @@ + + + + + + Form 表单组件 | Vben Admin + + + + + + + + + + + + + + + + +

Form 表单组件

antv 的 form 组件进行封装,扩展一些常用的功能

如果文档内没有,可以尝试在在线示例内寻找

Usage

useForm 方式

下面是一个使用简单表单的示例,只有一个输入框

<template>
+  <div class="m-4">
+    <BasicForm
+      :labelWidth="100"
+      :schemas="schemas"
+      :actionColOptions="{ span: 24 }"
+      @submit="handleSubmit"
+    />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicForm, FormSchema } from '/@/components/Form';
+  import { CollapseContainer } from '/@/components/Container';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  const schemas: FormSchema[] = [
+    {
+      field: 'field',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 8,
+      },
+      defaultValue: '1',
+      componentProps: {
+        placeholder: '自定义placeholder',
+        onChange: (e) => {
+          console.log(e);
+        },
+      },
+    },
+  ];
+
+  export default defineComponent({
+    components: { BasicForm, CollapseContainer },
+    setup() {
+      const { createMessage } = useMessage();
+      return {
+        schemas,
+        handleSubmit: (values: any) => {
+          createMessage.success('click search,values:' + JSON.stringify(values));
+        },
+      };
+    },
+  });
+</script>
+

template 方式

所有可调用函数见下方 Methods 说明

<template>
+  <div class="m-4">
+    <BasicForm
+      :schemas="schemas"
+      ref="formElRef"
+      :labelWidth="100"
+      @submit="handleSubmit"
+      :actionColOptions="{ span: 24 }"
+    />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { BasicForm, FormSchema, FormActionType, FormProps } from '/@/components/Form';
+  import { CollapseContainer } from '/@/components/Container';
+  const schemas: FormSchema[] = [];
+
+  export default defineComponent({
+    components: { BasicForm, CollapseContainer },
+    setup() {
+      const formElRef = ref<Nullable<FormActionType>>(null);
+      return {
+        formElRef,
+        schemas,
+        setProps(props: FormProps) {
+          const formEl = formElRef.value;
+          if (!formEl) return;
+          formEl.setProps(props);
+        },
+      };
+    },
+  });
+</script>
+

useForm

form 组件还提供了 useForm,方便调用函数内部方法

示例

<template>
+  <BasicForm @register="register" @submit="handleSubmit" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  const schemas: FormSchema[] = [
+    {
+      field: 'field1',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 8,
+      },
+      componentProps: {
+        placeholder: '自定义placeholder',
+        onChange: (e: any) => {
+          console.log(e);
+        },
+      },
+    },
+  ];
+
+  export default defineComponent({
+    components: { BasicForm, CollapseContainer },
+    setup() {
+      const { createMessage } = useMessage();
+      const [register, { setProps }] = useForm({
+        labelWidth: 120,
+        schemas,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      return {
+        register,
+        schemas,
+        handleSubmit: (values: any) => {
+          createMessage.success('click search,values:' + JSON.stringify(values));
+        },
+        setProps,
+      };
+    },
+  });
+</script>
+

参数介绍

const [register, methods] = useForm(props);
+

参数 props 内的值可以是 computed 或者 ref 类型

register

register 用于注册 useForm,如果需要使用 useForm 提供的 api,必须将 register 传入组件的 onRegister

<template>
+  <BasicForm @register="register" @submit="handleSubmit" />
+</template>
+<script>
+  export default defineComponent({
+    components: { BasicForm },
+    setup() {
+      const [register] = useForm();
+      return {
+        register,
+      };
+    },
+  });
+</script>
+

Methods见下方说明

Methods

getFieldsValue

类型: () => Recordable;

说明: 获取表单值

setFieldsValue

类型: <T>(values: T) => Promise<void>

说明: 设置表单字段值

resetFields

类型: ()=> Promise<void>

说明: 重置表单值

validateFields

类型: (nameList?: NamePath[]) => Promise<any>

说明: 校验指定表单项

validate

类型: (nameList?: NamePath[]) => Promise<any>

说明: 校验整个表单

submit

类型: () => Promise<void>

说明: 提交表单

scrollToField

类型: (name: NamePath, options?: ScrollOptions) => Promise<void>

说明: 滚动到对应字段位置

clearValidate

类型: (name?: string | string[]) => Promise<void>

说明: 清空校验

setProps

TIP

设置表单的 props 可以直接在标签上传递,也可以使用 setProps,或者初始化直接写 useForm(props)

类型: (formProps: Partial<FormProps>) => Promise<void>

说明: 设置表单 Props

removeSchemaByField

类型: (field: string | string[]) => Promise<void>

说明: 根据 field 删除 Schema

appendSchemaByField

类型: ( schema: FormSchema, prefixField: string | undefined, first?: boolean | undefined ) => Promise<void>

说明: 插入到指定 filed 后面,如果没传指定 field,则插入到最后,当 first = true 时插入到第一个位置

updateSchema

类型: (data: Partial<FormSchema> | Partial<FormSchema>[]) => Promise<void>

说明: 更新表单的 schema, 只更新函数所传的参数

e.g

updateSchema({ field: 'filed', componentProps: { disabled: true } });
+updateSchema([
+  { field: 'filed', componentProps: { disabled: true } },
+  { field: 'filed1', componentProps: { disabled: false } },
+]);
+

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv form

属性类型默认值可选值说明版本
schemasSchema[]--表单配置,见下方 FormSchema 配置
submitOnResetbooleanfalse-重置时是否提交表单
labelColPartial<ColEx>--整个表单通用 LabelCol 配置
wrapperColPartial<ColEx>--整个表单通用 wrapperCol 配置
baseColPropsPartial<ColEx>--配置所有选子项的 ColProps,不需要逐个配置,子项也可单独配置优先与全局
baseRowStyleobject--配置所有 Row 的 style 样式
labelWidthnumber , string--扩展 form 组件,增加 label 宽度,表单内所有组件适用,可以单独在某个项覆盖或者禁用
labelAlignstring-left,rightlabel 布局
mergeDynamicDataobject--额外传递到子组件的参数 values
autoFocusFirstItembooleanfalse-是否聚焦第一个输入框,只在第一个表单项为 input 的时候作用
compactbooleanfalsetrue/false紧凑类型表单,减少 margin-bottom
sizestringdefault'default' , 'small' , 'large'向表单内所有组件传递 size 参数,自定义组件需自行实现 size 接收
disabledbooleanfalsetrue/false向表单内所有组件传递 disabled 属性,自定义组件需自行实现 disabled 接收
autoSetPlaceHolderbooleantrue true/false自动设置表单内组件的 placeholder,自定义组件需自行实现
autoSubmitOnEnterbooleanfalse true/false在 input 中输入时按回车自动提交2.4.0
rulesMessageJoinLabelbooleanfalsetrue/false如果表单项有校验,会自动生成校验信息,该参数控制是否将字段中文名字拼接到自动生成的信息后方
showAdvancedButtonbooleanfalsetrue/false是否显示收起展开按钮
emptySpannumber , Partial<ColEx>0-空白行格,可以是数值或者 col 对象 数
autoAdvancedLinenumber3-如果 showAdvancedButton 为 true,超过指定行数行默认折叠
alwaysShowLinesnumber1-折叠时始终保持显示的行数2.7.1
showActionButtonGroupbooleantruetrue/false是否显示操作按钮(重置/提交)
actionColOptionsPartial<ColEx>--操作按钮外层 Col 组件配置,如果开启 showAdvancedButton,则不用设置,具体见下方 actionColOptions
showResetButtonbooleantrue-是否显示重置按钮
resetButtonOptionsobject-重置按钮配置见下方 ActionButtonOption
showSubmitButtonbooleantrue-是否显示提交按钮
submitButtonOptionsobject-确认按钮配置见下方 ActionButtonOption
resetFunc () => Promise<void>-重置表单行为前执行自定义重置按钮逻辑() => Promise<void>;
submitFunc () => Promise<void>-自定义提交按钮逻辑() => Promise<void>;
fieldMapToTime[string, [string, string], string?][]'timestamp' ,'timestampStartDay' ,momentjs 时间格式用于将表单内时间区域的应设成 2 个字段,见下方说明

ColEx

src/components/Form/src/types/index.ts

ActionButtonOption

BasicButtonProps

export interface ButtonProps extends BasicButtonProps {
+  text?: string;
+}
+

fieldMapToTime

将表单内时间区域的值映射成 2 个字段

如果表单内有时间区间组件,获取到的值是一个数组,但是往往我们传递到后台需要是 2 个字段

useForm({
+  fieldMapToTime: [
+    // data为时间组件在表单内的字段,startTime,endTime为转化后的开始时间与结束时间
+    // 'YYYY-MM-DD'为时间格式,参考moment
+    ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],
+    // 支持多个字段
+    ['datetime1', ['startTime1', 'endTime1'], 'YYYY-MM-DD HH:mm:ss'],
+  ],
+});
+
+// fieldMapToTime没写的时候表单获取到的值
+{
+  datetime: [Date(),Date()]
+}
+//  ['datetime', ['startTime', 'endTime'], 'YYYY-MM-DD'],等同于 dayjs(Date()).format('YYYY-MM-DD'). 之后
+{
+    startTime: '2020-08-12',
+    endTime: '2020-08-15',
+}
+
+// ['datetime', ['startTime', 'endTime'], 'timestamp'],等同于 dayjs(Date()).unix(). 之后
+{
+    startTime: 1597190400,
+    endTime: 1597449600,
+}
+
+// ['datetime', ['startTime', 'endTime'], 'timestampStartDay'],等同于 dayjs(Date()).startOf('day').unix(). 之后
+{
+    startTime: 1597190400,
+    endTime: 1597449600,
+}
+

FormSchema

属性类型默认值可选值说明
fieldstring--字段名
labelstring--标签名
subLabelstring--二级标签名灰色
suffixstring , number , ((values: RenderCallbackParams) => string / number);--组件后面的内容
changeEventstring--表单更新事件名称
helpMessagestring , string[]--标签名右侧温馨提示
helpComponentPropsHelpComponentProps--标签名右侧温馨提示组件 props,见下方 HelpComponentProps
labelWidthstring , number--覆盖统一设置的 labelWidth
disabledLabelWidthbooleanfalsetrue/false禁用 form 全局设置的 labelWidth,自己手动设置 labelCol 和 wrapperCol
componentstring--组件类型,见下方 ComponentType
componentPropsany,()=>{}--所渲染的组件的 props
rulesValidationRule[]--校验规则,见下方 ValidationRule
requiredboolean--简化 rules 配置,为 true 则转化成 [{required:true}]。2.4.0之前的版本只支持 string 类型的值
rulesMessageJoinLabelbooleanfalse-校验信息是否加入 label
itemPropsany--参考下方 FormItem
colPropsColEx--参考上方 actionColOptions
defaultValueobject--所渲渲染组件的初始值
render(renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string--自定义渲染组件
renderColContent(renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string--自定义渲染组件(需要自行包含 formItem)
renderComponentContent(renderCallbackParams: RenderCallbackParams) => any / string--自定义渲染组内部的 slot
slotstring--自定义 slot,渲染组件
colSlotstring--自定义 slot,渲染组件 (需要自行包含 formItem)
show boolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判断当前组件是否显示,css 控制,不会删除 dom
ifShow boolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判断当前组件是否显示,js 控制,会删除 dom
dynamicDisabledboolean / ((renderCallbackParams: RenderCallbackParams) => boolean) --动态判断当前组件是否禁用
dynamicRulesboolean / ((renderCallbackParams: RenderCallbackParams) => boolean)--动态判返当前组件你校验规则

RenderCallbackParams

export interface RenderCallbackParams {
+  schema: FormSchema;
+  values: any;
+  model: any;
+  field: string;
+}
+

componentProps

  • 当值为对象类型时,该对象将作为component所对应组件的的 props 传入组件

  • 当值为一个函数时候

参数有 4 个

schema: 表单的整个 schemas

formActionType: 操作表单的函数。与 useForm 返回的操作函数一致

formModel: 表单的双向绑定对象,这个值是响应式的。所以可以方便处理很多操作

tableAction: 操作表格的函数,与 useTable 返回的操作函数一致。注意该参数只在表格内开启搜索表单的时候有值,其余情况为null,

{
+  // 简单例子,值改变的时候操作表格或者修改表单内其他元素的值
+  component:'Input',
+  componentProps: ({ schema, tableAction, formActionType, formModel }) => {
+    return {
+      // xxxx props
+      onChange:e=>{
+        const {reload}=tableAction
+        reload()
+        // or
+        formModel.xxx='123'
+      }
+    };
+  };
+}
+

HelpComponentProps

export interface HelpComponentProps {
+  maxWidth: string;
+  // 是否显示序号
+  showIndex: boolean;
+  // 文本列表
+  text: any;
+  // 颜色
+  color: string;
+  // 字体大小
+  fontSize: string;
+  icon: string;
+  absolute: boolean;
+  // 定位
+  position: any;
+}
+

ComponentType

schema 内组件的可选类型

export type ComponentType =
+  | 'Input'
+  | 'InputGroup'
+  | 'InputPassword'
+  | 'InputSearch'
+  | 'InputTextArea'
+  | 'InputNumber'
+  | 'InputCountDown'
+  | 'Select'
+  | 'ApiSelect'
+  | 'TreeSelect'
+  | 'RadioButtonGroup'
+  | 'RadioGroup'
+  | 'Checkbox'
+  | 'CheckboxGroup'
+  | 'AutoComplete'
+  | 'Cascader'
+  | 'DatePicker'
+  | 'MonthPicker'
+  | 'RangePicker'
+  | 'WeekPicker'
+  | 'TimePicker'
+  | 'Switch'
+  | 'StrengthMeter'
+  | 'Upload'
+  | 'IconPicker'
+  | 'Render'
+  | 'Slider'
+  | 'Rate'
+  | 'Divider'; // v2.7.2新增
+

Divider schema 说明

Divider类型用于在schemas中占位,将会渲染成一个分割线(始终占一整行的版面),可以用于较长表单的版面分隔。请只将 Divider 类型的 schema 当作一个分割线,而不是一个常规的表单字段。

  • Divider仅在showAdvancedButton为 false 时才会显示(也就是说如果启用了表单收起和展开功能,Divider将不会显示)
  • Divider 使用schema中的label以及helpMessage来渲染分割线中的提示内容
  • Divider 可以使用componentProps来设置除type之外的 props
  • Divider 不会渲染AFormItem,因此schema中除labelcomponentPropshelpMessagehelpComponentProps以外的属性不会被用到

自行添加需要的组件类型

src/components/Form/src/componentMap.ts 内,添加需要的组件,并在上方 ComponentType 添加相应的类型 key

方式 1

这种写法适用与适用频率较高的组件

componentMap.set('componentName', 组件);
+
+// ComponentType
+export type ComponentType = xxxx | 'componentName';
+

方式 2

使用 useComponentRegister 进行注册

这种写法只能在当前页使用,页面销毁之后会从 componentMap 删除相应的组件

import { useComponentRegister } from '@/components/form/index';
+
+import { StrengthMeter } from '@/components/strength-meter/index';
+
+useComponentRegister('StrengthMeter', StrengthMeter);
+

提示

方式 2 出现的原因是为了减少打包体积,如果某个组件体积很大,用方式 1 的话可能会使首屏体积增加

render

自定义渲染内容

<template>
+  <div class="m-4">
+    <BasicForm @register="register" @submit="handleSubmit" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, h } from 'vue';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { Input } from 'ant-design-vue';
+  const schemas: FormSchema[] = [
+    {
+      field: 'field1',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 8,
+      },
+      rules: [{ required: true }],
+      render: ({ model, field }) => {
+        return h(Input, {
+          placeholder: '请输入',
+          value: model[field],
+          onChange: (e: ChangeEvent) => {
+            model[field] = e.target.value;
+          },
+        });
+      },
+    },
+    {
+      field: 'field2',
+      component: 'Input',
+      label: '字段2',
+      colProps: {
+        span: 8,
+      },
+      rules: [{ required: true }],
+      renderComponentContent: () => {
+        return {
+          suffix: () => 'suffix',
+        };
+      },
+    },
+  ];
+  export default defineComponent({
+    components: { BasicForm },
+    setup() {
+      const { createMessage } = useMessage();
+      const [register, { setProps }] = useForm({
+        labelWidth: 120,
+        schemas,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      return {
+        register,
+        schemas,
+        handleSubmit: (values: any) => {
+          createMessage.success('click search,values:' + JSON.stringify(values));
+        },
+        setProps,
+      };
+    },
+  });
+</script>
+

slot

自定义渲染内容

提示

使用插槽自定义表单域时,请注意 antdv 有关 FormItem 的相关说明

<template>
+  <div class="m-4">
+    <BasicForm @register="register">
+      <template #customSlot="{ model, field }">
+        <a-input v-model:value="model[field]" />
+      </template>
+    </BasicForm>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'compatible-vue';
+  import { BasicForm, useForm } from '@/components/Form/index';
+  import { BasicModal } from '@/components/modal/index';
+  export default defineComponent({
+    name: 'FormDemo',
+    setup(props) {
+      const [register] = useForm({
+        labelWidth: 100,
+        actionColOptions: {
+          span: 24,
+        },
+        schemas: [
+          {
+            field: 'field1',
+            label: '字段1',
+            slot: 'customSlot',
+          },
+        ],
+      });
+      return {
+        register,
+      };
+    },
+  });
+</script>
+

ifShow/show/dynamicDisabled

自定义显示/禁用

<template>
+  <div class="m-4">
+    <BasicForm @register="register" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  const schemas: FormSchema[] = [
+    {
+      field: 'field1',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 8,
+      },
+      show: ({ values }) => {
+        return !!values.field5;
+      },
+    },
+    {
+      field: 'field2',
+      component: 'Input',
+      label: '字段2',
+      colProps: {
+        span: 8,
+      },
+      ifShow: ({ values }) => {
+        return !!values.field6;
+      },
+    },
+    {
+      field: 'field3',
+      component: 'DatePicker',
+      label: '字段3',
+      colProps: {
+        span: 8,
+      },
+      dynamicDisabled: ({ values }) => {
+        return !!values.field7;
+      },
+    },
+  ];
+
+  export default defineComponent({
+    components: { BasicForm },
+    setup() {
+      const [register, { setProps }] = useForm({
+        labelWidth: 120,
+        schemas,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      return {
+        register,
+        schemas,
+        setProps,
+      };
+    },
+  });
+</script>
+

antv form

Slots

名称说明
formFooter表单底部区域
formHeader表单顶部区域
resetBefore重置按钮前
submitBefore提交按钮前
advanceBefore展开按钮前
advanceAfter展开按钮后

ApiSelect

远程下拉加载组件,该组件可以用于学习参考如何自定义组件集成到 Form 组件内,将自定义组件交由 Form 去管理

Usage

const schemas: FormSchema[] = [
+  {
+    field: 'field',
+    component: 'ApiSelect',
+    label: '字段',
+  },
+];
+

Props

属性类型默认值说明
numberToStringbooleanfalse是否将number值转化为string
api()=>Promise<{ label: string; value: string; disabled?: boolean }[]>-数据接口,接受一个 Promise 对象
paramsobject-接口参数。此属性改变时会自动重新加载接口数据
resultFieldstring-接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式
labelFieldstringlabel下拉数组项内label显示文本的字段,支持x.x.x格式
valueFieldstringvalue下拉数组项内value实际值的字段,支持x.x.x格式
immediatebooleantrue是否立即请求接口,否则将在第一次点击时候触发请求

ApiTreeSelect

远程下拉树加载组件,和ApiSelect类似,2.6.1 以上版本

Props

属性类型默认值说明
api()=>Promise<{ label: string; value: string; children?: any[] }[]>-数据接口,接受一个 Promise 对象
paramsobject-接口参数。此属性改变时会自动重新加载接口数据
resultFieldstring-接口返回的字段,如果接口返回数组,可以不填。支持x.x.x格式
immediatebooleantrue是否立即请求接口。

RadioButtonGroup

Radio Button 风格的选择按钮

Usage

const schemas: FormSchema[] = [
+  {
+    field: 'field',
+    component: 'RadioButtonGroup',
+    label: '字段',
+  },
+];
+

Props

属性类型默认值说明
options{ label: string; value: string; disabled?: boolean }[]-数据字段
+ + + + \ No newline at end of file diff --git a/components/functional/context-menu.html b/components/functional/context-menu.html new file mode 100644 index 00000000..f05d9477 --- /dev/null +++ b/components/functional/context-menu.html @@ -0,0 +1,71 @@ + + + + + + ContextMenu | Vben Admin + + + + + + + + + + + + + + + + +

ContextMenu

函数式创建右键菜单组件, 只要能拿到 dom 的 event 对象就能为其创建右键菜单。

Usage

<template>
+  <div>
+    <a-button type="primary" @contextmenu="handleContext">Right Click on me</a-button>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { useContextMenu } from '/@/hooks/web/useContextMenu';
+  import { CollapseContainer } from '/@/components/Container';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  export default defineComponent({
+    components: { CollapseContainer },
+    setup() {
+      const [createContextMenu] = useContextMenu();
+      const { createMessage } = useMessage();
+      function handleContext(e: MouseEvent) {
+        createContextMenu({
+          event: e,
+          items: [
+            {
+              label: 'New',
+              icon: 'ant-design:plus-outlined',
+              handler: () => {
+                createMessage.success('click new');
+              },
+            },
+            {
+              label: 'Open',
+              icon: 'ant-design:folder-open-filled',
+              handler: () => {
+                createMessage.success('click open');
+              },
+            },
+          ],
+        });
+      }
+      return { handleContext };
+    },
+  });
+</script>
+

createContextMenu

Options

属性类型默认值可选值说明
eventEvent--需要创建的 dom 的 Event 对象
itemsContextMenuItem[]--右键菜单列表,ContextMenuItem见下方说明

ContextMenuItem

属性类型说明
labelstring文本
iconstring图标,参考图标组件
disabledboolean是否禁用
handler()=>void点击触发函数
+ + + + \ No newline at end of file diff --git a/components/functional/loading.html b/components/functional/loading.html new file mode 100644 index 00000000..67e6daf0 --- /dev/null +++ b/components/functional/loading.html @@ -0,0 +1,84 @@ + + + + + + Loading | Vben Admin + + + + + + + + + + + + + + + + +

Loading

Usage

<template>
+  <div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">
+    <a-alert message="函数方式" />
+
+    <a-button class="my-4 mr-4" type="primary" @click="openFnFullLoading">全屏 Loading</a-button>
+    <a-button class="my-4" type="primary" @click="openFnWrapLoading">容器内 Loading</a-button>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, toRefs, ref } from 'vue';
+  import { Loading, useLoading } from '/@/components/Loading';
+  export default defineComponent({
+    components: { Loading },
+    setup() {
+      const [openFullLoading, closeFullLoading] = useLoading({
+        tip: '加载中...',
+      });
+
+      const [openWrapLoading, closeWrapLoading] = useLoading({
+        target: wrapEl,
+        props: {
+          tip: '加载中...',
+          absolute: true,
+        },
+      });
+
+      function openFnFullLoading() {
+        openFullLoading();
+
+        setTimeout(() => {
+          closeFullLoading();
+        }, 2000);
+      }
+
+      function openFnWrapLoading() {
+        openWrapLoading();
+
+        setTimeout(() => {
+          closeWrapLoading();
+        }, 2000);
+      }
+
+      return {
+        openFnFullLoading,
+        openFnWrapLoading,
+        ...toRefs(compState),
+      };
+    },
+  });
+</script>
+

useLoading

使用

import { useLoading } from '/@/components/Loading';
+
+const [open, close, setTip] = useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOptions>);
+

UseLoadingOptions

属性类型默认值可选值说明
targetHTMLElement or Ref<HTMLElement>--挂载的 dom 节点
propsLoadingProps--loading 组件参数

LoadingProps

属性类型默认值可选值说明
tipstring--加载文本
sizedefault, small , largedefault-大小
absolutebooleanfalse-绝对定位,为 false 时可以全屏
loadingboolean--当前加载状态
backgroundstring--背景色,
theme'dark' or 'light'light-背景色主题 ,当背景色不为空时使用背景色

返回值

open

打开 loading

close

关闭 loading

setTip

设置加在提示文案(v2.6.2以上版本)

+ + + + \ No newline at end of file diff --git a/components/functional/preview.html b/components/functional/preview.html new file mode 100644 index 00000000..dc637e70 --- /dev/null +++ b/components/functional/preview.html @@ -0,0 +1,78 @@ + + + + + + Preview | Vben Admin + + + + + + + + + + + + + + + + +

Preview

将图片预览组件组件函数化。通过函数方便创建组件

Usage

<template>
+  <div class="p-4">
+    <Alert message="有预览图" type="info" />
+    <div class="flex justify-center mt-4">
+      <img :src="img" v-for="img in imgList" :key="img" class="mr-2" @click="handleClick(img)" />
+    </div>
+    <Alert message="无预览图" type="info" />
+    <a-button @click="handlePreview" type="primary" class="mt-4">预览图片</a-button>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { Alert } from 'ant-design-vue';
+  import { createImgPreview } from '/@/components/Preview/index';
+  const imgList: string[] = [
+    'https://picsum.photos/id/66/346/216',
+    'https://picsum.photos/id/67/346/216',
+    'https://picsum.photos/id/68/346/216',
+  ];
+  export default defineComponent({
+    components: { Alert },
+    setup() {
+      function handleClick(img: string) {
+        createImgPreview({ imageList: [img] });
+      }
+
+      function handlePreview() {
+        createImgPreview({ imageList: imgList });
+      }
+      return { imgList, handleClick, handlePreview };
+    },
+  });
+</script>
+

createImgPreview

参数/Options

属性类型默认值可选值说明
imgListstring[]--图片列表
indexnumber0-初始预览时的图片索引
scaleStepnumber--缩放步进值(每次缩放的幅度)。默认为自动(当前缩放值的10%)
defaultWidthnumber--默认宽度(单位px)。当提供此值时,所有图片初始时都会被缩放至此宽度
maskClosablebooleanfalsetrue/false点击遮罩时是否自动关闭预览
rememberStatebooleanfalsetrue/false是否记住每张图片各自的缩放状态
onImgLoad({ index: number, url: string, dom: HTMLImageElement }) => void--图片加载成功时的回调函数
onImgError({ index: number, url: string, dom: HTMLImageElement }) => void--图片加载失败时的回调函数

返回值/PreviewActions

可用于控制当前预览状态

interface PreviewActions {
+  // 重置状态
+  resume: () => void;
+  // 关闭预览
+  close: () => void;
+  // 显示前一张
+  prev: () => void;
+  // 显示后一张
+  next: () => void;
+  // 设置缩放比例(针对当前图片)
+  setScale: (scale: number) => void;
+  // 设置旋转角度(针对当前图片)
+  setRotate: (rotate: number) => void;
+}
+
+ + + + \ No newline at end of file diff --git a/components/glob/button.html b/components/glob/button.html new file mode 100644 index 00000000..3dbc49ee --- /dev/null +++ b/components/glob/button.html @@ -0,0 +1,36 @@ + + + + + + button 按钮 | Vben Admin + + + + + + + + + + + + + + + + +

button 按钮

二次封装按钮组件,且使用相同的组件名替换全局的 a-button 组件

TIP

  • 按钮不需要 import,已经全局注册,直接使用 a-button 标签即可
  • 如果是 Tsx 文件,需要手动 import

Usage

<template>
+  <a-button color="success">成功按钮</a-button>
+  <a-button color="error">错误按钮</a-button>
+  <a-button color="warning">警告按钮</a-button>
+</template>
+

Props

提示

保持 ant design button 组件 原有功能的情况下扩展以下属性

属性类型默认值说明
color'error','warning', 'success'-按钮的颜色场景状态颜色,
preIconstring-按钮文本前图标,参考 Icon 组件
postIconstring-按钮文本后图标,参考 Icon 组件
iconSizenumber14按钮图标大小
+ + + + \ No newline at end of file diff --git a/components/icon.html b/components/icon.html new file mode 100644 index 00000000..1bbcdb92 --- /dev/null +++ b/components/icon.html @@ -0,0 +1,66 @@ + + + + + + icon 图标组件 | Vben Admin + + + + + + + + + + + + + + + + +

icon 图标组件

Icon

用于项目内组件的展示,基本支持所有图标库(支持按需加载,只打包所用到的图标)

icon 组件位于 src/components/Icon

TIP

icon 的值可以在 IconifyNetlify 上查询

Usage

<template>
+  <Icon icon="gg:loadbar-doc"></Icon>
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { Icon } from '/@/components/Icon';
+  export default defineComponent({
+    components: { Icon },
+  });
+</script>
+

Props

属性类型默认值说明
iconstring-图标名
colorstring-图标颜色
sizenumber16图标大小
prefixstring-图标前缀

提示

如果 icon 值以 |svg 结尾,则会渲染成 SvgIcon 组件

SvgIcon

用于使用项目 svg 雪碧图

Usage

<template>
+  <div>
+    <SvgIcon name="test"> </SvgIcon>
+  </div>
+</template>
+<script>
+  import { SvgIcon } from '/@/components/Icon';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { SvgIcon },
+  });
+</script>
+

Props

属性类型默认值说明
namestring-svg 图标名
sizenumber16图标大小

IconPicker

本组件详细说明请参阅图标选择器

Usage

<template>
+  <div>
+    <IconPicker />
+  </div>
+</template>
+<script>
+  import { IconPicker } from '/@/components/Icon';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { IconPicker },
+  });
+</script>
+

Props

属性类型默认值说明
widthstring100%宽度
pageSizenumber140每页显示的图标数
copybooleanfalse是否可以复制
modestringiconify备选图标池,为 svg 时,会读取所有 svg sprite 图标。详见下方说明

mode 说明

  • modeiconify时,会使用预生成的图标集数据作为备选图标池
  • modesvg时,会使用 /src/assets/icons 下的所有svg图标(可包含一级子目录)作为备选图标池,详见vite-plugin-svg-icons
+ + + + \ No newline at end of file diff --git a/components/introduction.html b/components/introduction.html new file mode 100644 index 00000000..74cd075b --- /dev/null +++ b/components/introduction.html @@ -0,0 +1,45 @@ + + + + + + 前言 | Vben Admin + + + + + + + + + + + + + + + + +

前言

注意事项

组件的 defaultXXX 属性不要使用,ant-design-vue 2.2 版本之后将会逐步移除。二次封装的组件也不兼容 defaultXXX 属性。

Usage

该项目的组件大部分没有进行全局注册。采用了按需引入注册方式,如下

<template>
+  <ConfigProvider>
+    <router-view />
+  </ConfigProvider>
+</template>
+
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { ConfigProvider } from 'ant-design-vue';
+  export default defineComponent({
+    name: 'App',
+    components: { ConfigProvider },
+  });
+</script>
+
+ + + + \ No newline at end of file diff --git a/components/json-preview.html b/components/json-preview.html new file mode 100644 index 00000000..65ad85d6 --- /dev/null +++ b/components/json-preview.html @@ -0,0 +1,47 @@ + + + + + + JsonPreview | Vben Admin + + + + + + + + + + + + + + + + +

JsonPreview

json 数据预览组件

Usage

<template>
+  <JsonPreview :data="data" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { JsonPreview } from '/@/components/CodeEditor';
+
+  export default defineComponent({
+    components: { JsonPreview },
+    setup() {
+      return {
+        data: {},
+      };
+    },
+  });
+</script>
+

Props

属性类型默认值可选值说明
dataobject--需要预览的 Json 数据
+ + + + \ No newline at end of file diff --git a/components/lazy-container.html b/components/lazy-container.html new file mode 100644 index 00000000..5c7a92fe --- /dev/null +++ b/components/lazy-container.html @@ -0,0 +1,73 @@ + + + + + + LazyContainer | Vben Admin + + + + + + + + + + + + + + + + +

LazyContainer

延时加载/懒加载组件, 只在组件可见或者延迟一段时间才进行加载

Usage

<template>
+  <div class="p-4 lazy-base-demo">
+    <div class="lazy-base-demo-wrap">
+      <h1>向下滚动</h1>
+      <LazyContainer @init="() => {}">
+        <TargetContent />
+        <template #skeleton>
+          <Skeleton :rows="10" />
+        </template>
+      </LazyContainer>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { Skeleton } from 'ant-design-vue';
+  import TargetContent from './TargetContent.vue';
+  import { LazyContainer } from '/@/components/Container/index';
+  export default defineComponent({
+    components: { LazyContainer, TargetContent, Skeleton },
+  });
+</script>
+<style lang="less" scoped>
+  .lazy-base-demo {
+    &-wrap {
+      display: flex;
+      width: 50%;
+      height: 2000px;
+      margin: 20px auto;
+      text-align: center;
+      background: #fff;
+      justify-content: center;
+      flex-direction: column;
+      align-items: center;
+    }
+
+    h1 {
+      height: 1300px;
+      margin: 20px 0;
+    }
+  }
+</style>
+

Props

属性类型默认值可选值说明
timeoutnumber--等待时间,如果指定了时间,不论可见与否,在指定时间之后自动加载
viewportHTMLElement--组件所在的视口,如果组件是在页面容器内滚动,视口就是该容器
thresholdstring0px-预加载阈值, css 单位
direction'vertical', 'horizontal' , vertical-视口的滚动方向, vertical 代表垂直方向,horizontal 代表水平方向
tagstring'div-包裹组件的外层容器的标签名
transitionNamestring'lazy-container-transition 动画 name
maxWaitingTimenumber'80-最大等待时间

Events

事件回调参数说明
init()=>void初始化之后

Slots

名称说明
default默认区域
skeleton懒加载骨架屏
+ + + + \ No newline at end of file diff --git a/components/loading.html b/components/loading.html new file mode 100644 index 00000000..02c10083 --- /dev/null +++ b/components/loading.html @@ -0,0 +1,74 @@ + + + + + + Loading | Vben Admin + + + + + + + + + + + + + + + + +

Loading

Usage

<template>
+  <div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">
+    <a-button class="my-4 mr-4" type="primary" @click="openCompFullLoading">全屏 Loading</a-button>
+    <a-button class="my-4" type="primary" @click="openCompAbsolute">容器内 Loading</a-button>
+    <Loading :loading="loading" :absolute="absolute" :tip="tip" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, toRefs, ref } from 'vue';
+  import { Loading } from '/@/components/Loading';
+  export default defineComponent({
+    components: { Loading },
+    setup() {
+      const compState = reactive({
+        absolute: false,
+        loading: false,
+        tip: '加载中...',
+      });
+
+      function openLoading(absolute: boolean) {
+        compState.absolute = absolute;
+        compState.loading = true;
+        setTimeout(() => {
+          compState.loading = false;
+        }, 2000);
+      }
+
+      function openCompFullLoading() {
+        openLoading(false);
+      }
+
+      function openCompAbsolute() {
+        openLoading(true);
+      }
+
+      return {
+        openCompFullLoading,
+        openCompAbsolute,
+        ...toRefs(compState),
+      };
+    },
+  });
+</script>
+

Props

属性类型默认值可选值说明
tipstring--加载文本
sizedefault, small , largedefault-大小
absolutebooleanfalse-绝对定位,为 false 时可以全屏
loadingboolean--当前加载状态
backgroundstring--背景色
theme'dark' or 'light'light-背景色主题,当背景色不为空时使用背景色
+ + + + \ No newline at end of file diff --git a/components/markdown.html b/components/markdown.html new file mode 100644 index 00000000..e468bcdf --- /dev/null +++ b/components/markdown.html @@ -0,0 +1,64 @@ + + + + + + Markdown | Vben Admin + + + + + + + + + + + + + + + + +

Markdown

基于 Vditor 的 MarkDown 编辑器

Usage

<template>
+  <div class="p-4">
+    <a-button @click="toggleTheme" class="mb-2" type="primary">黑暗主题</a-button>
+    <MarkDown v-model:value="value" ref="markDownRef" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { MarkDown, MarkDownActionType } from '/@/components/Markdown';
+  export default defineComponent({
+    components: { MarkDown },
+    setup() {
+      const markDownRef = ref<Nullable<MarkDownActionType>>(null);
+      const valueRef = ref(`
+# title
+
+# content
+`);
+
+      function toggleTheme() {
+        const markDown = unref(markDownRef);
+        if (!markDown) return;
+        const vditor = markDown.getVditor();
+        vditor.setTheme('dark');
+      }
+      return {
+        value: valueRef,
+        toggleTheme,
+        markDownRef,
+      };
+    },
+  });
+</script>
+

Props

TIP

除以下两个外,props 还可以传入 vidtor 的所有属性。可用 v-bind 统一绑定

属性类型默认值可选值说明
v-modelstring--双向绑定文本值
heightnumber--高度

Methods

名称回调参数说明
getVditorFunction获取 vditor 实例
+ + + + \ No newline at end of file diff --git a/components/modal.html b/components/modal.html new file mode 100644 index 00000000..23d634ff --- /dev/null +++ b/components/modal.html @@ -0,0 +1,114 @@ + + + + + + Modal 弹窗 | Vben Admin + + + + + + + + + + + + + + + + +

Modal 弹窗

对 antv 的 modal 组件进行封装,扩展拖拽,全屏,自适应高度等功能

代码路径 src/components/Modal

Usage

由于弹窗内代码一般作为单文件组件存在,也推荐这样做,所以示例都为单文件组件形式

TIP

注意 v-bind="$attrs"记得写,用于将弹窗组件的 attribute 传入 BasicModal 组件

// Modal.vue
+<template>
+  <BasicModal v-bind="$attrs" title="Modal Title" :helpMessage="['提示1', '提示2']">
+    Modal Info.
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicModal } from '/@/components/Modal';
+  export default defineComponent({
+    components: { BasicModal },
+    setup() {
+      return {};
+    },
+  });
+</script>
+

页面引用弹窗

// Page.vue
+<template>
+  <div class="px-10">
+    <Modal @register="register" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { useModal } from '/@/components/Modal';
+  import Modal from './Modal.vue';
+  export default defineComponent({
+    components: { Modal },
+    setup() {
+      const [register, { openModal }] = useModal();
+      return {
+        register,
+        openModal,
+      };
+    },
+  });
+</script>
+

useModal

用于外部组件调用

useModal 用于操作组件

const [register, { openModal, setModalProps }] = useModal();
+

register

register 用于注册 useModal,如果需要使用 useModal 提供的 api,必须将 register 传入组件的 onRegister

原理其实很简单,就是 vue 的组件子传父通信,内部通过 emit("register",instance) 实现。

同时独立出去的组件需要将 attrs 绑定到 BasicModal 上面。

<template>
+  <BasicModal v-bind="$attrs"></BasicModal>
+</template>
+

openModal

用于打开/关闭弹窗

// true/false: 打开关闭弹窗
+// data: 传递到子组件的数据
+openModal(true, data);
+

closeModal

用于关闭弹窗

closeModal();
+

setModalProps

用于更改 modal 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setModalProps 方便更改内部 modal 的 props

Props 内容可以见下方

setModalProps(props);
+

useModalInner

用于独立的 Modal 内部调用

Usage

<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="Modal Title"
+    :helpMessage="['提示1', '提示2']"
+  >
+    <a-button type="primary" @click="closeModal" class="mr-2">从内部关闭弹窗</a-button>
+
+    <a-button type="primary" @click="setModalProps">从内部修改title</a-button>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  export default defineComponent({
+    components: { BasicModal },
+    setup() {
+      const [register, { closeModal, setModalProps }] = useModalInner();
+      return {
+        register,
+        closeModal,
+        setModalProps: () => {
+          setModalProps({ title: 'Modal New Title' });
+        },
+      };
+    },
+  });
+</script>
+

useModalInner用于操作独立组件

const [register, { closeModal, setModalProps }] = useModalInner(callback);
+

callback

type: (data:any)=>void

回调函数用于接收 openModal 第二个参数传递的值

useModal((data: any) => {
+  console.log(data);
+});
+

closeModal

用于关闭弹窗

closeModal();
+

changeOkLoading

用于修改确认按钮的 loading 状态

changeOkLoading(true);
+

changeLoading

用于修改 modal 的 loading 状态

// true or false
+changeLoading(true);
+

setModalProps

用于更改 modal 的 props 参数因为 modal 内容独立成组件,如果在外部页面需要更改 props 可能比较麻烦,所以提供 setModalProps 方便更改内部 modal 的 props

Props 内容可以见下方

Props

TIP

除以下参数外,组件库文档内的 props 也都支持,具体可以参考 antv modal

属性类型默认值可选值说明
titlestring--modal 标题
heightnumber--固定 modal 的高度
minHeightnumber--设置 modal 的最小高度
draggablebooleantruetrue/false是否开启拖拽
useWrapperbooleantruetrue/false是否开启自适应高度,开启后会跟随屏幕变化自适应内容,并出现滚动条
wrapperFooterOffsetnumber0-开启是适应高度后,如果超过屏幕高度,底部和顶部会保持一样的间距,该参数可以用来缩小底部的间距
canFullscreenbooleantruetrue/false是否可以进行全屏
defaultFullscreenbooleanfalsetrue/false默认全屏
loadingbooleanfalsetrue/falseloading 状态
loadingTipstring--loading 文本
showCancelBtnbooleantruetrue/false显示关闭按钮
showOkBtnbooleantruetrue/false显示确认按钮
helpMessagestring , string[]--标题右侧提示文本
centeredbooleanfalsetrue/false是否居中弹窗
cancelTextstring'关闭'-关闭按钮文本
okTextstring'保存'-确认按钮文本
closeFunc() => Promise<boolean>关闭函数-关闭前执行,返回 true 则关闭,否则不关闭

Events

事件回调参数说明
okfunction(e)点击确定回调
cancelfunction(e)点击取消回调
visible-change(visible:boolean)=>{}打开或者关闭触发

Slots

名称说明
default默认区域
footer底部区域(会替换掉默认的按钮)
insertFooter关闭按钮的左边(不使用footer插槽时有效)
centerFooter关闭按钮和确认按钮的中间(不使用footer插槽时有效)
appendFooter确认按钮的右边(不使用footer插槽时有效)
+ + + + \ No newline at end of file diff --git a/components/page.html b/components/page.html new file mode 100644 index 00000000..2ed47303 --- /dev/null +++ b/components/page.html @@ -0,0 +1,67 @@ + + + + + + Page | Vben Admin + + + + + + + + + + + + + + + + +

Page

页面相关组件

PageWrapper

用于包裹页面组件

Usage

<template>
+  <div>
+    <PageWrapper>
+      <template #left>left</template>
+      <template #right>right</template>
+    </PageWrapper>
+  </div>
+</template>
+<script>
+  import { PageWrapper } from '/@/components/Page';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { PageWrapper },
+    setup() {
+      return {};
+    },
+  });
+</script>
+

Props

属性类型默认值说明
titlestring-pageHeader title
dense是否缩小主体区域false为 true 将会取消 padding/margin
contentstring-pageHeader Content 内容
contentStyleobject-主体区域样式
contentClassstring-主体区域 class
contentBackgroundboolean-主体区域背景
contentFullHeightbooleanfalse主体区域是否占满整个屏幕高度
fixedHeightbooleanfalse固定主体区域高度

Slots

pageHeader 的 slot 都支持

名称说明
leftFooterPageFooter 左侧区域
rightFooterPageFooter 右侧区域
headerContentpageHeader 主体内容
default主体区域

用于页面底部工具栏

使用

<template>
+  <div>
+    <PageFooter>
+      <template #left>left</template>
+      <template #right>right</template>
+    </PageFooter>
+  </div>
+</template>
+<script>
+  import { PageFooter } from '/@/components/Page';
+  import { defineComponent } from 'vue';
+  export default defineComponent({
+    components: { PageFooter },
+    setup() {
+      return {};
+    },
+  });
+</script>
+

Slots

名称说明
left左侧区域
right右侧区域
+ + + + \ No newline at end of file diff --git a/components/pop-confirm-button.html b/components/pop-confirm-button.html new file mode 100644 index 00000000..3e77a99c --- /dev/null +++ b/components/pop-confirm-button.html @@ -0,0 +1,42 @@ + + + + + + PopConfirmButton 按钮 | Vben Admin + + + + + + + + + + + + + + + + +

PopConfirmButton 按钮

带有 PopConfirm 下拉菜单功能的按钮

Usage

<template>
+  <PopConfirmButton>按钮文本</PopConfirmButton>
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { PopConfirmButton } from '/@/components/Button';
+  export default defineComponent({
+    components: { PopConfirmButton },
+  });
+</script>
+

Props

提示

保持 anv design popconfirm 组件 原有功能的情况下扩展以下属性

属性类型默认值说明
enablebooleantrue是否启用下拉菜单,为 false 则显示默认按钮
+ + + + \ No newline at end of file diff --git a/components/qrcode.html b/components/qrcode.html new file mode 100644 index 00000000..90370be8 --- /dev/null +++ b/components/qrcode.html @@ -0,0 +1,122 @@ + + + + + + QrCode | Vben Admin + + + + + + + + + + + + + + + + +

QrCode

用于生成二维码的组件

Usage

<template>
+  <QrCode :value="qrCodeUrl" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { QrCode, QrCodeActionType } from '/@/components/Qrcode/index';
+  import LogoImg from '/@/assets/images/logo.png';
+  const qrCodeUrl = 'https://www.vvbin.cn';
+  export default defineComponent({
+    components: { QrCode },
+    setup() {
+      const qrRef = ref<Nullable<QrCodeActionType>>(null);
+      function download() {
+        const qrEl = unref(qrRef);
+        if (!qrEl) return;
+        qrEl.download('文件名');
+      }
+      return {
+        qrCodeUrl,
+        LogoImg,
+        download,
+        qrRef,
+      };
+    },
+  });
+</script>
+<style scoped>
+  .qrcode-demo-item {
+    width: 30%;
+    margin-right: 1%;
+  }
+</style>
+

Props

属性类型默认值可选值说明
valuestring--二维码地址
optionsQRCodeRenderersOptions--二维码配置 ,见 QRCodeRenderersOptions
widthnumber2-宽度
logostring|LogoType--中间 logo 配置,见 LogoType
tag渲染标签canvascanvas | imgimg 不支持内嵌 logo

QRCodeRenderersOptions

/**
+ * 定义margin的宽度。.
+ * Default: 4
+ */
+margin?: number;
+/**
+ * 比例因子。值1表示每个模块1像素(黑点)。
+ * Default: 4
+ */
+scale?: number;
+/**
+ * 为输出图像强制指定宽度。
+ * 如果宽度太小而不能包含qr符号,则此选项将被忽略。
+ * 优先于规模。
+ */
+width?: number;
+color?: {
+  /**
+   * 暗模块的颜色。值必须为十六进制格式(RGBA).
+   * 注意:深色应始终比color.light暗。.
+   * Default: #000000ff
+   */
+  dark?: string;
+  /**
+   * 照明模块的颜色。值必须为十六进制格式(RGBA).
+   * Default: #ffffffff
+   */
+  light?: string;
+};
+
+

LogoType

{
+  // logo图片
+  src: string;
+  // logo大小
+  logoSize: number;
+  // 背景颜色
+  bgColor: string;
+  // logo圆角
+  logoRadius: number;
+}
+

Methods

名称回调参数说明
downloadFunction(fileName:string)下载

事件

名称回调参数说明
done(data: QrcodeDoneEventParams)=>void绘制完成
error(error)=>void生成二维码时发生错误

QrcodeDoneEventParams

{
+  url: string;  // 二维码DataURL数据
+  ctx?: CanvasRenderingContext2D;  // 该对象为画布的2D渲染上下文,仅在tag为canvas时有效,可用于自定义绘制
+}
+

done 事件回调中可以对二维码进行自定义的绘制,示例代码如下:

<QrCode
+  :value="qrCodeUrl"
+  :width="200"
+  @done="onQrcodeDone"
+/>
+
function onQrcodeDone({ ctx }) {
+  if (ctx instanceof CanvasRenderingContext2D) {
+    // 额外绘制
+    ctx.fillStyle = 'black';
+    ctx.font = '16px "微软雅黑"';
+    ctx.textBaseline = 'bottom';
+    ctx.textAlign = 'center';
+    ctx.fillText('你帅你先扫', 100, 195, 200);
+  }
+}
+

有关 CanvasRenderingContext2D 的更多资料以及绘制方法,请参考MDN

+ + + + \ No newline at end of file diff --git a/components/scroll-container.html b/components/scroll-container.html new file mode 100644 index 00000000..dfcf52c5 --- /dev/null +++ b/components/scroll-container.html @@ -0,0 +1,89 @@ + + + + + + ScrollContainer | Vben Admin + + + + + + + + + + + + + + + + +

ScrollContainer

参考 element-ui 的 el-scrollbar 组件实现

滚动容器组件

Usage

<template>
+  <div class="p-4">
+    <div class="my-4">
+      <a-button @click="scrollTo(100)">滚动到100px位置</a-button>
+      <a-button @click="scrollTo(800)">滚动到800px位置</a-button>
+      <a-button @click="scrollTo(0)">滚动到顶部</a-button>
+      <a-button @click="scrollBottom()">滚动到底部</a-button>
+    </div>
+    <div class="scroll-wrap">
+      <ScrollContainer ref="scrollRef">
+        <ul>
+          <template v-for="index in 100" :key="index">
+            <li>{{ index }}</li>
+          </template>
+        </ul>
+      </ScrollContainer>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import { ScrollContainer, ScrollActionType } from '/@/components/Container/index';
+  export default defineComponent({
+    components: { CollapseContainer, ScrollContainer },
+    setup() {
+      const scrollRef = ref<Nullable<ScrollActionType>>(null);
+      const getScroll = () => {
+        const scroll = unref(scrollRef);
+        if (!scroll) {
+          throw new Error('scroll is Null');
+        }
+        return scroll;
+      };
+
+      function scrollTo(top: number) {
+        getScroll()?.scrollTo(top);
+      }
+
+      function scrollBottom() {
+        getScroll()?.scrollBottom();
+      }
+
+      return {
+        scrollTo,
+        scrollRef,
+        scrollBottom,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .scroll-wrap {
+    width: 50%;
+    height: 300px;
+    background: #fff;
+  }
+</style>
+

Methods

名称回调参数说明
getScrollWrap()=>HtmlElement获取滚动容器 el
scrollBottomFunction滚动到底部
scrollToFunction(to:number,duration = 500)滚动到指定位置

Slots

名称说明
default默认区域
+ + + + \ No newline at end of file diff --git a/components/strength-meter.html b/components/strength-meter.html new file mode 100644 index 00000000..2f938e0e --- /dev/null +++ b/components/strength-meter.html @@ -0,0 +1,58 @@ + + + + + + StrengthMeter | Vben Admin + + + + + + + + + + + + + + + + +

StrengthMeter

用于校验密码强度

Usage

<template>
+  <div class="p-4 flex justify-center">
+    <div class="demo-wrap p-10">
+      <StrengthMeter placeholder="默认" />
+      <StrengthMeter placeholder="禁用" disabled />
+      <br />
+      <StrengthMeter placeholder="隐藏input" :show-input="false" value="!@#qwe12345" />
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import StrengthMeter from '/@/components/StrengthMeter/index';
+  export default defineComponent({
+    components: {
+      StrengthMeter,
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .demo-wrap {
+    width: 50%;
+    background: #fff;
+    border-radius: 10px;
+  }
+</style>
+

Props

属性类型默认值可选值说明
valuestring--校验的值
showInputbooleantrue-是否显示 input
disabledbooleanfalse-是否禁用

Events

事件回调参数说明
score-changenumber强度值改变触发
changestringinput 值改变触发
+ + + + \ No newline at end of file diff --git a/components/table.html b/components/table.html new file mode 100644 index 00000000..74eb7ca5 --- /dev/null +++ b/components/table.html @@ -0,0 +1,342 @@ + + + + + + Table 表格 | Vben Admin + + + + + + + + + + + + + + + + +

Table 表格

antv 的 table 组件进行封装

如果文档内没有,可以尝试在在线示例内寻找

Usage

示例

<template>
+  <div class="p-4">
+    <BasicTable
+      title="基础示例"
+      titleHelpMessage="温馨提醒"
+      :columns="columns"
+      :dataSource="data"
+      :canResize="canResize"
+      :loading="loading"
+      :striped="striped"
+      :bordered="border"
+      :pagination="{ pageSize: 20 }"
+    >
+      <template #toolbar>
+        <a-button type="primary"> 操作按钮 </a-button>
+      </template>
+    </BasicTable>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { BasicTable } from '/@/components/Table';
+  import { getBasicColumns, getBasicData } from './tableData';
+
+  export default defineComponent({
+    components: { BasicTable },
+    setup() {
+      return {
+        columns: getBasicColumns(),
+        data: getBasicData(),
+      };
+    },
+  });
+</script>
+

template 示例

所有可调用函数见下方 Methods 说明

<template>
+  <div class="p-4">
+    <BasicTable
+      :canResize="false"
+      title="RefTable示例"
+      titleHelpMessage="使用Ref调用表格内方法"
+      ref="tableRef"
+      :api="api"
+      :columns="columns"
+      rowKey="id"
+      :rowSelection="{ type: 'checkbox' }"
+    />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { BasicTable, TableActionType } from '/@/components/Table';
+  import { getBasicColumns, getBasicShortColumns } from './tableData';
+  import { demoListApi } from '/@/api/demo/table';
+  export default defineComponent({
+    components: { BasicTable },
+    setup() {
+      const tableRef = ref<Nullable<TableActionType>>(null);
+
+      function getTableAction() {
+        const tableAction = unref(tableRef);
+        if (!tableAction) {
+          throw new Error('tableAction is null');
+        }
+        return tableAction;
+      }
+      function changeLoading() {
+        getTableAction().setLoading(true);
+        setTimeout(() => {
+          getTableAction().setLoading(false);
+        }, 1000);
+      }
+      return {
+        tableRef,
+        api: demoListApi,
+        columns: getBasicColumns(),
+        changeLoading,
+      };
+    },
+  });
+</script>
+

BasicColumn 和 tableAction 通过权限和业务控制显示隐藏的示例

<template>
+  <div class="p-4">
+    <BasicTable @register="registerTable">
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '编辑',
+              onClick: handleEdit.bind(null, record),
+              auth: 'other', // 根据权限控制是否显示: 无权限,不显示
+            },
+            {
+              label: '删除',
+              icon: 'ic:outline-delete-outline',
+              onClick: handleDelete.bind(null, record),
+              auth: 'super', // 根据权限控制是否显示: 有权限,会显示
+            },
+          ]"
+          :dropDownActions="[
+            {
+              label: '启用',
+              popConfirm: {
+                title: '是否启用?',
+                confirm: handleOpen.bind(null, record),
+              },
+              ifShow: (_action) => {
+                return record.status !== 'enable'; // 根据业务控制是否显示: 非enable状态的不显示启用按钮
+              },
+            },
+            {
+              label: '禁用',
+              popConfirm: {
+                title: '是否禁用?',
+                confirm: handleOpen.bind(null, record),
+              },
+              ifShow: () => {
+                return record.status === 'enable'; // 根据业务控制是否显示: enable状态的显示禁用按钮
+              },
+            },
+            {
+              label: '同时控制',
+              popConfirm: {
+                title: '是否动态显示?',
+                confirm: handleOpen.bind(null, record),
+              },
+              auth: 'super', // 同时根据权限和业务控制是否显示
+              ifShow: () => {
+                return true; // 根据业务控制是否显示
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
+
+  import { demoListApi } from '/@/api/demo/table';
+  const columns: BasicColumn[] = [
+    {
+      title: '姓名',
+      dataIndex: 'name',
+      auth: 'test', // 根据权限控制是否显示: 无权限,不显示
+    },
+    {
+      title: '地址',
+      dataIndex: 'address',
+      auth: 'super', // 同时根据权限控制是否显示
+      ifShow: (_column) => {
+        return true; // 根据业务控制是否显示
+      },
+    },
+  ];
+  export default defineComponent({
+    components: { BasicTable, TableAction },
+    setup() {
+      const [registerTable] = useTable({
+        title: 'TableAction组件及固定列示例',
+        api: demoListApi,
+        columns: columns,
+        bordered: true,
+        actionColumn: {
+          width: 250,
+          title: 'Action',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+      });
+      function handleEdit(record: Recordable) {
+        console.log('点击了编辑', record);
+      }
+      function handleDelete(record: Recordable) {
+        console.log('点击了删除', record);
+      }
+      function handleOpen(record: Recordable) {
+        console.log('点击了启用', record);
+      }
+      return {
+        registerTable,
+        handleEdit,
+        handleDelete,
+        handleOpen,
+      };
+    },
+  });
+</script>
+

useTable

使用组件自带的 useTable 可以方便使用表单

下面是一个使用简单表格的示例,

<template>
+  <BasicTable @register="registerTable" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable } from '/@/components/Table';
+  import { getBasicColumns, getBasicShortColumns } from './tableData';
+  import { demoListApi } from '/@/api/demo/table';
+  export default defineComponent({
+    components: { BasicTable },
+    setup() {
+      const [
+        registerTable,
+        {
+          setLoading,
+        },
+      ] = useTable({
+        api: demoListApi,
+        columns: getBasicColumns(),
+      });
+
+      function changeLoading() {
+        setLoading(true);
+        setTimeout(() => {
+          setLoading(false);
+        }, 1000);
+      }
+      }
+      return {
+        registerTable,
+        changeLoading,
+      };
+    },
+  });
+</script>
+

Usage

用于调用 Table 内部方法及 table 参数配置

// 表格的props也可以直接注册到useTable内部
+const [register, methods] = useTable(props);
+

register

register 用于注册 useTable,如果需要使用useTable提供的 api,必须将 register 传入组件的 onRegister

<template>
+  <BasicTable @register="register" />
+</template>
+<script>
+  export default defineComponent({
+    components: { BasicForm },
+    setup() {
+      const [register] = useTable();
+      return { register };
+    },
+  });
+</script>
+

Methods

setProps

类型:(props: Partial<BasicTableProps>) => void

说明: 用于设置表格参数

reload

类型:(opt?: FetchParams) => Promise<void>

说明: 刷新表格

redoHeight

类型:() => void

说明: 重新计算表格高度

setLoading

类型:(loading: boolean) => void

说明: 设置表格 loading 状态

getDataSource

获取表格数据

类型:<T = Recordable>() => T[]

说明: 获取表格数据

getRawDataSource

获取后端接口原始数据

类型:<T = Recordable>() => T

说明: 获取后端接口原始数据

getColumns

类型:(opt?: GetColumnsParams) => BasicColumn[]

说明: 获取表格数据

setColumns

类型:(columns: BasicColumn[] | string[]) => void

说明: 设置表头数据

setTableData

类型:<T = Recordable>(values: T[]) => void

说明: 设置表格数据

setPagination

类型:(info: Partial<PaginationProps>) => void

说明: 设置分页信息

deleteSelectRowByKey

类型:(key: string) => void

说明: 根据 key 删除取消选中行

getSelectRowKeys

类型:() => string[]

说明: 获取选中行的 keys

getSelectRows

类型:<T = Recordable>() => T[]

说明: 获取选中行的 rows

clearSelectedRowKeys

类型:() => void

说明: 清空选中行

setSelectedRowKeys

类型:(rowKeys: string[] | number[]) => void

说明: 设置选中行

getPaginationRef

类型:() => PaginationProps | boolean

说明: 获取当前分页信息

getShowPagination

类型:() => boolean

说明: 获取当前是否显示分页

setShowPagination

类型:(show: boolean) => Promise<void>

说明: 设置当前是否显示分页

getRowSelection

类型:() => TableRowSelection<Recordable>

说明: 获取勾选框信息

updateTableData

类型:(index: number, key: string, value: any)=>void

说明: 更新表格数据

updateTableDataRecord

类型: (rowKey: string | number, record: Recordable) => Recordable | void

说明: 根据唯一的 rowKey 更新指定行的数据.可用于不刷新整个表格而局部更新数据

deleteTableDataRecord

类型: (rowKey: string | number | string[] | number[]) => void

说明: 根据唯一的rowKey 动态删除指定行的数据.可用于不刷新整个表格而局部更新数据

insertTableDataRecord

类型: (record: Recordable, index?: number) => Recordable | void

说明: 可根据传入的 index 值决定插入数据行的位置,不传则是顺序插入,可用于不刷新整个表格而局部更新数据

getForm

类型:() => FormActionType

说明: 如果开启了搜索区域。可以通过该函数获取表单对象函数进行操作

expandAll

类型:() => void

说明: 展开树形表格

collapseAll

类型:() => void

说明: 折叠树形表格

Props

温馨提醒

  • 除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv table
  • 注意:defaultExpandAllRowsdefaultExpandedRowKeys 属性在basicTable中不受支持,并且在antv table v2.2.0之后也被移除。
属性类型默认值可选值说明版本
clickToRowSelectbooleantrue-点击行是否选中 checkbox 或者 radio。需要开启
sortFn(sortInfo: SorterResult<any>) => any--自定义排序方法。见下方全局配置说明
filterFn(sortInfo: Partial<Recordable<string[]>>) => any--自定义过滤方法。见下方全局配置说明
showTableSettingbooleanfalse-显示表格设置工具
tableSettingTableSetting--表格设置工具配置,见下方 TableSetting
stripedbooleantrue-斑马纹
insetbooleanfalse-取消表格的默认 padding
autoCreateKeybooleantrue-是否自动生成 key
showSummarybooleanfalse-是否显示合计行
summaryDataany[]--自定义合计数据。如果有则显示该数据
emptyDataIsShowTablebooleantrue-在启用搜索表单的前提下,是否在表格没有数据的时候显示表格
summaryFunc(...arg) => any[]--计算合计行的方法
canRowDragbooleanfalse-是否可拖拽行排序
canColDragbooleanfalse-是否可拖拽列
isTreeTablebooleanfalse-是否树表
api(...arg: any) => Promise<any>--请求接口,可以直接将src/api内的函数直接传入
beforeFetch(T)=>T--请求之前对参数进行处理
afterFetch(T)=>T--请求之后对返回值进行处理
handleSearchInfoFn(T)=>T--开启表单后,在请求之前处理搜索条件参数
fetchSettingFetchSetting--接口请求配置,可以配置请求的字段和响应的字段名,见下方全局配置说明
immediatebooleantrue-组件加载后是否立即请求接口,在 api 有传的情况下,如果为 false,需要自行使用 reload 加载表格数据
searchInfoany--额外的请求参数
useSearchFormbooleanfalse-使用搜索表单
formConfigany--表单配置,参考表单组件的 Props
columnsany--表单列信息 BasicColumn[]
showIndexColumnbooleanture-是否显示序号列
indexColumnPropsany--序号列配置 BasicColumn
actionColumnany--表格右侧操作列配置 BasicColumn
ellipsisbooleantrue-文本超过宽度是否显示...
canResizebooleantrue-是否可以自适应高度(如果置于PageWrapper组件内,请勿启用PageWrapper的fixedHeight属性,二者不可同时使用)
clearSelectOnPageChangebooleanfalse-切换页码是否重置勾选状态
resizeHeightOffsetnumber0-表格自适应高度计算结果会减去这个值
rowSelectionany--选择列配置
titlestring--表格标题
titleHelpMessagestring | string[]--表格标题右侧温馨提醒
maxHeightnumber--表格最大高度,超出会显示滚动条
dataSourceany[]--表格数据,非 api 加载情况
borderedbooleanfalse-是否显示表格边框
paginationany--分页信息配置,为 false 不显示分页
loadingbooleanfalse-表格 loading 状态
scrollany--参考官方文档 scroll
beforeEditSubmit({record: Recordable,index: number,key: string | number,value: any}) => Promise<any>--单元格编辑状态提交回调,返回false将阻止单元格提交数据到table。该回调在行编辑模式下无效。2.7.2

TableSetting

{
+  // 是否显示刷新按钮
+  redo?: boolean;
+  // 是否显示尺寸调整按钮
+  size?: boolean;
+  // 是否显示字段调整按钮
+  setting?: boolean;
+  // 是否显示全屏按钮
+  fullScreen?: boolean;
+}
+

BasicColumn

除 参考官方 Column 配置外,扩展以下参数

属性类型默认值可选值说明
defaultHiddenbooleanfalse-默认隐藏,可在列配置显示
helpMessagestring|string[]--列头右侧帮助文本
editboolean--是否开启单元格编辑
editRowboolean--是否开启行编辑
editablebooleanfalse-是否处于编辑状态
editComponentComponentTypeInput-编辑组件
editComponentPropsany--对应编辑组件的 props
editRule((text: string, record: Recordable) => Promise<string>)--对应编辑组件的表单校验
editValueMap(value: any) => string--对应单元格值枚举
onEditRow()=>void--触发行编辑
formatCellFormat--单元格格式化
authRoleEnumRoleEnum[]stringstring[]--根据权限编码来控制当前列是否显示
ifShowboolean | ((action: ActionItem) => boolean)--根据业务状态来控制当前列是否显示

EditComponentType

export type ComponentType =
+  | 'Input'
+  | 'InputNumber'
+  | 'Select'
+  | 'ApiSelect'
+  | 'Checkbox'
+  | 'Switch'
+  | 'DatePicker'  // v2.5.0 以上
+  | 'TimePicker'; // v2.5.0 以上
+

CellFormat

export type CellFormat =
+  | string
+  | ((text: string, record: Recordable, index: number) => string | number)
+  | Map<string | number, any>;
+

事件

温馨提醒

除以下事件外,官方文档内的 event 也都支持,具体可以参考 antv table

事件回调参数说明
fetch-successFunction({items,total})接口请求成功后触发
fetch-errorFunction(error)错误信息
selection-changeFunction({keys,rows})勾选事件触发
row-clickFunction(record, index, event)行点击触发
row-dbClickFunction(record, index, event)行双击触发
row-contextmenuFunction(record, index, event)行右键触发
row-mouseenterFunction(record, index, event)行移入触发
row-mouseleaveFunction(record, index, event)行移出触发
edit-endFunction({record, index, key, value})单元格编辑完成触发
edit-cancelFunction({record, index, key, value})单元格取消编辑触发
edit-row-endFunction()行编辑结束触发
edit-changeFunction({column,value,record})单元格编辑组件的 value 发生变化时触发

edit-change 说明

从版本 2.4.2 起,对于 edit-change 事件,record 中的 editValueRefs 装载了当前行的所有编辑组件(如果有的话)的值的 ref 对象,可用于处理同一行中的编辑组件的联动。请看下面的例子

      function onEditChange({ column, record }) {
+        // 当同一行的单价或者数量发生变化时,更新合计金额(三个数据均为当前行编辑组件的值)
+        if (column.dataIndex === 'qty' || column.dataIndex === 'price') {
+          const { editValueRefs: { total, qty, price } } = record;
+          total.value = unref(qty) * unref(price);
+        }
+      }
+

Slots

温馨提醒

除以下参数外,官方文档内的 slot 也都支持,具体可以参考 antv table

名称说明版本
tableTitle表格顶部左侧区域
toolbar表格顶部右侧区域
expandedRowRender展开行区域
headerTop表格顶部区域(标题上方)2.6.1

Form-Slots

当开启 form 表单后。以form-xxxx为前缀的 slot 会被视为 form 的 slot

xxxx 为 form 组件的 slot。具体参考form 组件文档

e.g

form-submitBefore
+

ColumnSetting组件

字段调整组件

提供了可视化操作表格每一列的是否展示、位置、固定;包括序号列、勾选列。会响应tableMethodssetColumnssetProps方法的更改内容。

值得注意的是

序号列勾选列是在table的props中定义的,对应的字段分别是showIndexColumnrowSelection。因此在动态改变表格列配置的时候,建议使用setProps方法,并显式地设置这两个字段的值来保证达到预期效果

// ...
+const [registerTable, { setProps }] = useTable({...})
+
+setProps({
+  columns: [], // 表格的列配置 BasicColumn[]
+  showIndexColumn: false, // 是否展示序号列
+  rowSelection: false // 勾选列配置
+})
+

内置组件(只能用于表格内部)

TableAction

用于表格右侧操作列渲染

Props

属性类型默认值可选值说明版本
actionsActionItem[]--右侧操作列按钮列表
dropDownActionsActionItem[]--右侧操作列更多下拉按钮列表
stopButtonPropagationbooleanfalsetrue/false是否阻止操作按钮的click事件冒泡2.5.0

ActionItem

export interface ActionItem {
+  // 按钮文本
+  label: string;
+  // 是否禁用
+  disabled?: boolean;
+  // 按钮颜色
+  color?: 'success' | 'error' | 'warning';
+  // 按钮类型
+  type?: string;
+  // button组件props
+  props?: any;
+  // 按钮图标
+  icon?: string;
+  // 气泡确认框
+  popConfirm?: PopConfirm;
+  // 是否显示分隔线,v2.0.0+
+  divider?: boolean;
+  // 根据权限编码来控制当前列是否显示,v2.4.0+
+  auth?: RoleEnum | RoleEnum[] | string | string[];
+  // 根据业务状态来控制当前列是否显示,v2.4.0+
+  ifShow?: boolean | ((action: ActionItem) => boolean);
+  // 点击回调
+  onClick?: Fn;
+  // Tooltip配置,2.5.3以上版本支持,可以配置为string,或者完整的tooltip属性
+  tooltip?: string | TooltipProps
+}
+

有关TooltipProps的说明,请参考tooltip

PopConfirm

export interface PopConfirm {
+  title: string;
+  okText?: string;
+  cancelText?: string;
+  confirm: Fn;
+  cancel?: Fn;
+  icon?: string;
+}
+

TableImg

用于渲染单元格图片,支持图片预览

Props

属性类型默认值可选值说明版本
imgListstring[]--图片地址列表
sizenumber--图片大小
simpleShowbooleanfalsetrue/false简单显示模式(只显示第一张图片)2.5.0
showBadgebooleantruetrue/false简单模式下是否显示计数Badge2.5.0
marginnumber4-常规模式下的图片间距2.5.0
srcPrefixstring--在每一个图片src前插入的内容2.5.0

全局配置

componentsSettings 可以配置全局参数。用于统一整个项目的风格。可以通过 props 传值覆盖

+ + + + \ No newline at end of file diff --git a/components/time.html b/components/time.html new file mode 100644 index 00000000..47f74856 --- /dev/null +++ b/components/time.html @@ -0,0 +1,52 @@ + + + + + + Time | Vben Admin + + + + + + + + + + + + + + + + +

Time

相对时间组件

Usage

<template>
+  <Time :value="time" />
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, toRefs } from 'vue';
+  import { Time } from '/@/components/Time';
+
+  export default defineComponent({
+    components: { Time },
+    setup() {
+      const now = new Date().getTime();
+      const state = reactive({
+        time: now - 60 * 3 * 1000,
+      });
+      return {
+        ...toRefs(state),
+        now,
+      };
+    },
+  });
+</script>
+

Props

属性类型默认值可选值说明
valuestring,Date,number--时间值
stepnumber60-刷新时间
modestringrelative-模式,date:日期,datetime:时间戳,relative:相对时间
+ + + + \ No newline at end of file diff --git a/components/tinymce.html b/components/tinymce.html new file mode 100644 index 00000000..2f102b12 --- /dev/null +++ b/components/tinymce.html @@ -0,0 +1,50 @@ + + + + + + Tinymce | Vben Admin + + + + + + + + + + + + + + + + +

Tinymce

富文本组件位于 src/components/TinyMce

富文本组件使用的是 CDN 方式引入

可在 /@/components/TinyMce/src/Editor.vue 更改下面 CDN 地址

const CDN_URL = 'https://cdn.bootcdn.net/ajax/libs/tinymce/5.5.1';
+

Usage

<template>
+  <Tinymce v-model="value" @change="handleChange" width="100%" />
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { Tinymce } from '/@/components/Tinymce/index';
+
+  export default defineComponent({
+    components: { Tinymce },
+    setup() {
+      const value = ref('hello world!');
+      function handleChange(value: string) {
+        console.log(value);
+      }
+      return { handleChange, value };
+    },
+  });
+</script>
+

Props

属性类型默认值说明
optionsany{}tinymce 的配置项
value(v-model)string-双向绑定值
heightnumber , string400高度
widthnumber , stringauto宽度
toolbarstring[]-工具栏
pluginsstring[]-插件
showImageUploadbooleantrue是否显示上传按钮

Events

事件回调参数返回值说明
change(str:string)=>{}富文本内容改变触发事件
+ + + + \ No newline at end of file diff --git a/components/transition.html b/components/transition.html new file mode 100644 index 00000000..ae796009 --- /dev/null +++ b/components/transition.html @@ -0,0 +1,125 @@ + + + + + + Transition | Vben Admin + + + + + + + + + + + + + + + + +

Transition

用于页面/组件切换动画

Usage

<template>
+  <div class="p-4">
+    <div class="flex">
+      <Select
+        :options="options"
+        v-model:value="value"
+        placeholder="选择动画"
+        :style="{ width: '150px' }"
+      />
+      <a-button type="primary" class="ml-4" @click="start"> start </a-button>
+    </div>
+    <component :is="`${value}Transition`">
+      <div class="box" v-show="show"></div>
+    </component>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { Select } from 'ant-design-vue';
+  import {
+    FadeTransition,
+    ScaleTransition,
+    SlideYTransition,
+    ScrollYTransition,
+    SlideYReverseTransition,
+    ScrollYReverseTransition,
+    SlideXTransition,
+    ScrollXTransition,
+    SlideXReverseTransition,
+    ScrollXReverseTransition,
+    ScaleRotateTransition,
+    ExpandXTransition,
+    ExpandTransition,
+  } from '/@/components/Transition/index';
+
+  const transitionList = [
+    'Fade',
+    'Scale',
+    'SlideY',
+    'ScrollY',
+    'SlideYReverse',
+    'ScrollYReverse',
+    'SlideX',
+    'ScrollX',
+    'SlideXReverse',
+    'ScrollXReverse',
+    'ScaleRotate',
+    'ExpandX',
+    'Expand',
+  ];
+  const options = transitionList.map((item) => ({
+    label: item,
+    value: item,
+    key: item,
+  }));
+
+  export default defineComponent({
+    components: {
+      Select,
+      FadeTransition,
+      ScaleTransition,
+      SlideYTransition,
+      ScrollYTransition,
+      SlideYReverseTransition,
+      ScrollYReverseTransition,
+      SlideXTransition,
+      ScrollXTransition,
+      SlideXReverseTransition,
+      ScrollXReverseTransition,
+      ScaleRotateTransition,
+      ExpandXTransition,
+      ExpandTransition,
+    },
+    setup() {
+      const value = ref('Fade');
+      const show = ref(true);
+      function start() {
+        show.value = false;
+        setTimeout(() => {
+          show.value = true;
+        }, 300);
+      }
+      return { options, value, start, show };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .box {
+    width: 150px;
+    height: 150px;
+    margin-top: 20px;
+    background: pink;
+  }
+</style>
+
+ + + + \ No newline at end of file diff --git a/components/tree.html b/components/tree.html new file mode 100644 index 00000000..f1c5ba76 --- /dev/null +++ b/components/tree.html @@ -0,0 +1,104 @@ + + + + + + Tree | Vben Admin + + + + + + + + + + + + + + + + +

Tree

antv 的 tree 组件进行封装

Usage

<template>
+  <BasicTree :treeData="treeData" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTree } from '/@/components/Tree/index';
+  import { treeData } from './data';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import { TreeItem } from '/@/components/Tree/index';
+
+  export const treeData: TreeItem[] = [
+    {
+      title: 'parent 1',
+      key: '0-0',
+      icon: 'home|svg',
+      children: [
+        { title: 'leaf', key: '0-0-0' },
+        {
+          title: 'leaf',
+          key: '0-0-1',
+          children: [
+            { title: 'leaf', key: '0-0-0-0' },
+            { title: 'leaf', key: '0-0-0-1' },
+          ],
+        },
+      ],
+    },
+    {
+      title: 'parent 2',
+      key: '1-1',
+      icon: 'home|svg',
+      children: [
+        { title: 'leaf', key: '1-1-0' },
+        { title: 'leaf', key: '1-1-1' },
+      ],
+    },
+    {
+      title: 'parent 3',
+      key: '2-2',
+      icon: 'home|svg',
+      children: [
+        { title: 'leaf', key: '2-2-0' },
+        { title: 'leaf', key: '2-2-1' },
+      ],
+    },
+  ];
+  export default defineComponent({
+    components: { BasicTree, CollapseContainer },
+    setup() {
+      return { treeData };
+    },
+  });
+</script>
+

Props

温馨提醒

除以下参数外,官方文档内的 props 也都支持,具体可以参考 antv tree

属性类型默认值可选值说明版本
treeDataTreeItem[]--树组件数据
rightMenuListContextMenuItem[]--右键菜单列表
checkedKeysstring[]--勾选的节点
selectedKeysstring[]--选中的节点
expandedKeysstring[]--展开的节点
actionListActionItem[]--鼠标移动上去右边操作按钮列表
titlestring--定制标题字符串
toolbarboolean--是否显示工具栏
searchboolean--显示搜索框
clickRowToExpandboolean--是否在点击行时自动展开
beforeRightClick(node, event)=>ContextMenuItem[]--右键点击回调,可返回右键菜单列表数据来生成右键菜单
rightMenuListContextMenuItem[]--右键菜单列表数据
defaultExpandLevelstring | number--初次渲染后默认展开的层级2.4.1
defaultExpandAllbooleanfalsetrue/false初次渲染后默认全部2.4.1
searchValue(v-model)string--当前搜索词2.7.1

注意

defaultExpandLeveldefaultExpandAll 仅在初次渲染时生效。如果basicTree是在创建完毕之后才设置的treeData(如异步数据),需要在更新后自己调用basicTree提供的expandAllfilterByLevel来执行展开

ActionItem

{
+  // 渲染的图标
+  render: (record: any) => any;
+  // 是否显示
+  show?: boolean | ((record: Recordable) => boolean);
+}
+

ContextMenuItem

{
+  // 文本
+  label: string;
+  // 图标
+  icon?: string;
+  // 是否禁用
+  disabled?: boolean;
+  // 事件
+  handler?: (...arg) => any;
+  // 是否显示分隔线
+  divider?: boolean;
+  // 子级菜单数据
+  children?: ContextMenuItem[];
+}
+

Slots

温馨提醒

官方文档内的 slot 都支持,具体可以参考 antv tree

Methods

名称回调参数说明
checkAll(checkAll: boolean) => void选择所有
expandAll(expandAll: boolean) => void展开所有
setExpandedKeys(keys: Keys) => void设置展开节点
getExpandedKeys() => Keys获取展开节点
setSelectedKeys(keys: Keys) => void设置选中节点
getSelectedKeys() => Keys获取选中节点
setCheckedKeys(keys: CheckKeys) => void设置勾选节点
getCheckedKeys() => CheckKeys获取勾选节点
filterByLevel(level: number) => void显示指定等级
insertNodeByKey(opt: InsertNodeParams) => void插入子节点到指定节点内
deleteNodeByKey(key: string) => void根据 key 删除节点
updateNodeByKey(key: string, node: Omit<TreeItem, 'key'>) => void根据 key 更新节点
setSearchValue(value: string) => void设置当前搜索词(v2.7.1)
getSearchValue() => string获取当前搜索词(v2.7.1)
+ + + + \ No newline at end of file diff --git a/components/upload.html b/components/upload.html new file mode 100644 index 00000000..aa3493cb --- /dev/null +++ b/components/upload.html @@ -0,0 +1,65 @@ + + + + + + Upload | Vben Admin + + + + + + + + + + + + + + + + +

Upload

文件上传组件

Usage

<template>
+  <BasicUpload :maxSize="20" :maxNumber="10" @change="handleChange" :api="uploadApi" />
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicUpload } from '/@/components/Upload';
+  import { uploadApi } from '/@/api/sys/upload';
+
+  export default defineComponent({
+    components: { BasicUpload },
+    setup() {
+      return {
+        uploadApi,
+        handleChange: (list: string[]) => {
+          createMessage.info(`已上传文件${JSON.stringify(list)}`);
+        },
+      };
+    },
+  });
+</script>
+

Config

.env.development.env.production 配置开发和生产的文件上传地址

# .env.development
+
+VITE_PROXY=[["/upload","http://localhost:3001/upload"]]
+
+::: tip
+v3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。
+:::
+
+# 如果没有跨域问题,则直接使用真实上传地址
+VITE_GLOB_UPLOAD_URL=/upload
+
+# .env.production
+VITE_GLOB_UPLOAD_URL=/upload
+
+

Props

属性类型默认值可选值说明
valuestring[]--已上传的文件列表,支持v-model
showPreviewNumberbooleantrue-是否显示预览数量
emptyHidePreviewbooleanfalse-没有上传文件时是否隐藏预览
helpTextstring--帮助文本
maxSizenumber2-单个文件最大体积,单位 M
maxNumbernumberInfinity-最大上传数量,Infinity 则不限制
acceptstring[]--限制上传格式,可使用文件后缀名(点号可选)或MIME字符串。例如 ['.doc,','docx','application/msword','image/*']
multipleboolean--开启多文件上传
uploadParamsany--上传携带的参数
apiFn--上传接口,为上面配置的接口

Events

事件回调参数返回值说明版本
change(fileList)=>void文件列表内容改变触发事件
delete(record)=>void在上传列表中删除文件的事件
preview-delete(url:string)=>void在预览列表中删除文件的事件2.5.3
+ + + + \ No newline at end of file diff --git a/components/verify.html b/components/verify.html new file mode 100644 index 00000000..c3e70b2a --- /dev/null +++ b/components/verify.html @@ -0,0 +1,76 @@ + + + + + + BasicDragVerify | Vben Admin + + + + + + + + + + + + + + + + +

BasicDragVerify

拖动校验组件

BasicDragVerify

Usage

<template>
+  <div class="p-10">
+    <BasicDragVerify @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { BasicDragVerify, DragVerifyActionType, PassingData } from '/@/components/Verify/index';
+  export default defineComponent({
+    components: { BasicDragVerify },
+    setup() {
+      function handleSuccess(data: PassingData) {
+        const { time } = data;
+        createMessage.success(`校验成功,耗时${time}`);
+      }
+      return {
+        handleSuccess,
+        handleBtnClick,
+      };
+    },
+  });
+</script>
+

Props

属性类型默认值说明
valueboolean-是否通过
textstring请按住滑块拖动未拖动时候显示文字
successTextstring验证通过验证成功后显示文本
heightstring|string40高度
widthstring|string260宽度
circlebooleanfalse是否圆角
wrapStyleany-外层容器样式
contentStyleany-主体内容样式
barStyleany-bar 样式
actionStyleany-拖拽按钮样式

Methods

名称回调参数说明
resume()=>{}还原初始值

RotateDragVerify

图片还原正方向校验组件

Usage

<template>
+  <div class="p-10">
+    <RotateDragVerify :src="img" ref="el" @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { RotateDragVerify } from '/@/components/Verify/index';
+
+  import img from '/@/assets/images/header.jpg';
+  export default defineComponent({
+    components: { RotateDragVerify },
+    setup() {
+      const handleSuccess = () => {
+        console.log('success!');
+      };
+      return {
+        handleSuccess,
+        img,
+      };
+    },
+  });
+</script>
+

props

属性类型默认值说明
srcstring-图片地址
imgWidthnumber-图片宽度
imgWrapStyleany-图片外层容器样式
minDegreenumber-最小旋转角度
maxDegreenumber-最大旋转角度
diffDegreenumber-误差角度
valueboolean-是否通过
textstring请按住滑块拖动未拖动时候显示文字
successTextstring验证通过验证成功后显示文本
heightstring|string40高度
widthstring|string260宽度
circlebooleanfalse是否圆角
wrapStyleany-外层容器样式
contentStyleany-主体内容样式
barStyleany-bar 样式
actionStyleany-拖拽按钮样式

Methods

名称回调参数说明
resumeFunction还原初始值
+ + + + \ No newline at end of file diff --git a/components/virtual-scroll.html b/components/virtual-scroll.html new file mode 100644 index 00000000..d00e965b --- /dev/null +++ b/components/virtual-scroll.html @@ -0,0 +1,90 @@ + + + + + + VirtualScroll | Vben Admin + + + + + + + + + + + + + + + + +

VirtualScroll

虚拟滚动组件(用于大量数据纯展示时使用)

Usage

<template>
+  <div class="p-4 virtual-scroll-demo">
+    <Divider>基础滚动示例</Divider>
+    <div class="virtual-scroll-demo-wrap">
+      <VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300">
+        <template v-slot="{ item }">
+          <div class="virtual-scroll-demo__item">{{ item.title }}</div>
+        </template>
+      </VirtualScroll>
+    </div>
+
+    <Divider>即使不可见,也预先加载50条数据,防止空白</Divider>
+    <div class="virtual-scroll-demo-wrap">
+      <VirtualScroll :itemHeight="41" :items="data" :height="300" :width="300" :bench="50">
+        <template v-slot="{ item }">
+          <div class="virtual-scroll-demo__item">{{ item.title }}</div>
+        </template>
+      </VirtualScroll>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { VirtualScroll } from '/@/components/VirtualScroll/index';
+
+  import { Divider } from 'ant-design-vue';
+  const data: any[] = (() => {
+    const arr: any[] = [];
+    for (let index = 1; index < 20000; index++) {
+      arr.push({
+        title: '列表项' + index,
+      });
+    }
+    return arr;
+  })();
+  export default defineComponent({
+    components: { VirtualScroll, Divider },
+    setup() {
+      return { data: data };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .virtual-scroll-demo {
+    &-wrap {
+      display: flex;
+      margin: 0 30%;
+      background: #fff;
+      justify-content: center;
+    }
+
+    /deep/ &__item {
+      height: 40px;
+      padding: 0 20px;
+      line-height: 40px;
+      border-bottom: 1px solid #ddd;
+    }
+  }
+</style>
+

Props

属性类型默认值可选值说明
heightstring|number--高度
widthstring|number--宽度
maxHeightstring|number--最大高度
maxWidthstring|number--最大宽度
minHeightstring|number--最小高度
minWidthstring|number--最小宽度
itemHeightstring|number--每个选项高度,必传
itemsany[]--选项列表

Slots

名称说明
default默认
+ + + + \ No newline at end of file diff --git a/dep/cors.html b/dep/cors.html new file mode 100644 index 00000000..15528a1d --- /dev/null +++ b/dep/cors.html @@ -0,0 +1,31 @@ + + + + + + 跨域处理 | Vben Admin + + + + + + + + + + + + + + + + +

跨域处理

产生原因

跨域产生的原因是由于前端地址与后台接口不是同源,从而导致 ajax 不能发送

非同源产生的问题

  1. Cookie、LocalStorage 和 IndexDB 无法获取
  2. DOM 无法获得
  3. AJAX 请求不能发送

同源条件

协议端口主机 三者相同即为同源

反之,其中只要 某一个 不一样则为不同源

解决方式

本地开发跨域

本地开发一般使用下面 3 种方式进行处理

  1. vite 的 proxy 进行代理
  2. 后台开启 cors
  3. 使用 nginx 转发请求

项目内部自带第一种方式,具体可以参考服务端交互-本地开发环境接口地址修改

生产环境跨域

生产环境一般使用下面 2 种方式进行处理

  1. 后台开启 cors
  2. 使用 nginx 转发请求

后台开启 cors 不需要前端做任何改动

nginx 配置文件可以查看nginx 配置

+ + + + \ No newline at end of file diff --git a/dep/dark.html b/dep/dark.html new file mode 100644 index 00000000..68378215 --- /dev/null +++ b/dep/dark.html @@ -0,0 +1,56 @@ + + + + + + 黑暗主题 | Vben Admin + + + + + + + + + + + + + + + + +

黑暗主题

介绍

项目已经内置了黑暗主题切换,只需配置自己需要的颜色变量,即可在项目中使用

原理

通过 vite-plugin-theme 插件,将所有的颜色变量抽取到独立的 css 文件,并且全部在 html 上面加上 css 选择器。通过改变 html 标签的 data-theme 属性来进行黑暗主题切换

配置

黑暗主题颜色配置通过 vite-plugin-theme 实现,具体代码在 build/vite/plugin/theme

antdDarkThemePlugin({
+  darkModifyVars: {
+    ...generateModifyVars(true),
+    'text-color': '#c9d1d9',
+    'text-color-base': '#c9d1d9',
+    'component-background': '#151515',
+    'text-color-secondary': '#8b949e',
+    'border-color-base': '#303030',
+    'item-active-bg': '#111b26',
+    'app-content-background': 'rgb(255 255 255 / 4%)',
+  },
+});
+

切换

只需要使用 vite-plugin-theme 提供的函数来进行切换即可

import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client';
+
+export async function updateDarkTheme(mode: string | null = 'light') {
+  const htmlRoot = document.getElementById('htmlRoot');
+  if (mode === 'dark') {
+    if (import.meta.env.PROD && !darkCssIsReady) {
+      await loadDarkThemeCss();
+    }
+    htmlRoot?.setAttribute('data-theme', 'dark');
+  } else {
+    htmlRoot?.setAttribute('data-theme', 'light');
+  }
+}
+
+ + + + \ No newline at end of file diff --git a/dep/i18n.html b/dep/i18n.html new file mode 100644 index 00000000..b9ca02c5 --- /dev/null +++ b/dep/i18n.html @@ -0,0 +1,150 @@ + + + + + + 国际化 | Vben Admin + + + + + + + + + + + + + + + + +

国际化

如果你使用的 vscode 开发工具,则推荐安装 I18n-ally 这个插件

I18n-ally 插件

安装了该插件后,你的代码内可以实时看到对应的语言内容

配置默认语言

src/settings/localeSetting.ts 内可以配置默认语言

export const LOCALE: { [key: string]: LocaleType } = {
+  ZH_CN: 'zh_CN',
+  EN_US: 'en',
+};
+
+export const localeSetting: LocaleSetting = {
+  // 是否显示语言选择器
+  showPicker: true,
+  // 当前语言
+  locale: LOCALE.ZH_CN,
+  // 默认语言
+  fallback: LOCALE.ZH_CN,
+  // 允许的语言
+  availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US],
+};
+
+// 配置语言列表
+export const localeList: DropMenu[] = [
+  {
+    text: '简体中文',
+    event: 'zh_CN',
+  },
+  {
+    text: 'English',
+    event: 'en',
+  },
+];
+

配置

src/locales/setupI18n.ts 内引入的 i18n 这个无需修改

语言文件

src/locales/lang/ 可以配置具体的语言

# locales/lang/
+
+# 中文语言
+zh_CN:
+  component: 组件相关
+  layout: 布局相关
+  routes: 路由菜单相关
+  sys: 系统页面相关
+
+en: 同上
+
+

语言导入逻辑说明

  1. 初始化

src/locales/setupI18n 内的根语言文件可以看到

const defaultLocal = await import(`./lang/${locale}.ts`);
+

这会导入 src/locales/lang/{lang}.ts 文件语言包,此文件会导入对应语言下的所有文件。

import { genMessage } from '../helper';
+import antdLocale from 'ant-design-vue/es/locale/zh_CN';
+import momentLocale from 'moment/dist/locale/zh-cn';
+
+const modules = import.meta.globEager('./zh_CN/**/*.ts');
+export default {
+  message: {
+    ...genMessage(modules, 'zh_CN'),
+    antdLocale,
+  },
+  momentLocale,
+  momentLocaleName: 'zh-cn',
+};
+

并将其按相应的目录结构转化为多层级的

例:

lang/zh_CN/components/modal.ts 的文件内容为

{
+  title: '标题';
+}
+

则在使用的使用直接使用 t('components.modal.title') 进行获取。

这样做的好处在于更容易管理大型项目的多语言。如果不需要分模块划分,可以直接自己手动导入即可。

使用

引入项目自带的 useI18n 注意不要引入 vue-i18n 的 useI18n

import { useI18n } from '/@/hooks/web/useI18n';
+
+const { t } = useI18n();
+
+const title = t('components.modal.title');
+

切换语言

切换语言需要使用 src/locales/useLocale.ts

import { useLocale } from '/@/locales/useLocale';
+
+const { changeLocale } = useLocale();
+
+changeLocale('en');
+

新增

语言文件

src/locales/lang/ 增加对应语言的文件即可

新增语言

目前项目自带的语言只有 zh_CNen 两种

如果需要新增,按以下操作即可

  1. src/locales/lang/ 下新增相应的语言目录及语言文件并引入 引入 ant-design-vue 和 moment 对应的语言包
  2. types/config.d.ts 内加上预览类型定义
  3. src/settings/localeSetting.ts 修改语言配置

远程读取语言数据

目前项目会在 src/main.ts 内等待 setupI18n 这个函数执行完之后才会渲染界面,所以只需在 setupI18n 内发送 ajax 请求,将对应的数据设置到 i18n 实例上即可

// src/main.ts
+await setupI18n(app);
+
+app.mount('#app', true);
+

setupI18n 函数

代码: src/locales/setupI18n/

如下所示,这里会先设置一个默认语言,默认语言可以设置在本地,也可以在这里等待接口返回默认语言

// setup i18n instance with glob
+export async function setupI18n(app: App) {
+  const options = await createI18nOptions();
+  i18n = createI18n(options) as I18n;
+  app.use(i18n);
+}
+
+async function createI18nOptions(): Promise<I18nOptions> {
+  const locale = localeStore.getLocale;
+
+  // 这里改成接口获取
+  const defaultLocal = await import(`./lang/${locale}.ts`);
+  const message = defaultLocal.default?.message ?? {};
+
+  return {
+    legacy: false,
+    locale,
+    fallbackLocale: fallback,
+    messages: {
+      [locale]: message,
+    },
+    availableLocales: availableLocales,
+    sync: true,
+    silentTranslationWarn: true,
+    missingWarn: false,
+    silentFallbackWarn: true,
+  };
+}
+

changeLocale 函数

代码: src/locales/useLocale/

当手动切换语言的时候会触发 useLocale 函数,useLocale 也是异步函数,只需等待接口返回响应的数据后,再进行设置即可

async function changeLocale(locale: LocaleType) {
+  const globalI18n = i18n.global;
+  const currentLocale = unref(globalI18n.locale);
+  if (currentLocale === locale) return locale;
+
+  if (loadLocalePool.includes(locale)) {
+    setI18nLanguage(locale);
+    return locale;
+  }
+  // 这里改成接口获取
+  const langModule = ((await import(`./lang/${locale}.ts`)) as any).default as LangModule;
+  if (!langModule) return;
+
+  const { message, momentLocale, momentLocaleName } = langModule;
+
+  globalI18n.setLocaleMessage(locale, message);
+  moment.updateLocale(momentLocaleName, momentLocale);
+  loadLocalePool.push(locale);
+
+  setI18nLanguage(locale);
+  return locale;
+}
+
+ + + + \ No newline at end of file diff --git a/dep/icon.html b/dep/icon.html new file mode 100644 index 00000000..a05e080e --- /dev/null +++ b/dep/icon.html @@ -0,0 +1,193 @@ + + + + + + 图标 | Vben Admin + + + + + + + + + + + + + + + + +

图标

项目中有以下多种图标使用方式。

组件库图标

使用 ant-design-vue 提供的图标

<template>
+  <StarOutlined />
+  <StarFilled />
+  <StarTwoTone twoToneColor="#eb2f96" />
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { StarOutlined, StarFilled, StarTwoTone } from '@ant-design/icons-vue';
+  export default defineComponent({
+    components: { StarOutlined, StarFilled, StarTwoTone },
+  });
+</script>
+

Svg Sprite 图标

使用

将需要的 svg 图标放到src/assets/icons

例: test.svg

  1. 使用SvgIcon组件进行展示
<template>
+  <SvgIcon name="test" />
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { SvgIcon } from '/@/components/Icon';
+  export default defineComponent({
+    components: { SvgIcon },
+  });
+</script>
+
  1. 使用Icon组件进行展示

|svg 结尾会自动使用SvgIcon组件

<template>
+  <Icon name="test|svg" />
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { Icon } from '/@/components/Icon';
+  export default defineComponent({
+    components: { Icon },
+  });
+</script>
+

Iconify 图标

使用方式请参考 Icon 组件

项目中使用到的是 vite-plugin-purge-icons 这个插件来进行图标实现。

  1. 安装依赖

+yarn add @iconify/iconify
+
+yarn add @iconify/json @purge-icons/generated -D
+
+
  1. vite.config.ts内引入插件
import PurgeIcons from 'vite-plugin-purge-icons';
+
+export default {
+  plugins: [PurgeIcons()],
+};
+
  1. 编写 Icon 组件

完整代码 src/components/Icon/src/Icon.vue

<template>
+  <SvgIcon :size="size" :name="getSvgIcon" v-if="isSvgIcon" :class="[$attrs.class]" :spin="spin" />
+  <span
+    v-else
+    ref="elRef"
+    :class="[$attrs.class, 'app-iconify anticon', spin && 'app-iconify-spin']"
+    :style="getWrapStyle"
+  ></span>
+</template>
+<script lang="ts">
+  import type { PropType } from 'vue';
+  import {
+    defineComponent,
+    ref,
+    watch,
+    onMounted,
+    nextTick,
+    unref,
+    computed,
+    CSSProperties,
+  } from 'vue';
+
+  import SvgIcon from './SvgIcon.vue';
+  import Iconify from '@purge-icons/generated';
+  import { isString } from '/@/utils/is';
+  import { propTypes } from '/@/utils/propTypes';
+
+  const SVG_END_WITH_FLAG = '|svg';
+  export default defineComponent({
+    name: 'GIcon',
+    components: { SvgIcon },
+    props: {
+      // icon name
+      icon: propTypes.string,
+      // icon color
+      color: propTypes.string,
+      // icon size
+      size: {
+        type: [String, Number] as PropType<string | number>,
+        default: 16,
+      },
+      spin: propTypes.bool.def(false),
+      prefix: propTypes.string.def(''),
+    },
+    setup(props) {
+      const elRef = ref<ElRef>(null);
+
+      const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG));
+      const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, ''));
+      const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`);
+
+      const update = async () => {
+        if (unref(isSvgIcon)) return;
+
+        const el = unref(elRef);
+        if (!el) return;
+
+        await nextTick();
+        const icon = unref(getIconRef);
+        if (!icon) return;
+
+        const svg = Iconify.renderSVG(icon, {});
+        if (svg) {
+          el.textContent = '';
+          el.appendChild(svg);
+        } else {
+          const span = document.createElement('span');
+          span.className = 'iconify';
+          span.dataset.icon = icon;
+          el.textContent = '';
+          el.appendChild(span);
+        }
+      };
+
+      const getWrapStyle = computed((): CSSProperties => {
+        const { size, color } = props;
+        let fs = size;
+        if (isString(size)) {
+          fs = parseInt(size, 10);
+        }
+
+        return {
+          fontSize: `${fs}px`,
+          color: color,
+          display: 'inline-flex',
+        };
+      });
+
+      watch(() => props.icon, update, { flush: 'post' });
+
+      onMounted(update);
+
+      return { elRef, getWrapStyle, isSvgIcon, getSvgIcon };
+    },
+  });
+</script>
+<style lang="less">
+  .app-iconify {
+    display: inline-block;
+    // vertical-align: middle;
+
+    &-spin {
+      svg {
+        animation: loadingCircle 1s infinite linear;
+      }
+    }
+  }
+
+  span.iconify {
+    display: block;
+    min-width: 1em;
+    min-height: 1em;
+    background-color: @iconify-bg-color;
+    border-radius: 100%;
+  }
+</style>
+

图标选择器

图标集预生成

由于图标选择器这个比较特殊的存在,项目会打包一些比较多的图标,图标选择器的图标需要事先指定并生成相应的文件。

生成

  • 执行图标生成命令
yarn gen:icon
+
  • 这里会让你选择本地还是在线生成,两种方式各有利弊。如下图所示

local 表示本地,online 表示在线,回车确认

  • 选择你要生成的图标集,回车确认

  • 选择图标输出的目录(项目默认 src/components/Icon/data),可以直接回车选择默认

到这里图标集已经生成完成了,此时你的图标选择器已经是你所选的的图标集的图标了。

注意不要频繁更新

如果前面选择的是本地生成的话,频繁更换图标集,可能会导致图标丢失或者显示不出来

优缺点

  • 在线图标(项目默认,推荐)

该方式会在图标选择器使用到图标的时候进行在线请求,然后缓存对应的图标到浏览器。可以有效减少代码打包体积。

如果你的项目可以访问外网,建议可以使用这种方式

缺点: 在局域网或者无法访问到外网的环境中图标显示不出来

  • 本地图标

该方式会在打包的时候将图标选择器的图标全部打包到 js 内。在使用的时候不会额外的请求在线图标

缺点: 打包体积会偏大,具体的体积增加得看前面选择图标集的时候选择的图标数量的多少决定

+ + + + \ No newline at end of file diff --git a/dep/lint.html b/dep/lint.html new file mode 100644 index 00000000..56c31364 --- /dev/null +++ b/dep/lint.html @@ -0,0 +1,51 @@ + + + + + + Lint | Vben Admin + + + + + + + + + + + + + + + + +

Lint

介绍

使用 lint 的好处

具备基本工程素养的同学都会注重编码规范,而代码风格检查(Code Linting,简称 Lint)是保障代码规范一致性的重要手段。

遵循相应的代码规范有以下好处

  • 较少 bug 错误率
  • 高效的开发效率
  • 更高的可读性

项目内集成了以下几种代码校验方式

  1. eslint 用于校验代码格式规范
  2. commitlint 用于校验 git 提交信息规范
  3. stylelint 用于校验 css/less 规范
  4. prettier 代码格式化

WARNING

lint 不是必须的,但是很有必要,一个项目做大了以后或者参与人员过多后,就会出现各种风格迥异的代码,对后续的维护造成了一定的麻烦

ESLint

ESLint 是一个代码规范和错误检查工具,有以下几个特性

  • 所有东西都是可以插拔的。你可以调用任意的 rule api 或者 formatter api 去打包或者定义 rule or formatter。
  • 任意的 rule 都是独立的
  • 没有特定的 coding style,你可以自己配置

手动校验代码

# 执行下面代码.能修复的会自动修复,不能修复的需要手动修改
+yarn run lint:eslint
+

配置项

项目的 eslint 配置位于根目录下 .eslintrc.js 内,可以根据团队自行修改代码规范

编辑器配合

推荐使用 vscode 进行开发,vscode 自带 eslint 插件,可以自动修改一些错误。

同时项目内也自带了 vscode eslint 配置,具体在 .vscode/setting.json 文件夹内部。只要使用 vscode 开发不用任何设置即可使用

CommitLint

在一个团队中,每个人的 git 的 commit 信息都不一样,五花八门,没有一个机制很难保证规范化,如何才能规范化呢?可能你想到的是 git 的 hook 机制,去写 shell 脚本去实现。这当然可以,其实 JavaScript 有一个很好的工具可以实现这个模板,它就是 commitlint(用于校验 git 提交信息规范)。

配置

commit-lint 的配置位于项目根目录下 commitlint.config.js

Git 提交规范

  • 参考 vue 规范 (Angular)

    • feat 增加新功能
    • fix 修复问题/BUG
    • style 代码风格相关无影响运行结果的
    • perf 优化/性能提升
    • refactor 重构
    • revert 撤销修改
    • test 测试相关
    • docs 文档/注释
    • chore 依赖更新/脚手架配置修改等
    • workflow 工作流改进
    • ci 持续集成
    • mod 不确定分类的修改
    • wip 开发中
    • types 类型修改

如何关闭

.husky/commit-msg 内注释以下代码即可

# npx --no-install commitlint --edit "$1"
+

示例


+git commit -m 'feat(home): add home page'
+
+

Stylelint

stylelint 用于校验项目内部 css 的风格,加上编辑器的自动修复,可以很好的统一项目内部 css 风格

配置

stylelint 配置位于根目录下 stylelint.config.js

编辑器配合

如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 css 样式

插件

StyleLint

Prettier

prettier 可以用于统一项目代码风格,统一的缩进,单双引号,尾逗号等等风格

配置

prettier 配置文件位于项目根目录下 prettier.config.js

编辑器配合

如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 js 格式

插件

Prettier

Git Hook

git hook 一般结合各种 lint,在 git 提交代码的时候进行代码风格校验,如果校验没通过,则不会进行提交。需要开发者自行修改后再次进行提交

husky

有一个问题就是校验会校验全部代码,但是我们只想校验我们自己提交的代码,这个时候就可以使用 husky。

最有效的解决方案就是将 Lint 校验放到本地,常见做法是使用 husky 或者 pre-commit 在本地提交之前先做一次 Lint 校验。

项目在 .husky 内部定义了相应的 hooks

如何关闭

# 删除husky依赖即可
+yarn remove huksy
+
+

如何跳过某一个检查

# 加上 --no-verify即可跳过git hook校验(--no-verify 简写为 -n)
+git commit -m "xxx" --no-verify
+

lint-staged

用于自动修复提交文件风格问题

lint-staged 配置位于项目 .husky 目录下 lintstagedrc.js

module.exports = {
+  // 对指定格式文件 在提交的时候执行相应的修复命令
+  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
+  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
+  'package.json': ['prettier --write'],
+  '*.vue': ['eslint --fix', 'stylelint --fix', 'prettier --write', 'git add .'],
+  '*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write', 'git add .'],
+  '*.md': ['prettier --write'],
+};
+
+ + + + \ No newline at end of file diff --git a/guide/auth.html b/guide/auth.html new file mode 100644 index 00000000..6ef68483 --- /dev/null +++ b/guide/auth.html @@ -0,0 +1,260 @@ + + + + + + 权限 | Vben Admin + + + + + + + + + + + + + + + + +

权限

项目中集成了三种权限处理方式:

  1. 通过用户角色来过滤菜单(前端方式控制),菜单和路由分开配置
  2. 通过用户角色来过滤菜单(前端方式控制),菜单由路由配置自动生成
  3. 通过后台来动态生成路由表(后台方式控制)

前端角色权限

实现原理: 在前端固定写死路由的权限,指定路由有哪些权限可以查看。只初始化通用的路由,需要权限才能访问的路由没有被加入路由表内。在登陆后或者其他方式获取用户角色后,通过角色去遍历路由表,获取该角色可以访问的路由表,生成路由表,再通过 router.addRoutes 添加到路由实例,实现权限的过滤。

缺点: 权限相对不自由,如果后台改动角色,前台也需要跟着改动。适合角色较固定的系统

实现

  1. 项目配置将系统内权限模式改为 ROLE 模式
// ! 改动后需要清空浏览器缓存
+const setting: ProjectConfig = {
+  // 权限模式
+  permissionMode: PermissionModeEnum.ROLE,
+};
+
  1. 在路由表配置路由所需的权限,如果不配置,默认可见(见注释)
import type { AppRouteModule } from '/@/router/types';
+
+import { getParentLayout, LAYOUT } from '/@/router/constant';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { t } from '/@/hooks/web/useI18n';
+
+const permission: AppRouteModule = {
+  path: '/permission',
+  name: 'Permission',
+  component: LAYOUT,
+  redirect: '/permission/front/page',
+  meta: {
+    icon: 'ion:key-outline',
+    title: t('routes.demo.permission.permission'),
+  },
+
+  children: [
+    {
+      path: 'front',
+      name: 'PermissionFrontDemo',
+      component: getParentLayout('PermissionFrontDemo'),
+      meta: {
+        title: t('routes.demo.permission.front'),
+      },
+      children: [
+        {
+          path: 'auth-pageA',
+          name: 'FrontAuthPageA',
+          component: () => import('/@/views/demo/permission/front/AuthPageA.vue'),
+          meta: {
+            title: t('routes.demo.permission.frontTestA'),
+            roles: [RoleEnum.SUPER],
+          },
+        },
+        {
+          path: 'auth-pageB',
+          name: 'FrontAuthPageB',
+          component: () => import('/@/views/demo/permission/front/AuthPageB.vue'),
+          meta: {
+            title: t('routes.demo.permission.frontTestB'),
+            roles: [RoleEnum.TEST],
+          },
+        },
+      ],
+    },
+  ],
+};
+
+export default permission;
+
  1. 在路由钩子内动态判断

详细代码见 src/router/guard/permissionGuard.ts

// 这里只列举了主要代码
+const routes = await permissionStore.buildRoutesAction();
+
+routes.forEach((route) => {
+  router.addRoute(route as unknown as RouteRecordRaw);
+});
+
+const redirectPath = (from.query.redirect || to.path) as string;
+const redirect = decodeURIComponent(redirectPath);
+const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
+permissionStore.setDynamicAddedRoute(true);
+next(nextData);
+

permissionStore.buildRoutesAction 用于过滤动态路由,详细代码见 src/store/modules/permission.ts

// 主要代码
+if (permissionMode === PermissionModeEnum.ROLE) {
+  const routeFilter = (route: AppRouteRecordRaw) => {
+    const { meta } = route;
+    const { roles } = meta || {};
+    if (!roles) return true;
+    return roleList.some((role) => roles.includes(role));
+  };
+  routes = filter(asyncRoutes, routeFilter);
+  routes = routes.filter(routeFilter);
+  // Convert multi-level routing to level 2 routing
+  routes = flatMultiLevelRoutes(routes);
+}
+

动态更换角色

系统提供 usePermission 方便角色相关操作

import { usePermission } from '/@/hooks/web/usePermission';
+import { RoleEnum } from '/@/enums/roleEnum';
+
+export default defineComponent({
+  setup() {
+    const { changeRole } = usePermission();
+    // 更换为test角色
+    // 动态更改角色,传入角色名称,可以是数组
+    changeRole(RoleEnum.TEST);
+    return {};
+  },
+});
+

细粒度权限

函数方式

usePermission 还提供了按钮级别的权限控制。

<template>
+  <a-button v-if="hasPermission([RoleEnum.TEST, RoleEnum.SUPER])" color="error" class="mx-4">
+    拥有[test,super]角色权限可见
+  </a-button>
+</template>
+<script lang="ts">
+  import { usePermission } from '/@/hooks/web/usePermission';
+  import { RoleEnum } from '/@/enums/roleEnum';
+
+  export default defineComponent({
+    setup() {
+      const { hasPermission } = usePermission();
+
+      return { hasPermission };
+    },
+  });
+</script>
+

组件方式

具体查看权限组件使用

指令方式

TIP

指令方式不能动态更改权限

<a-button v-auth="RoleEnum.SUPER" type="primary" class="mx-4"> 拥有super角色权限可见</a-button>
+

后台动态获取

实现原理: 是通过接口动态生成路由表,且遵循一定的数据结构返回。前端根据需要处理该数据为可识别的结构,再通过 router.addRoutes 添加到路由实例,实现权限的动态生成。

实现

  1. 项目配置将系统内权限模式改为 BACK 模式
// ! 改动后需要清空浏览器缓存
+const setting: ProjectConfig = {
+  // 权限模式
+  permissionMode: PermissionModeEnum.BACK,
+};
+
  1. 路由拦截,与角色权限模式一致

permissionStore.buildRoutesAction 用于过滤动态路由,详细代码见 /@/store/modules/permission.ts

// 主要代码
+if (permissionMode === PermissionModeEnum.BACK) {
+  const { createMessage } = useMessage();
+
+  createMessage.loading({
+    content: t('sys.app.menuLoading'),
+    duration: 1,
+  });
+
+  // !Simulate to obtain permission codes from the background,
+  // this function may only need to be executed once, and the actual project can be put at the right time by itself
+  let routeList: AppRouteRecordRaw[] = [];
+  try {
+    this.changePermissionCode();
+    routeList = (await getMenuList()) as AppRouteRecordRaw[];
+  } catch (error) {
+    console.error(error);
+  }
+
+  // Dynamically introduce components
+  routeList = transformObjToRoute(routeList);
+
+  //  Background routing to menu structure
+  const backMenuList = transformRouteToMenu(routeList);
+  this.setBackMenuList(backMenuList);
+
+  routeList = flatMultiLevelRoutes(routeList);
+  routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
+}
+

getMenuList 返回值格式

返回值由多个路由模块组成

注意

后端接口返回的数据中必须包含PageEnum.BASE_HOME指定的路由(path定义于src/enums/pageEnum.ts

[
+  {
+    path: '/dashboard',
+    name: 'Dashboard',
+    component: '/dashboard/welcome/index',
+    meta: {
+      title: 'routes.dashboard.welcome',
+      affix: true,
+      icon: 'ant-design:home-outlined',
+    },
+  },
+  {
+    path: '/permission',
+    name: 'Permission',
+    component: 'LAYOUT',
+    redirect: '/permission/front/page',
+    meta: {
+      icon: 'carbon:user-role',
+      title: 'routes.demo.permission.permission',
+    },
+    children: [
+      {
+        path: 'back',
+        name: 'PermissionBackDemo',
+        meta: {
+          title: 'routes.demo.permission.back',
+        },
+
+        children: [
+          {
+            path: 'page',
+            name: 'BackAuthPage',
+            component: '/demo/permission/back/index',
+            meta: {
+              title: 'routes.demo.permission.backPage',
+            },
+          },
+          {
+            path: 'btn',
+            name: 'BackAuthBtn',
+            component: '/demo/permission/back/Btn',
+            meta: {
+              title: 'routes.demo.permission.backBtn',
+            },
+          },
+        ],
+      },
+    ],
+  },
+];
+

动态更换菜单

系统提供 usePermission 方便角色相关操作

import { usePermission } from '/@/hooks/web/usePermission';
+import { RoleEnum } from '/@/enums/roleEnum';
+
+export default defineComponent({
+  setup() {
+    const { changeMenu } = usePermission();
+
+    // 更改菜单的实现需要自行去修改
+    changeMenu();
+    return {};
+  },
+});
+

细粒度权限

函数方式

usePermission 还提供了按钮级别的权限控制。

<template>
+  <a-button v-if="hasPermission(['20000', '2000010'])" color="error" class="mx-4">
+    拥有[20000,2000010]code可见
+  </a-button>
+</template>
+<script lang="ts">
+  import { usePermission } from '/@/hooks/web/usePermission';
+  import { RoleEnum } from '/@/enums/roleEnum';
+
+  export default defineComponent({
+    setup() {
+      const { hasPermission } = usePermission();
+      return { hasPermission };
+    },
+  });
+</script>
+

组件方式

具体查看权限组件使用

指令方式

TIP

指令方式不能动态更改权限

<a-button v-auth="'1000'" type="primary" class="mx-4"> 拥有code ['1000']权限可见 </a-button>
+

如何初始化 code

通常,如需做按钮级别权限,后台会提供相应的 code,或者类型的判断标识。这些编码只需要在登录后获取一次即可。

import { getPermCodeByUserId } from '/@/api/sys/user';
+import { permissionStore } from '/@/store/modules/permission';
+async function changePermissionCode(userId: string) {
+  // 从后台获取当前用户拥有的编码
+  const codeList = await getPermCodeByUserId({ userId });
+  permissionStore.commitPermCodeListState(codeList);
+}
+
+ + + + \ No newline at end of file diff --git a/guide/component.html b/guide/component.html new file mode 100644 index 00000000..4cc0e749 --- /dev/null +++ b/guide/component.html @@ -0,0 +1,145 @@ + + + + + + 组件注册 | Vben Admin + + + + + + + + + + + + + + + + +

组件注册

按需引入

项目目前的组件注册机制是按需注册,是在需要用到的页面才引入。

<template>
+  <Menu>
+    <SubMenu></SubMenu>
+  <Menu>
+
+  <menu>
+    <sub-menu></sub-menu>
+  <menu>
+</template>
+<script>
+import { Menu } from 'ant-design-vue';
+export default defineComponent({
+  components: {
+    Menu: Menu,
+    SubMenu: Menu.SubMenu
+  },
+})
+</script>
+

tsx 文件注册

tsx 文件内不能使用全局注册组件

import { Menu } from 'ant-design-vue';
+
+export default defineComponent({
+  setup() {
+    return () => (
+      <Menu>
+        <Menu.SubMenu></Menu.SubMenu>
+      </Menu>
+    );
+  },
+});
+

全局注册

如果不习惯按需引入方式,可以进行全局注册。全局注册也分两种方式

全局按需注册

只注册需要的组件

代码地址:src/components/registerGlobComp.ts

import {
+  // Need
+  Button as AntButton,
+  Optional,
+  Select,
+  Alert,
+  Checkbox,
+  DatePicker,
+  Radio,
+  Switch,
+  Card,
+  List,
+  Tabs,
+  Descriptions,
+  Tree,
+  Table,
+  Divider,
+  Modal,
+  Drawer,
+  Dropdown,
+  Tag,
+  Tooltip,
+  Badge,
+  Popover,
+  Upload,
+  Transfer,
+  Steps,
+  PageHeader,
+  Result,
+  Empty,
+  Avatar,
+  Menu,
+  Breadcrumb,
+  Form,
+  Input,
+  Row,
+  Col,
+  Spin,
+} from 'ant-design-vue';
+
+export function registerGlobComp(app: App) {
+  app
+    .use(Select)
+    .use(Alert)
+    .use(Breadcrumb)
+    .use(Checkbox)
+    .use(DatePicker)
+    .use(Radio)
+    .use(Switch)
+    .use(Card)
+    .use(List)
+    .use(Descriptions)
+    .use(Tree)
+    .use(Table)
+    .use(Divider)
+    .use(Modal)
+    .use(Drawer)
+    .use(Dropdown)
+    .use(Tag)
+    .use(Tooltip)
+    .use(Badge)
+    .use(Popover)
+    .use(Upload)
+    .use(Transfer)
+    .use(Steps)
+    .use(PageHeader)
+    .use(Result)
+    .use(Empty)
+    .use(Avatar)
+    .use(Menu)
+    .use(Tabs)
+    .use(Form)
+    .use(Input)
+    .use(Row)
+    .use(Col)
+    .use(Spin);
+}
+

全量注册

  • main.ts
import { createApp } from 'vue';
+import Antd from 'ant-design-vue';
+import 'ant-design-vue/dist/antd.less';
+const app = createApp(App);
+app.use(Antd);
+
  • 删除以下代码
if (import.meta.env.DEV) {
+  import('ant-design-vue/dist/antd.less');
+}
+
+ + + + \ No newline at end of file diff --git a/guide/deploy.html b/guide/deploy.html new file mode 100644 index 00000000..97fa6950 --- /dev/null +++ b/guide/deploy.html @@ -0,0 +1,139 @@ + + + + + + 构建&部署 | Vben Admin + + + + + + + + + + + + + + + + +

构建&部署

前言

由于是展示项目,所以打包后相对较大,如果项目中没有用到的插件,可以删除对应的文件或者路由,不引用即可,没有引用就不会打包。

当然,你也可以使用精简版 vue-vben-admin-thin 进行开发。

构建

项目开发完成之后,执行以下命令进行构建

yarn build
+

构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件

旧版浏览器兼容

.env.production

设置 VITE_LEGACY=true 即可打包出兼容旧版浏览器的代码

VITE_LEGACY = true
+

预览

发布之前可以在本地进行预览,有多种方式,这里介绍两种

不能直接打开构建后的 html 文件

  • 使用项目自定的命令进行预览(推荐)
# 先打包再进行预览
+yarn preview
+# 直接预览本地 dist 文件目录
+yarn preview:dist
+
  • 本地服务器预览(通过 live-server)
# 1.全局安装live-server
+yarn global add live-server
+# 2. 进入打包的后目录
+cd ./dist
+# 本地预览,默认端口8080
+live-server
+# 指定端口
+live-server --port 9000
+

分析构建文件体积

如果你的构建文件很大,可以通过项目内置 rollup-plugin-analyzer 插件进行代码体积分析,从而优化你的代码。

yarn report
+
+

运行之后,在自动打开的页面可以看到具体的体积分布,以分析哪些依赖有问题。

TIP

左上角可以切换 显示 gzip 或者 brotli

压缩

开启 gzip 压缩

开启 gzip,并配合 nginx 的 gzip_static 功能可以大大加快页面访问速度

TIP

只需开启 VITE_BUILD_COMPRESS='gzip' 即可在打包的同时生成 .gz 文件

# 根据自己路径来配置更改
+# 例如部署在nginx /next/路径下  则VITE_PUBLIC_PATH=/next/
+VITE_PUBLIC_PATH=/
+

开启 brotli 压缩

brotli 是比 gzip 压缩率更高的算法,可以与 gzip 共存不会冲突,需要 nginx 安装指定模块并开启即可。

TIP

只需开启 VITE_BUILD_COMPRESS='brotli' 即可在打包的同时生成 .br 文件

# 根据自己路径来配置更改
+# 例如部署在nginx /next/路径下  则VITE_PUBLIC_PATH=/next/
+VITE_PUBLIC_PATH=/
+

同时开启 gzip 与 brotli

只需开启 VITE_BUILD_COMPRESS='brotli,gzip' 即可在打包的同时生成 .gz.br 文件。

gzip 与 brotli 在 nginx 内的配置

http {
+  # 开启gzip
+  gzip on;
+  # 开启gzip_static
+  # gzip_static 开启后可能会报错,需要安装相应的模块, 具体安装方式可以自行查询
+  # 只有这个开启,vue文件打包的.gz文件才会有效果,否则不需要开启gzip进行打包
+  gzip_static on;
+  gzip_proxied any;
+  gzip_min_length 1k;
+  gzip_buffers 4 16k;
+  #如果nginx中使用了多层代理 必须设置这个才可以开启gzip。
+  gzip_http_version 1.0;
+  gzip_comp_level 2;
+  gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
+  gzip_vary off;
+  gzip_disable "MSIE [1-6]\.";
+
+  # 开启 brotli压缩
+  # 需要安装对应的nginx模块,具体安装方式可以自行查询
+  # 可以与gzip共存不会冲突
+  brotli on;
+  brotli_comp_level 6;
+  brotli_buffers 16 8k;
+  brotli_min_length 20;
+  brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
+}
+

部署

注意

项目默认是在生产环境开启 Mock,这样做非常不好,只是为了演示环境有数据,不建议在生产环境使用 Mock,而应该使用真实的后台接口,并将 Mock 关闭。

发布

简单的部署只需要将最终生成的静态文件,dist 文件夹的静态文件发布到你的 cdn 或者静态服务器即可,需要注意的是其中的 index.html 通常会是你后台服务的入口页面,在确定了 js 和 css 的静态之后可能需要改变页面的引入路径。

例如上传到 nginx

/srv/www/project/index.html

# nginx配置
+location / {
+  # 不缓存html,防止程序更新后缓存继续生效
+  if ($request_filename ~* .*\.(?:htm|html)$) {
+    add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
+    access_log on;
+  }
+  # 这里是vue打包文件dist内的文件的存放路径
+  root   /srv/www/project/;
+  index  index.html index.htm;
+}
+
+

部署时可能会发现资源路径不对,只需要修改.env.production文件即可。

# 根据自己路径来配置更改
+# 注意需要以 / 开头和结尾
+VITE_PUBLIC_PATH=/
+VITE_PUBLIC_PATH=/xxx/
+

前端路由与服务端的结合

项目前端路由使用的是 vue-router,所以你可以选择两种方式:history 和 hash。

  • hash 默认会在 url 后面拼接#
  • history 则不会,不过 history 需要服务器配合

可在 src/router/index.ts 内进行 mode 修改

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router';
+
+createRouter({
+  history: createWebHashHistory(),
+  // or
+  history: createWebHistory(),
+});
+

history 路由模式下服务端配置

开启 history 模式需要服务器配置,更多的服务器配置详情可以看 history-mode

这里以 nginx 配置为例

部署到根目录

server {
+  listen 80;
+  location / {
+    # 用于配合 History 使用
+    try_files $uri $uri/ /index.html;
+  }
+}
+

部署到非根目录

  1. 首先需要在打包的时候更改配置
# 在.env.production内,配置子目录路径
+VITE_PUBLIC_PATH = /sub/
+
server {
+    listen       80;
+    server_name  localhost;
+    location /sub/ {
+      # 这里是vue打包文件dist内的文件的存放路径
+      alias   /srv/www/project/;
+      index index.html index.htm;
+      try_files $uri $uri/ /sub/index.html;
+    }
+}
+

使用 nginx 处理跨域

使用 nginx 处理项目部署后的跨域问题

  1. 配置前端项目接口地址
# 在.env.production内,配置接口地址
+VITE_GLOB_API_URL=/api
+
  1. 在 nginx 配置请求转发到后台
server {
+  listen       8080;
+  server_name  localhost;
+  # 接口代理,用于解决跨域问题
+  location /api {
+    proxy_set_header Host $host;
+    proxy_set_header X-Real-IP $remote_addr;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    # 后台接口地址
+    proxy_pass http://110.110.1.1:8080/api;
+    proxy_redirect default;
+    add_header Access-Control-Allow-Origin *;
+    add_header Access-Control-Allow-Headers X-Requested-With;
+    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
+  }
+}
+
+ + + + \ No newline at end of file diff --git a/guide/design.html b/guide/design.html new file mode 100644 index 00000000..691473a3 --- /dev/null +++ b/guide/design.html @@ -0,0 +1,107 @@ + + + + + + 样式 | Vben Admin + + + + + + + + + + + + + + + + +

样式

介绍

主要介绍如何在项目中使用和规划样式文件。

默认使用 less 作为预处理语言,建议在使用前或者遇到疑问时学习一下 Less 的相关特性(如果想获取基础的 CSS 知识或查阅属性,请参考 MDN 文档)。

项目中使用的通用样式,都存放于 src/design/ 下面。

.
+├── ant # ant design 一些样式覆盖
+├── color.less # 颜色
+├── index.less # 入口
+├── public.less # 公共类
+├── theme.less # 主题相关
+├── config.less  # 每个组件都会自动引入样式
+├── transition # 动画相关
+└── var # 变量
+
+

全局注入

config.less 这个文件会被全局注入到所有文件,所以在页面内可以直接使用变量而不需要手动引入

<style lang="less" scoped>
+  // 这里已经隐式注入了 config.less
+</style>
+

tailwindcss(2.5.0+)

项目中引用到了 tailwindcss,具体可以见文件使用说明。

语法如下:

<div class="relative w-full h-full px-4"></div>
+

windicss(2.5.0 已弃用)

项目中使用了 windicss,具体参见文件使用说明。

语法如下:

<div class="relative w-full h-full px-4"></div>
+

注意事项

windcss 目前会造成本地开发内存溢出,所以后续可能会考虑切换到 TailwindCss,两者基本相同。

所以尽量少用 Windicss 新增的特性,防止后续切换成本高。

为什么使用 Less

主要是因为 Ant Design 默认使用 less 作为样式语言,使用 Less 可以跟其保持一致。

开启 scoped

没有加 scoped 属性,默认会编译成全局样式,可能会造成全局污染

<style></style>
+
+<style scoped></style>
+

温馨提醒

使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。

深度选择器

有时我们可能想明确地制定一个针对子组件的规则。

如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符。有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

详情可以查看 RFC0023-scoped-styles-changes

使用 scoped 后,父组件的样式将不会渗透到子组件中,所以可以使用以下方式解决:

<style scoped>
+  /* deep selectors */
+  ::v-deep(.foo) {
+  }
+  /* shorthand */
+  :deep(.foo) {
+  }
+
+  /* targeting slot content */
+  ::v-slotted(.foo) {
+  }
+  /* shorthand */
+  :slotted(.foo) {
+  }
+
+  /* one-off global rule */
+  ::v-global(.foo) {
+  }
+  /* shorthand */
+  :global(.foo) {
+  }
+</style>
+

CSS Modules

针对样式覆盖问题,还有一种方案是使用 CSS Modules 模块化方案。使用方式如下。

<template>
+  <span :class="$style.span1">hello</span>
+</template>
+
+<script>
+  import { useCSSModule } from 'vue';
+
+  export default {
+    setup(props, context) {
+      const $style = useCSSModule();
+      const moduleAStyle = useCSSModule('moduleA');
+      return {
+        $style,
+        moduleAStyle,
+      };
+    },
+  };
+</script>
+
+<style lang="less" module>
+  .span1 {
+    color: green;
+    font-size: 30px;
+  }
+</style>
+
+<style lang="less" module="moduleA">
+  .span1 {
+    color: green;
+    font-size: 30px;
+  }
+</style>
+

重复引用问题

加上 reference 可以解决页面内重复引用导致实际生成的 style 样式表重复的问题。

这步已经全局引入了。所以可以不写,直接使用变量

<style lang="less" scoped>
+  /* 该行代码已全局引用。可以不用单独引入 */
+  @import (reference) '../../design/config.less';
+<style>
+
+ + + + \ No newline at end of file diff --git a/guide/electron.html b/guide/electron.html new file mode 100644 index 00000000..81ec6918 --- /dev/null +++ b/guide/electron.html @@ -0,0 +1,37 @@ + + + + + + Electron | Vben Admin + + + + + + + + + + + + + + + + +

Electron

URL 模式

这种模式会先启动 vite 服务,Electron 使用 Url 地址来进行渲染

使用

从 GitHub 获取代码

Electron 代码在 electron-main 分支

# clone electron-main分支代码
+git clone -b electron-main https://github.com/vbenjs/vue-vben-admin vben-admin-electron
+

安装依赖

yarn
+

提示

首次下载 Electron 依赖会比较慢,可以在项目根目录下新建.npmrc文件,填入下方内容即可

ELETRON_MIRROR=https://npm.taobao.org/mirrors/electron/
+

运行

yarn dev:app
+

打包

yarn build:app
+

标准模式

TODO: 待适配

+ + + + \ No newline at end of file diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 00000000..94cc42e9 --- /dev/null +++ b/guide/index.html @@ -0,0 +1,130 @@ + + + + + + 开始 | Vben Admin + + + + + + + + + + + + + + + + +

开始

本文会帮助你从头启动项目

前言

关于组件

项目虽然二次封装了一些组件,但是可能不能满足大部分的要求。所以,如果组件不满足你的要求,完全可以不用甚至删除代码自己写,不必坚持使用项目自带的组件。

环境准备

本地环境需要安装 pnpmNode.jsGit

注意

  • 推荐使用pnpm,否则依赖可能安装不上。
  • Node.js 版本要求14.x以上,这里推荐 20.x 及以上。
  • 推荐安装 nvm 来管理 Node.js 版本。

工具配置

如果您使用的 IDE 是vscode(推荐)的话,可以安装以下工具来提高开发效率及代码格式化

代码获取

注意

注意存放代码的目录及所有父级目录不能存在中文、韩文、日文以及空格,否则安装依赖后启动会出错。

从 GitHub 获取代码

# clone 代码
+git clone https://github.com/vbenjs/vue-vben-admin.git
+
+

从 Gitee 获取代码

如果从 github clone 代码较慢的话,可以尝试用 Gitee 同步代码到自己的仓库,再 clone 下来即可。

也可以通过下方地址进行 clone

git clone https://gitee.com/annsion/vue-vben-admin.git
+

注意

Gitee的代码可能不是最新的

安装

安装 Node.js

如果您电脑未安装Node.js,请安装它。

验证

# 出现相应npm版本即可
+npm -v
+# 出现相应node版本即可
+node -v
+
+

如果你需要同时存在多个 node 版本,可以使用 Nvm 或者其他工具进行 Node.js 进行版本管理。

安装依赖

pnpm 安装

必须使用 pnpm进行依赖安装(若其他包管理器安装不了需要自行处理)。

如果未安装pnpm,可以用下面命令来进行全局安装

# 全局安装pnpm
+npm install -g pnpm
+# 验证
+pnpm -v # 出现对应版本号即代表安装成功
+

依赖安装命令

在项目根目录下,打开命令窗口执行,耐心等待安装完成即可

# 安装依赖
+pnpm i
+

安装依赖时 husky 安装失败

请查看你的源码是否从 github 直接下载的,直接下载是没有 .git 文件夹的,而 husky 需要依赖 git 才能安装。此时需使用 git init 初始化项目,再尝试重新安装即可。

npm script

"scripts": {
+  # 安装依赖
+  "bootstrap": "pnpm install",
+  # 构建项目
+  "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build",
+  # 生成打包分析,在电脑上执行完成后会自动打开界面
+  "build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode analyze",
+  # 构建成docker镜像
+  "build:docker": "vite build --mode docker",
+  # 清空缓存后构建项目
+  "build:no-cache": "pnpm clean:cache && npm run build",
+  "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 pnpm vite build --mode test",
+  # 用于生成标准化的git commit message
+  "commit": "czg",
+  # 运行项目
+  "dev": "pnpm vite",
+  "preinstall": "npx only-allow pnpm",
+  "postinstall": "turbo run stub",
+  "lint": "turbo run lint",
+  # 执行 eslint 校验,并修复部分问题
+  "lint:eslint": "eslint --cache --max-warnings 0  \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
+  # 执行 prettier 格式化(该命令会对项目所有代码进行 prettier 格式化,请谨慎执行)
+  "lint:prettier": "prettier --write .",
+  # 执行 stylelint 格式化
+  "lint:stylelint": "stylelint \"**/*.{vue,css,less,scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/",
+  # 安装git hooks
+  "prepare": "husky install",
+  # 预览打包后的内容(先打包在进行预览)
+  "preview": "npm run build && vite preview",
+  # 重新安装依赖
+  "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap",
+  # 运行项目
+  "serve": "npm run dev",
+  # 对打包结果进行 gzip 测试
+  "test:gzip": "npx http-server dist --cors --gzip -c-1",
+  # 类型检查
+  "type:check": "vue-tsc --noEmit --skipLibCheck"
+},
+

生成图标集

该命令会生成所选择的图标集,提供给图标选择器使用。具体使用方式请查看 图标集生成

重新安装依赖

该命令会先删除 node_modulesyarn.lockpackage.lock.json 后再进行依赖重新安装(安装速度会明显变慢)。

接下来你可以修改代码进行业务开发了。我们内建了模拟数据、HMR 实时预览、状态管理、国际化、全局路由等各种实用的功能辅助开发,请阅读其他章节了解更多。

目录说明


+.
+├── build # 打包脚本相关
+│   ├── config # 配置文件
+│   ├── generate # 生成器
+│   ├── script # 脚本
+│   └── vite # vite配置
+├── mock # mock文件夹
+├── public # 公共静态资源目录
+├── src # 主目录
+│   ├── api # 接口文件
+│   ├── assets # 资源文件
+│   │   ├── icons # icon sprite 图标文件夹
+│   │   ├── images # 项目存放图片的文件夹
+│   │   └── svg # 项目存放svg图片的文件夹
+│   ├── components # 公共组件
+│   ├── design # 样式文件
+│   ├── directives # 指令
+│   ├── enums # 枚举/常量
+│   ├── hooks # hook
+│   │   ├── component # 组件相关hook
+│   │   ├── core # 基础hook
+│   │   ├── event # 事件相关hook
+│   │   ├── setting # 配置相关hook
+│   │   └── web # web相关hook
+│   ├── layouts # 布局文件
+│   │   ├── default # 默认布局
+│   │   ├── iframe # iframe布局
+│   │   └── page # 页面布局
+│   ├── locales # 多语言
+│   ├── logics # 逻辑
+│   ├── main.ts # 主入口
+│   ├── router # 路由配置
+│   ├── settings # 项目配置
+│   │   ├── componentSetting.ts # 组件配置
+│   │   ├── designSetting.ts # 样式配置
+│   │   ├── encryptionSetting.ts # 加密配置
+│   │   ├── localeSetting.ts # 多语言配置
+│   │   ├── projectSetting.ts # 项目配置
+│   │   └── siteSetting.ts # 站点配置
+│   ├── store # 数据仓库
+│   ├── utils # 工具类
+│   └── views # 页面
+├── types # 类型文件
+└── vite.config.ts # vite配置文件
+
+
+ + + + \ No newline at end of file diff --git a/guide/introduction.html b/guide/introduction.html new file mode 100644 index 00000000..c660be6e --- /dev/null +++ b/guide/introduction.html @@ -0,0 +1,39 @@ + + + + + + 介绍 | Vben Admin + + + + + + + + + + + + + + + + +

介绍

简介

Vue-Vben-Admin 是一个基于 Vue3.0ViteAnt-Design-VueTypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3vitets 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。

文档

  • 中文文档地址为 vben-admin-doc,采用 Vitepress 开发。如发现文档有误,欢迎提 pr 帮助我们改进。
  • 英文文档暂时没有时间来写,欢迎有时间的同学来帮忙写英文文档。

本地运行文档

如需本地运行文档,请拉取代码到本地。

# 拉取代码
+git clone https://github.com/vbenjs/vue-vben-admin-doc
+
+# 安装依赖
+yarn
+
+# 运行项目
+yarn dev
+

需要掌握的基础知识

本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:

模版

该版本主要是提供一些 Demo 示例及插件的使用集成方式,主要用于参考。如果对项目不是很熟悉,不建议在此基础上进行开发,请使用下方提供的精简版本。

vue-vben-admin 精简版本。删除了相关示例、无用文件及功能、依赖。可以根据自身需求安装对应的依赖。因为使用的是 vite,依赖删除不会导致相关组件或者 hook 发出警告。只在需要的时候安装对应的库即可。

vite 插件推荐

如果这些插件对你有帮助,可以给一个 star 支持下

浏览器支持

本地开发推荐使用Chrome 最新版浏览器,不支持Chrome 80以下版本。

生产环境支持现代浏览器,不支持 IE。

IEIE EdgeEdgeFirefoxFirefoxChromeChromeSafariSafari
not supportlast 2 versionslast 2 versionslast 2 versionslast 2 versions

如何加入我们

  • Vue-Vben-Admin 还在持续更新中,本项目欢迎您的参与,共同维护,逐步完善,将项目做得更强。同时整个项目本着一切免费的原则,原则上不会收取任何费用及版权,可以放心使用。
  • 如果你想加入我们,可以多提供一些好的建议或者提交 pr,我们会根据你的活跃度邀请你加入。
+ + + + \ No newline at end of file diff --git a/guide/lib.html b/guide/lib.html new file mode 100644 index 00000000..20acefad --- /dev/null +++ b/guide/lib.html @@ -0,0 +1,52 @@ + + + + + + 引入外部模块 | Vben Admin + + + + + + + + + + + + + + + + +

引入外部模块

除了自带组件以外,有时我们还需要引入其他外部模块。我们以 ant-design-vue 为例:

安装

安装 ant-design-vue

# 在终端输入下面的命令完成安装
+yarn add ant-design-vue
+

使用

全局使用

import { createApp } from 'vue';
+import App from './App.vue';
+import Antd from 'ant-design-vue';
+const app = createApp(App);
+app.use(Antd);
+app.mount('#app');
+

局部使用

<template>
+  <Button>text</Button>
+</template>
+
+<script>
+  import { defineComponent } from 'vue';
+  import { Button } from 'ant-design-vue';
+  export default defineComponent({
+    components: {
+      Button,
+    },
+  });
+</script>
+

注意

  • 如果组件有依赖样式,则需要再引入样式文件
+ + + + \ No newline at end of file diff --git a/guide/menu.html b/guide/menu.html new file mode 100644 index 00000000..85e42a21 --- /dev/null +++ b/guide/menu.html @@ -0,0 +1,91 @@ + + + + + + 菜单 | Vben Admin + + + + + + + + + + + + + + + + +

菜单

项目菜单配置存放于 src/router/menus 下面

提示

菜单必须和路由匹配才能显示

菜单项类型

export interface Menu {
+  //  菜单名
+  name: string;
+  // 菜单图标,如果没有,则会尝试使用route.meta.icon
+  icon?: string;
+  // 菜单图片,如果同时传递了icon和img,则只会显示img
+  img?: string;
+  // 菜单路径
+  path: string;
+  // 是否禁用
+  disabled?: boolean;
+  // 子菜单
+  children?: Menu[];
+  // 菜单标签设置
+  tag: {
+    // 为true则显示小圆点
+    dot: boolean;
+    // 内容
+    content: string';
+    // 类型
+    type: 'error' | 'primary' | 'warn' | 'success';
+  };
+  // 是否隐藏菜单
+  hideMenu?: boolean;
+}
+

菜单模块

一个菜单文件会被当作一个模块

提示

children 的 path 字段不需要以/开头

import type { MenuModule } from '/@/router/types';
+import { t } from '/@/hooks/web/useI18n';
+const menu: MenuModule = {
+  orderNo: 10,
+  menu: {
+    name: t('routes.dashboard.dashboard'),
+    path: '/dashboard',
+
+    children: [
+      {
+        path: 'analysis',
+        name: t('routes.dashboard.analysis'),
+      },
+      {
+        path: 'workbench',
+        name: t('routes.dashboard.workbench'),
+      },
+    ],
+  },
+};
+export default menu;
+

以上模块会转化成以下结构

[
+  path: '/dashboard',
+  name: t('routes.dashboard.dashboard'),
+  children: [
+    {
+      path: 'dashboard/analysis',
+      name: t('routes.dashboard.analysis'),
+    },
+    {
+      path: 'dashboard/workbench',
+      name: t('routes.dashboard.workbench'),
+    },
+  ],
+]
+

新增菜单

直接在 src/router/routes/modules 内新增一个模块文件即可。

不需要手动引入,放在src/router/routes/modules 内的文件会自动被加载。

菜单排序

在菜单模块内,设置 orderNo 变量,数值越大,排序越靠后

+ + + + \ No newline at end of file diff --git a/guide/mock.html b/guide/mock.html new file mode 100644 index 00000000..cfffed66 --- /dev/null +++ b/guide/mock.html @@ -0,0 +1,443 @@ + + + + + + 数据 mock&联调 | Vben Admin + + + + + + + + + + + + + + + + +

数据 mock&联调

开发环境

如果前端应用和后端接口服务器没有运行在同一个主机上,你需要在开发环境下将接口请求代理到接口服务器。

如果是同一个主机,可以直接请求具体的接口地址。

配置

开发环境时候,接口地址在项目根目录下

.env.development 文件配置

# vite 本地跨域代理
+VITE_PROXY=[["/basic-api","http://localhost:3000"]]
+# 接口地址
+VITE_GLOB_API_URL=/api
+

TIP

  • .env 文件中的字段如果是字符串,则无需加引号,默认全部为字符串
  • VITE_PROXY 不能换行

TIP

v3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。

跨域处理

如果你在 src/api/ 下面的接口为下方代码,且 .env.development 文件配置如下注释,则在控制台看到的地址为 http://localhost:3100/basic-api/login

由于 /basic-api 匹配到了设置的 VITE_PROXY,所以上方实际是请求 http://localhost:3000/login,这样同时也解决了跨域问题。(3100为项目端口号,http://localhost:3000为PROXY代理的目标地址)

// .env.development
+// VITE_PROXY=[["/basic-api","http://localhost:3000"]]
+// VITE_GLOB_API_URL=/basic-api
+
+enum Api {
+  Login = '/login',
+}
+
+/**
+ * @description: 用户登陆
+ */
+export function loginApi(params: LoginParams) {
+  return http.request<LoginResultModel>({
+    url: Api.Login,
+    method: 'POST',
+    params,
+  });
+}
+

没有跨域时的配置

如果没有跨域问题,可以直接忽略 VITE_PROXY 配置,直接将接口地址设置在 VITE_GLOB_API_URL

# 例如接口地址为 http://localhost:3000 则
+VITE_GLOB_API_URL=http://localhost:3000
+

如果有跨域问题,将 VITE_GLOB_API_URL 设置为跟 VITE_PROXY 内其中一个数组的第一个项一致的值即可。

下方的接口地址设置为 /basic-api,当请求发出的时候会经过 Vite 的 proxy 代理,匹配到了我们设置的 VITE_PROXY 规则,将 /basic-api 转化为 http://localhost:3000 进行请求

# 例如接口地址为 http://localhost:3000 则
+VITE_PROXY=[["/basic-api","http://localhost:3000"]]
+# 接口地址
+VITE_GLOB_API_URL=/basic-api
+

跨域原理解析

vite.config.ts 配置文件中,提供了 server 的 proxy 功能,用于代理 API 请求。

server: {
+  proxy: {
+    "/basic-api":{
+      target: 'http://localhost:3000',
+      changeOrigin: true,
+      ws: true,
+      rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''),
+    }
+  },
+},
+

注意

从浏览器控制台的 Network 看,请求是 http://localhost:3000/basic-api/xxx,这是因为 proxy 配置不会改变本地请求的 url。

生产环境

生产环境接口地址在项目根目录下 .env.production 文件配置。

生产环境接口地址值需要修改 VITE_GLOB_API_URL,如果出现跨域问题,可以使用 nginx 或者后台开启 cors 进行处理

打包后如何进行地址修改?

VITE_GLOB_* 开头的变量会在打包的时候注入 _app.config.js 文件内。

dist/_app.config.js 修改相应的接口地址后刷新页面即可,不需要在根据不同环境打包多次,一次打包可以用于多个不同接口环境的部署。

接口请求

在 vue-vben-admin 中:

  1. 页面交互操作;
  2. 调用统一管理的 api 请求函数;
  3. 使用封装的 axios.ts 发送请求;
  4. 获取服务端返回数据
  5. 更新 data;

接口统一存放于 src/api/ 下面管理

以登陆接口为例:

src/api/ 内新建模块文件,其中参数与返回值最好定义一下类型,方便校验。虽然麻烦,但是后续维护字段很方便。

TIP

类型定义文件可以抽取出去统一管理,具体参考项目

import { defHttp } from '/@/utils/http/axios';
+import { LoginParams, LoginResultModel } from './model/userModel';
+
+enum Api {
+  Login = '/login',
+}
+
+export function loginApi(params: LoginParams) {
+  return defHttp.request<LoginResultModel>({
+    url: Api.Login,
+    method: 'POST',
+    params,
+  });
+}
+

axios 配置

axios 请求封装存放于 src/utils/http/axios 文件夹内部

index.ts 文件内容需要根据项目自行修改外,其余文件无需修改


+├── Axios.ts // axios实例
+├── axiosCancel.ts // axiosCancel实例,取消重复请求
+├── axiosTransform.ts // 数据转换类
+├── checkStatus.ts // 返回状态值校验
+├── index.ts // 接口返回统一处理
+
+

index.ts 配置说明

const axios = new VAxios({
+  // 认证方案,例如: Bearer
+  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
+  authenticationScheme: '',
+  // 接口超时时间 单位毫秒
+  timeout: 10 * 1000,
+  // 接口可能会有通用的地址部分,可以统一抽取出来
+  prefixUrl: prefix,
+  headers: { 'Content-Type': ContentTypeEnum.JSON },
+  // 数据处理方式,见下方说明
+  transform,
+  // 配置项,下面的选项都可以在独立的接口请求中覆盖
+  requestOptions: {
+    // 默认将prefix 添加到url
+    joinPrefix: true,
+    // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+    isReturnNativeResponse: false,
+    // 需要对返回数据进行处理
+    isTransformRequestResult: true,
+    // post请求的时候添加参数到url
+    joinParamsToUrl: false,
+    // 格式化提交参数时间
+    formatDate: true,
+    // 消息提示类型
+    errorMessageMode: 'message',
+    // 接口地址
+    apiUrl: globSetting.apiUrl,
+    //  是否加入时间戳
+    joinTime: true,
+    // 忽略重复请求
+    ignoreCancelToken: true,
+  },
+});
+

transform 数据处理说明

类型定义,见 axiosTransform.ts 文件

export abstract class AxiosTransform {
+  /**
+   * @description: 请求之前处理配置
+   */
+  beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig;
+
+  /**
+   * @description: 请求成功处理
+   */
+  transformRequestData?: (res: AxiosResponse<Result>, options: RequestOptions) => any;
+
+  /**
+   * @description: 请求失败处理
+   */
+  requestCatch?: (e: Error) => Promise<any>;
+
+  /**
+   * @description: 请求之前的拦截器
+   */
+  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig;
+
+  /**
+   * @description: 请求之后的拦截器
+   */
+  responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>;
+
+  /**
+   * @description: 请求之前的拦截器错误处理
+   */
+  requestInterceptorsCatch?: (error: Error) => void;
+
+  /**
+   * @description: 请求之后的拦截器错误处理
+   */
+  responseInterceptorsCatch?: (error: Error) => void;
+}
+
+
+

项目默认 transform 处理逻辑,可以根据各自项目进行处理。一般需要更改的部分为下方代码,见代码注释说明

/**
+ * @description: 数据处理,方便区分多种处理方式
+ */
+const transform: AxiosTransform = {
+  /**
+   * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
+   */
+  transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
+    const { t } = useI18n();
+    const { isTransformResponse, isReturnNativeResponse } = options;
+    // 是否返回原生响应头 比如:需要获取响应头时使用该属性
+    if (isReturnNativeResponse) {
+      return res;
+    }
+    // 不进行任何处理,直接返回
+    // 用于页面代码可能需要直接获取code,data,message这些信息时开启
+    if (!isTransformResponse) {
+      return res.data;
+    }
+    // 错误的时候返回
+
+    const { data } = res;
+    if (!data) {
+      // return '[HTTP] Request has no return value';
+      throw new Error(t('sys.api.apiRequestFailed'));
+    }
+    //  这里 code,result,message为 后台统一的字段,需要在 types.ts内修改为项目自己的接口返回格式
+    const { code, result, message } = data;
+
+    // 这里逻辑可以根据项目进行修改
+    const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS;
+    if (hasSuccess) {
+      return result;
+    }
+
+    // 在此处根据自己项目的实际情况对不同的code执行不同的操作
+    // 如果不希望中断当前请求,请return数据,否则直接抛出异常即可
+    let timeoutMsg = '';
+    switch (code) {
+      case ResultEnum.TIMEOUT:
+        timeoutMsg = t('sys.api.timeoutMessage');
+      default:
+        if (message) {
+          timeoutMsg = message;
+        }
+    }
+
+    // errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
+    // errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
+    if (options.errorMessageMode === 'modal') {
+      createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });
+    } else if (options.errorMessageMode === 'message') {
+      createMessage.error(timeoutMsg);
+    }
+
+    throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));
+  },
+
+  // 请求之前处理config
+  beforeRequestHook: (config, options) => {
+    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options;
+
+    if (joinPrefix) {
+      config.url = `${urlPrefix}${config.url}`;
+    }
+
+    if (apiUrl && isString(apiUrl)) {
+      config.url = `${apiUrl}${config.url}`;
+    }
+    const params = config.params || {};
+    if (config.method?.toUpperCase() === RequestEnum.GET) {
+      if (!isString(params)) {
+        // 给 get 请求加上时间戳参数,避免从缓存中拿数据。
+        config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
+      } else {
+        // 兼容restful风格
+        config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
+        config.params = undefined;
+      }
+    } else {
+      if (!isString(params)) {
+        formatDate && formatRequestDate(params);
+        config.data = params;
+        config.params = undefined;
+        if (joinParamsToUrl) {
+          config.url = setObjToUrlParams(config.url as string, config.data);
+        }
+      } else {
+        // 兼容restful风格
+        config.url = config.url + params;
+        config.params = undefined;
+      }
+    }
+    return config;
+  },
+
+  /**
+   * @description: 请求拦截器处理
+   */
+  requestInterceptors: (config, options) => {
+    // 请求之前处理config
+    const token = getToken();
+    if (token) {
+      // jwt token
+      config.headers.Authorization = options.authenticationScheme
+        ? `${options.authenticationScheme} ${token}`
+        : token;
+    }
+    return config;
+  },
+
+  /**
+   * @description: 响应拦截器处理
+   */
+  responseInterceptors: (res: AxiosResponse<any>) => {
+    return res;
+  },
+
+  /**
+   * @description: 响应错误处理
+   */
+  responseInterceptorsCatch: (error: any) => {
+    const { t } = useI18n();
+    const errorLogStore = useErrorLogStoreWithOut();
+    errorLogStore.addAjaxErrorInfo(error);
+    const { response, code, message, config } = error || {};
+    const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none';
+    const msg: string = response?.data?.error?.message ?? '';
+    const err: string = error?.toString?.() ?? '';
+    let errMessage = '';
+
+    try {
+      if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
+        errMessage = t('sys.api.apiTimeoutMessage');
+      }
+      if (err?.includes('Network Error')) {
+        errMessage = t('sys.api.networkExceptionMsg');
+      }
+
+      if (errMessage) {
+        if (errorMessageMode === 'modal') {
+          createErrorModal({ title: t('sys.api.errorTip'), content: errMessage });
+        } else if (errorMessageMode === 'message') {
+          createMessage.error(errMessage);
+        }
+        return Promise.reject(error);
+      }
+    } catch (error) {
+      throw new Error(error);
+    }
+
+    checkStatus(error?.response?.status, msg, errorMessageMode);
+    return Promise.reject(error);
+  },
+};
+

更改参数格式

项目接口默认为 Json 参数格式,即 headers: { 'Content-Type': ContentTypeEnum.JSON },

如果需要更改为 form-data 格式,更改 headers 的 'Content-TypeContentTypeEnum.FORM_URLENCODED 即可

多个接口地址

当项目中需要用到多个接口地址时, 可以在 src/utils/http/axios/index.ts 导出多个 axios 实例

// 目前只导出一个默认实例,接口地址对应的是环境变量中的 VITE_GLOB_API_URL 接口地址
+export const defHttp = createAxios();
+
+// 需要有其他接口地址的可以在后面添加
+
+// other api url
+export const otherHttp = createAxios({
+  requestOptions: {
+    apiUrl: 'xxx',
+  },
+});
+

删除请求 URL 携带的时间戳参数

如果不需要 url 上面默认携带的时间戳参数 ?_t=xxx

const axios = new VAxios({
+  requestOptions: {
+    // 是否加入时间戳
+    joinTime: false,
+  },
+});
+

Mock 服务

Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发进程所阻塞。

本项目使用 vite-plugin-mock 来进行 mock 数据处理。项目内 mock 服务分本地和线上

本地 Mock

本地 mock 采用 Node.js 中间件进行参数拦截(不采用 mock.js 的原因是本地开发看不到请求参数和响应结果)。

如何新增 mock 接口

如果你想添加 mock 数据,只要在根目录下找到 mock 文件,添加对应的接口,对其进行拦截和模拟数据。

在 mock 文件夹内新建文件

TIP

文件新增后会自动更新,不需要手动重启,可以在代码控制台查看日志信息 mock 文件夹内会自动注册,排除以_开头的文件夹及文件

例:

import { MockMethod } from 'vite-plugin-mock';
+import { resultPageSuccess } from '../_util';
+
+const demoList = (() => {
+  const result: any[] = [];
+  for (let index = 0; index < 60; index++) {
+    result.push({
+      id: `${index}`,
+      beginTime: '@datetime',
+      endTime: '@datetime',
+      address: '@city()',
+      name: '@cname()',
+      'no|100000-10000000': 100000,
+      'status|1': ['正常', '启用', '停用'],
+    });
+  }
+  return result;
+})();
+
+export default [
+  {
+    url: '/api/table/getDemoList',
+    timeout: 1000,
+    method: 'get',
+    response: ({ query }) => {
+      const { page = 1, pageSize = 20 } = query;
+      return resultPageSuccess(page, pageSize, demoList);
+    },
+  },
+] as MockMethod[];
+

TIP

mock 的值可以直接使用 mockjs 的语法。

接口格式

{
+  url: string; // mock 接口地址
+  method?: MethodType; // 请求方式
+  timeout?: number; // 延时时间
+  statusCode: number; // 响应状态码
+  response: ((opt: { // 响应结果
+      body: any;
+      query: any;
+  }) => any) | object;
+}
+

参数获取

GET 接口: ({ query }) => { }

POST 接口: ({ body }) => { }

util 说明

可在 代码 中查看

TIP

util 只作为服务处理结果数据使用。可以不用,如需使用可自行封装,需要将对应的字段改为接口的返回结构

匹配

src/api 下面,如果接口匹配到 mock,则会优先使用 mock 进行响应

import { defHttp } from '/@/utils/http/axios';
+import { LoginParams, LoginResultModel } from './model/userModel';
+
+enum Api {
+  Login = '/login',
+}
+
+/**
+ * @description: user login api
+ */
+export function loginApi(params: LoginParams) {
+  return defHttp.request<LoginResultModel>(
+    {
+      url: Api.Login,
+      method: 'POST',
+      params,
+    },
+    {
+      errorMessageMode: 'modal',
+    }
+  );
+}
+// 会匹配到上方的
+export default [
+  {
+    url: '/api/login',
+    timeout: 1000,
+    method: 'POST',
+    response: ({ body }) => {
+      return resultPageSuccess({});
+    },
+  },
+] as MockMethod[];
+

接口有了,如何去掉 mock

当后台接口已经开发完成,只需要将相应的 mock 函数去掉即可。

以上方接口为例,假如后台接口 login 已经开发完成,则只需要删除/注释掉下方代码即可

export default [
+  {
+    url: '/api/login',
+    timeout: 1000,
+    method: 'POST',
+    response: ({ body }) => {
+      return resultPageSuccess({});
+    },
+  },
+] as MockMethod[];
+

线上 mock

由于该项目是一个展示类项目,线上也是用 mock 数据,所以在打包后同时也集成了 mock。通常项目线上一般为正式接口。

项目线上 mock 采用的是 mockjs 进行 mock 数据模拟。

线上如何开启 mock

注意

线上开启 mock 只适用于一些简单的示例网站及预览网站。一定不要在正式的生产环境开启!!!

  1. 修改 .env.production 文件内的 VITE_USE_MOCK 的值为 true
VITE_USE_MOCK = true;
+
  1. mock/_createProductionServer.ts 文件中引入需要的 mock 文件
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
+
+const modules = import.meta.globEager('./**/*.ts');
+
+const mockModules: any[] = [];
+Object.keys(modules).forEach((key) => {
+  if (key.includes('/_')) {
+    return;
+  }
+  mockModules.push(...modules[key].default);
+});
+
+export function setupProdMockServer() {
+  createProdMockServer(mockModules);
+}
+
  1. build/vite/plugin/mock.ts 里面引入
import { viteMockServe } from 'vite-plugin-mock';
+
+export function configMockPlugin(isBuild: boolean) {
+  return viteMockServe({
+    injectCode: `
+      import { setupProdMockServer } from '../mock/_createProductionServer';
+
+      setupProdMockServer();
+      `,
+  });
+}
+

为什么通过插件注入代码而不是直接在 main.ts 内插入

在插件内通过 injectCode 插入代码,方便控制 mockjs 是否被打包到最终代码内。如果在 main.ts 内判断,如果关闭了 mock 功能,mockjs 也会打包到构建文件内,这样会增加打包体积。

到这里线上 mock 就配置完成了。线上与本地差异不大,比较大的区别是线上在控制台内看不到接口请求日志。

+ + + + \ No newline at end of file diff --git a/guide/router.html b/guide/router.html new file mode 100644 index 00000000..9bbf0ad1 --- /dev/null +++ b/guide/router.html @@ -0,0 +1,291 @@ + + + + + + 路由 | Vben Admin + + + + + + + + + + + + + + + + +

路由

项目路由配置存放于 src/router/routes 下面。 src/router/routes/modules用于存放路由模块,在该目录下的文件会自动注册。

配置

模块说明

src/router/routes/modules 内的 .ts 文件会被视为一个路由模块。

一个路由模块包含以下结构

import type { AppRouteModule } from '/@/router/types';
+
+import { LAYOUT } from '/@/router/constant';
+import { t } from '/@/hooks/web/useI18n';
+
+const dashboard: AppRouteModule = {
+  path: '/dashboard',
+  name: 'Dashboard',
+  component: LAYOUT,
+  redirect: '/dashboard/analysis',
+  meta: {
+    icon: 'ion:grid-outline',
+    title: t('routes.dashboard.dashboard'),
+  },
+  children: [
+    {
+      path: 'analysis',
+      name: 'Analysis',
+      component: () => import('/@/views/dashboard/analysis/index.vue'),
+      meta: {
+        affix: true,
+        title: t('routes.dashboard.analysis'),
+      },
+    },
+    {
+      path: 'workbench',
+      name: 'Workbench',
+      component: () => import('/@/views/dashboard/workbench/index.vue'),
+      meta: {
+        title: t('routes.dashboard.workbench'),
+      },
+    },
+  ],
+};
+export default dashboard;
+

多级路由

注意事项

  • 整个项目所有路由 name 不能重复
  • 所有的多级路由最终都会转成二级路由,所以不能内嵌子路由
  • 除了 layout 对应的 path 前面需要加 /,其余子路由都不要以/开头

示例

import type { AppRouteModule } from '/@/router/types';
+import { getParentLayout, LAYOUT } from '/@/router/constant';
+import { t } from '/@/hooks/web/useI18n';
+const permission: AppRouteModule = {
+  path: '/level',
+  name: 'Level',
+  component: LAYOUT,
+  redirect: '/level/menu1/menu1-1/menu1-1-1',
+  meta: {
+    icon: 'ion:menu-outline',
+    title: t('routes.demo.level.level'),
+  },
+
+  children: [
+    {
+      path: 'tabs/:id', 
+      name: 'TabsParams',
+      component: getParentLayout('TabsParams'),
+      meta: {
+        carryParam: true,
+        hidePathForChildren: true, // 本级path将会在子级菜单中合成完整path时会忽略这一层级
+      },
+      children: [
+        path: 'tabs/id1', // 其上级有标记hidePathForChildren,所以本级在生成菜单时最终的path为  /level/tabs/id1
+        name: 'TabsParams',
+        component: getParentLayout('TabsParams'),
+        meta: {
+          carryParam: true,
+          ignoreRoute: true,  // 本路由仅用于菜单生成,不会在实际的路由表中出现
+        },
+      ]
+    },
+    {
+      path: 'menu1',
+      name: 'Menu1Demo',
+      component: getParentLayout('Menu1Demo'),
+      meta: {
+        title: 'Menu1',
+      },
+      redirect: '/level/menu1/menu1-1/menu1-1-1',
+      children: [
+        {
+          path: 'menu1-1',
+          name: 'Menu11Demo',
+          component: getParentLayout('Menu11Demo'),
+          meta: {
+            title: 'Menu1-1',
+          },
+          redirect: '/level/menu1/menu1-1/menu1-1-1',
+          children: [
+            {
+              path: 'menu1-1-1',
+              name: 'Menu111Demo',
+              component: () => import('/@/views/demo/level/Menu111.vue'),
+              meta: {
+                title: 'Menu111',
+              },
+            },
+          ],
+        },
+      ],
+    },
+  ],
+};
+
+export default permission;
+

Meta 配置说明

export interface RouteMeta {
+  // 路由title  一般必填
+  title: string;
+  // 动态路由可打开Tab页数
+  dynamicLevel?: number;
+  // 动态路由的实际Path, 即去除路由的动态部分;
+  realPath?: string;
+  // 是否忽略权限,只在权限模式为Role的时候有效
+  ignoreAuth?: boolean;
+  // 可以访问的角色,只在权限模式为Role的时候有效
+  roles?: RoleEnum[];
+  // 是否忽略KeepAlive缓存
+  ignoreKeepAlive?: boolean;
+  // 是否固定标签
+  affix?: boolean;
+  // 图标,也是菜单图标
+  icon?: string;
+  // 内嵌iframe的地址
+  frameSrc?: string;
+  // 指定该路由切换的动画名
+  transitionName?: string;
+  // 隐藏该路由在面包屑上面的显示
+  hideBreadcrumb?: boolean;
+  // 如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true
+  carryParam?: boolean;
+  // 隐藏所有子菜单
+  hideChildrenInMenu?: boolean;
+  // 当前激活的菜单。用于配置详情页时左侧激活的菜单路径
+  currentActiveMenu?: string;
+  // 当前路由不再标签页显示
+  hideTab?: boolean;
+  // 当前路由不再菜单显示
+  hideMenu?: boolean;
+  // 菜单排序,只对第一级有效
+  orderNo?: number;
+  // 忽略路由。用于在ROUTE_MAPPING以及BACK权限模式下,生成对应的菜单而忽略路由。2.5.3以上版本有效
+  ignoreRoute?: boolean;
+  // 是否在子级菜单的完整path中忽略本级path。2.5.3以上版本有效
+  hidePathForChildren?: boolean;
+}
+

外部页面嵌套

只需要将 frameSrc 设置为需要跳转的地址即可

const IFrame = () => import('/@/views/sys/iframe/FrameBlank.vue');
+{
+  path: 'doc',
+  name: 'Doc',
+  component: IFrame,
+  meta: {
+    frameSrc: 'https://vvbin.cn/doc-next/',
+    title: t('routes.demo.iframe.doc'),
+  },
+},
+

外链

只需要将 path 设置为需要跳转的HTTP 地址即可

{
+  path: 'https://vvbin.cn/doc-next/',
+  name: 'DocExternal',
+  component: IFrame,
+  meta: {
+    title: t('routes.demo.iframe.docExternal'),
+  },
+}
+

动态路由Tab自动关闭功能

若需要开启该功能,需要在动态路由的meta中设置如下两个参数:

  • dynamicLevel 最大能打开的Tab标签页数
  • realPath 动态路由实际路径(考虑到动态路由有时候可能存在N层的情况, 例:/:id/:subId/:...), 为了减少计算开销, 使用配置方式事先规定好路由的实际路径(注意: 该参数若不设置,将无法使用该功能)
{
+  path: 'detail/:id',
+  name: 'TabDetail',
+  component: () => import('/@/views/demo/feat/tabs/TabDetail.vue'),
+  meta: {
+    currentActiveMenu: '/feat/tabs',
+    title: t('routes.demo.feat.tabDetail'),
+    hideMenu: true,
+    dynamicLevel: 3,
+    realPath: '/feat/tabs/detail',
+  },
+}
+

图标

这里的 icon 配置,会同步到 菜单(icon 的值可以查看此处)。

新增路由

如何新增一个路由模块

  1. src/router/routes/modules 内新增一个模块文件。

示例,新增 test.ts 文件

import type { AppRouteModule } from '/@/router/types';
+import { LAYOUT } from '/@/router/constant';
+import { t } from '/@/hooks/web/useI18n';
+
+const dashboard: AppRouteModule = {
+  path: '/about',
+  name: 'About',
+  component: LAYOUT,
+  redirect: '/about/index',
+  meta: {
+    icon: 'simple-icons:about-dot-me',
+    title: t('routes.dashboard.about'),
+  },
+  children: [
+    {
+      path: 'index',
+      name: 'AboutPage',
+      component: () => import('/@/views/sys/about/index.vue'),
+      meta: {
+        title: t('routes.dashboard.about'),
+        icon: 'simple-icons:about-dot-me',
+      },
+    },
+  ],
+};
+
+export default dashboard;
+

此时路由已添加完成,不需要手动引入,放在src/router/routes/modules 内的文件会自动被加载。

验证

访问 ip:端口/about/index 出现对应组件内容即代表成功

路由刷新

项目中采用的是重定向方式

实现

import { useRedo } from '/@/hooks/web/usePage';
+import { defineComponent } from 'vue';
+export default defineComponent({
+  setup() {
+    const redo = useRedo();
+    // 执行刷新
+    redo();
+    return {};
+  },
+});
+

Redirect

src/views/sys/redirect/index.vue

import { defineComponent, unref } from 'vue';
+import { useRouter } from 'vue-router';
+export default defineComponent({
+  name: 'Redirect',
+  setup() {
+    const { currentRoute, replace } = useRouter();
+    const { params, query } = unref(currentRoute);
+    const { path } = params;
+    const _path = Array.isArray(path) ? path.join('/') : path;
+    replace({
+      path: '/' + _path,
+      query,
+    });
+    return {};
+  },
+});
+

页面跳转

页面跳转建议采用项目提供的 useGo

方式

import { useGo } from '/@/hooks/web/usePage';
+import { defineComponent } from 'vue';
+export default defineComponent({
+  setup() {
+    const go = useGo();
+
+    // 执行刷新
+    go();
+    go(PageEnum.Home);
+    return {};
+  },
+});
+

多标签页

标签页使用的是 keep-aliverouter-view 实现,实现切换 tab 后还能保存切换之前的状态。

如何开启页面缓存

开启缓存有 3 个条件

  1. src/settings/projectSetting.ts 内将openKeepAlive 设置为 true
  2. 路由设置 name,且不能重复
  3. 路由对应的组件加上 name,与路由设置的 name 保持一致
 {
+   ...,
+    // name
+    name: 'Login',
+    // 对应组件组件的name
+    component: () => import('/@/views/sys/login/index.vue'),
+    ...
+  },
+
+  // /@/views/sys/login/index.vue
+  export default defineComponent({
+    // 需要和路由的name一致
+    name:"Login"
+  });
+

注意

keep-alive 生效的前提是:需要将路由的 name 属性及对应的页面的 name 设置成一样。因为:

include - 字符串或正则表达式,只有名称匹配的组件会被缓存

如何让某个页面不缓存

可在 router.meta 下配置

可以将 ignoreKeepAlive 配置成 true 即可关闭缓存。

export interface RouteMeta {
+  // 是否忽略KeepAlive缓存
+  ignoreKeepAlive?: boolean;
+}
+

如何更改首页路由

首页路由指的是应用程序中的默认路由,当不输入其他任何路由时,会自动重定向到该路由下,并且该路由在Tab上是固定的,即使设置affix: false也不允许关闭

例:首页路由配置的是/dashboard/analysis,那么当直接访问 http://localhost:3100/ 会自动跳转到http://localhost:3100/#/dashboard/analysis 上(用户已登录的情况下)

可以将pageEnum.ts中的BASE_HOME更改为需要你想设置的首页即可

export enum PageEnum {
+    // basic home path
+    // 更改此处即可
+    BASE_HOME = '/dashboard',
+}
+
+
+ + + + \ No newline at end of file diff --git a/guide/settings.html b/guide/settings.html new file mode 100644 index 00000000..ddf6aab9 --- /dev/null +++ b/guide/settings.html @@ -0,0 +1,405 @@ + + + + + + 项目配置项 | Vben Admin + + + + + + + + + + + + + + + + +

项目配置项

用于修改项目的配色、布局、缓存、多语言、组件默认配置

环境变量配置

项目的环境变量配置位于项目根目录下的 .env.env.development.env.production

具体可以参考 Vite 文档

.env                # 在所有的环境中被载入
+.env.local          # 在所有的环境中被载入,但会被 git 忽略
+.env.[mode]         # 只在指定的模式中被载入
+.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略
+
+

温馨提醒

  • 只有以 VITE_ 开头的变量会被嵌入到客户端侧的包中,你可以在项目代码中这样访问它们:
console.log(import.meta.env.VITE_PROT);
+
  • VITE_GLOB_* 开头的的变量,在打包的时候,会被加入_app.config.js配置文件当中.

配置项说明

.env

所有环境适用

# 端口号
+VITE_PORT=3100
+# 网站标题
+VITE_GLOB_APP_TITLE=vben admin
+# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
+VITE_GLOB_APP_SHORT_NAME=vben_admin
+

.env.development

开发环境适用

# 是否开启mock数据,关闭时需要自行对接后台接口
+VITE_USE_MOCK=true
+# 资源公共路径,需要以 /开头和结尾
+VITE_PUBLIC_PATH=/
+# 是否删除Console.log
+VITE_DROP_CONSOLE=false
+# 本地开发代理,可以解决跨域及多地址代理
+# 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题
+# 可以有多个,注意多个不能换行,否则代理将会失效
+VITE_PROXY=[["/api","http://localhost:3000"],["api1","http://localhost:3001"],["/upload","http://localhost:3001/upload"]]
+
+::: tip
+v3.0.0开始,作者重构了vite.config.ts,新版本不再支持VITE_PROXY环境变量。
+:::
+
+# 接口地址
+# 如果没有跨域问题,直接在这里配置即可
+VITE_GLOB_API_URL=/api
+# 文件上传接口  可选
+VITE_GLOB_UPLOAD_URL=/upload
+# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换
+VITE_GLOB_API_URL_PREFIX=
+

注意

这里配置的 VITE_PROXY 以及 VITE_GLOB_API_URL, /api 需要是唯一的,不要和接口有的名字冲突

如果你的接口是 http://localhost:3000/api 之类的,请考虑将 VITE_GLOB_API_URL=/xxxx 换成别的名字

.env.production

生产环境适用

# 是否开启mock
+VITE_USE_MOCK=true
+# 接口地址 可以由nginx做转发或者直接写实际地址
+VITE_GLOB_API_URL=/api
+# 文件上传地址 可以由nginx做转发或者直接写实际地址
+VITE_GLOB_UPLOAD_URL=/upload
+# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换
+VITE_GLOB_API_URL_PREFIX=
+# 是否删除Console.log
+VITE_DROP_CONSOLE=true
+# 资源公共路径,需要以 / 开头和结尾
+VITE_PUBLIC_PATH=/
+# 打包是否输出gz|br文件
+# 可选: gzip | brotli | none
+# 也可以有多个, 例如 ‘gzip’|'brotli',这样会同时生成 .gz和.br文件
+VITE_BUILD_COMPRESS = 'gzip'
+# 打包是否压缩图片
+VITE_USE_IMAGEMIN = false
+# 打包是否开启pwa功能
+VITE_USE_PWA = false
+# 是否兼容旧版浏览器。开启后打包时间会慢一倍左右。会多打出旧浏览器兼容包,且会根据浏览器兼容性自动使用相应的版本
+VITE_LEGACY = false
+

生产环境动态配置

说明

当执行yarn build构建项目之后,会自动生成 _app.config.js 文件并插入 index.html

注意: 开发环境不会生成

// _app.config.js
+// 变量名命名规则  __PRODUCTION__xxx_CONF__   xxx:为.env配置的VITE_GLOB_APP_SHORT_NAME
+window.__PRODUCTION__VUE_VBEN_ADMIN__CONF__ = {
+  VITE_GLOB_APP_TITLE: 'vben admin',
+  VITE_GLOB_APP_SHORT_NAME: 'vue_vben_admin',
+  VITE_GLOB_API_URL: '/app',
+  VITE_GLOB_API_URL_PREFIX: '/',
+  VITE_GLOB_UPLOAD_URL: '/upload',
+};
+

作用

_app.config.js 用于项目在打包后,需要动态修改配置的需求,如接口地址。不用重新进行打包,可在打包后修改 /dist/_app.config.js 内的变量,刷新即可更新代码内的局部变量。

如何获取全局变量

想要获取 _app.config.js 内的变量,可以使用 src/hooks/setting/index.ts 提供的函数来进行获取

如何新增(新增一个可动态修改的配置项)

  1. 首先在 .env 或者对应的开发环境配置文件内,新增需要可动态配置的变量,需要以 VITE_GLOB_开头

  2. VITE_GLOB_ 开头的变量会自动加入环境变量,通过在 types/config.d.ts 内修改 GlobEnvConfigGlobConfig 两个环境变量的值来定义新添加的类型

  3. useGlobSetting 函数中添加刚新增的返回值即可

const {
+  VITE_GLOB_APP_TITLE,
+  VITE_GLOB_API_URL,
+  VITE_GLOB_APP_SHORT_NAME,
+  VITE_GLOB_API_URL_PREFIX,
+  VITE_GLOB_UPLOAD_URL,
+} = ENV;
+
+export const useGlobSetting = (): SettingWrap => {
+  // Take global configuration
+  const glob: Readonly<GlobConfig> = {
+    title: VITE_GLOB_APP_TITLE,
+    apiUrl: VITE_GLOB_API_URL,
+    shortName: VITE_GLOB_APP_SHORT_NAME,
+    urlPrefix: VITE_GLOB_API_URL_PREFIX,
+    uploadUrl: VITE_GLOB_UPLOAD_URL
+  };
+  return glob as Readonly<GlobConfig>;
+};
+
+

项目配置

WARNING

项目配置文件用于配置项目内展示的内容、布局、文本等效果,存于localStorage中。如果更改了项目配置,需要手动清空 localStorage 缓存,刷新重新登录后方可生效。

配置文件路径

src/settings/projectSetting.ts

说明

// ! 改动后需要清空浏览器缓存
+const setting: ProjectConfig = {
+  // 是否显示SettingButton
+  showSettingButton: true,
+
+  // 是否显示主题切换按钮
+  showDarkModeToggle: true,
+
+  // 设置按钮位置 可选项
+  // SettingButtonPositionEnum.AUTO: 自动选择
+  // SettingButtonPositionEnum.HEADER: 位于头部
+  // SettingButtonPositionEnum.FIXED: 固定在右侧
+  settingButtonPosition: SettingButtonPositionEnum.AUTO,
+
+  // 权限模式,默认前端角色权限模式
+  // ROUTE_MAPPING: 前端模式(菜单由路由生成,默认)
+  // ROLE:前端模式(菜单路由分开)
+  permissionMode: PermissionModeEnum.ROUTE_MAPPING,
+  // 权限缓存存放位置。默认存放于localStorage
+  permissionCacheType: CacheTypeEnum.LOCAL,
+  // 会话超时处理方案
+  // SessionTimeoutProcessingEnum.ROUTE_JUMP: 路由跳转到登录页
+  // SessionTimeoutProcessingEnum.PAGE_COVERAGE: 生成登录弹窗,覆盖当前页面
+  sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP,
+  // 项目主题色
+  themeColor: primaryColor,
+  // 网站灰色模式,用于可能悼念的日期开启
+  grayMode: false,
+  // 色弱模式
+  colorWeak: false,
+  // 是否取消菜单,顶部,多标签页显示, 用于可能内嵌在别的系统内
+  fullContent: false,
+  // 主题内容宽度
+  contentMode: ContentEnum.FULL,
+  // 是否显示logo
+  showLogo: true,
+  // 是否显示底部信息 copyright
+  showFooter: true,
+  // 头部配置
+  headerSetting: {
+    // 背景色
+    bgColor: '#ffffff',
+    // 固定头部
+    fixed: true,
+    // 是否显示顶部
+    show: true,
+    // 主题
+    theme: MenuThemeEnum.LIGHT,
+    // 开启锁屏功能
+    useLockPage: true,
+    // 显示全屏按钮
+    showFullScreen: true,
+    // 显示文档按钮
+    showDoc: true,
+    // 显示消息中心按钮
+    showNotice: true,
+    // 显示菜单搜索按钮
+    showSearch: true,
+  },
+  // 菜单配置
+  menuSetting: {
+    // 背景色
+    bgColor: '#273352',
+    // 是否固定住菜单
+    fixed: true,
+    // 菜单折叠
+    collapsed: false,
+    // 折叠菜单时候是否显示菜单名
+    collapsedShowTitle: false,
+    // 是否可拖拽
+    canDrag: true,
+    // 是否显示
+    show: true,
+    // 菜单宽度
+    menuWidth: 180,
+    // 菜单模式
+    mode: MenuModeEnum.INLINE,
+    // 菜单类型
+    type: MenuTypeEnum.SIDEBAR,
+    // 菜单主题
+    theme: MenuThemeEnum.DARK,
+    // 分割菜单
+    split: false,
+    // 顶部菜单布局
+    topMenuAlign: 'start',
+    // 折叠触发器的位置
+    trigger: TriggerEnum.HEADER,
+    // 手风琴模式,只展示一个菜单
+    accordion: true,
+    // 在路由切换的时候关闭左侧混合菜单展开菜单
+    closeMixSidebarOnChange: false,
+    // 左侧混合菜单模块切换触发方式
+    mixSideTrigger: MixSidebarTriggerEnum.CLICK,
+    // 是否固定左侧混合菜单
+    mixSideFixed: false,
+  },
+  // 多标签
+  multiTabsSetting: {
+    // 刷新后是否保留已经打开的标签页
+    cache: false,
+    // 开启
+    show: true,
+    // 开启快速操作
+    showQuick: true,
+    // 是否可以拖拽
+    canDrag: true,
+    // 是否显示刷新按钮
+    showRedo: true,
+    // 是否显示折叠按钮
+    showFold: true,
+  },
+
+  // 动画配置
+  transitionSetting: {
+    //  是否开启切换动画
+    enable: true,
+    // 动画名
+    basicTransition: RouterTransitionEnum.FADE_SIDE,
+    // 是否打开页面切换loading
+    openPageLoading: true,
+    // 是否打开页面切换顶部进度条
+    openNProgress: false,
+  },
+
+  // 是否开启KeepAlive缓存  开发时候最好关闭,不然每次都需要清除缓存
+  openKeepAlive: true,
+  // 自动锁屏时间,为0不锁屏。 单位分钟 默认1个小时
+  lockTime: 0,
+  // 显示面包屑
+  showBreadCrumb: true,
+  // 显示面包屑图标
+  showBreadCrumbIcon: false,
+  // 是否使用全局错误捕获
+  useErrorHandle: false,
+  // 是否开启回到顶部
+  useOpenBackTop: true,
+  //  是否可以嵌入iframe页面
+  canEmbedIFramePage: true,
+  // 切换界面的时候是否删除未关闭的message及notify
+  closeMessageOnSwitch: true,
+  // 切换界面的时候是否取消已经发送但是未响应的http请求。
+  // 如果开启,想对单独接口覆盖。可以在单独接口设置
+  removeAllHttpPending: true,
+};
+

缓存配置

用于配置缓存内容加密信息,对缓存到浏览器的信息进行 AES 加密

/@/settings/encryptionSetting.ts 内可以配置 localStoragesessionStorage 缓存信息

前提: 使用项目自带的缓存工具类 /@/utils/cache 来进行缓存操作

import { isDevMode } from '/@/utils/env';
+
+// 缓存默认过期时间
+export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
+
+// 开启缓存加密后,加密密钥。采用aes加密
+export const cacheCipher = {
+  key: '_11111000001111@',
+  iv: '@11111000001111_',
+};
+
+// 是否加密缓存,默认生产环境加密
+export const enableStorageEncryption = !isDevMode();
+

多语言配置

用于配置多语言信息

src/settings/localeSetting.ts 内配置

export const LOCALE: { [key: string]: LocaleType } = {
+  ZH_CN: 'zh_CN',
+  EN_US: 'en',
+};
+
+export const localeSetting: LocaleSetting = {
+  // 是否显示语言选择器
+  showPicker: true,
+  // 当前语言
+  locale: LOCALE.ZH_CN,
+  // 默认语言
+  fallback: LOCALE.ZH_CN,
+  // 允许的语言
+  availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US],
+};
+
+// 语言列表
+export const localeList: DropMenu[] = [
+  {
+    text: '简体中文',
+    event: LOCALE.ZH_CN,
+  },
+  {
+    text: 'English',
+    event: LOCALE.EN_US,
+  },
+];
+

主题色配置

默认全局主题色配置位于 build/config/glob/themeConfig.ts

只需要修改 primaryColor 为您需要的配色,然后重新执行 yarn serve 即可

/**
+ * less global variable
+ */
+export const primaryColor = '#0960bd';
+

样式配置

css 前缀设置

用于修改项目内组件 class 的统一前缀

export const prefixCls = 'vben';
+
@namespace: vben;
+

前缀使用

在 css 内

<style lang="less" scoped>
+  /* namespace已经全局注入,不需要额外再引入 */
+  @prefix-cls: ~'@{namespace}-app-logo';
+
+  .@{prefix-cls} {
+    width: 100%;
+  }
+</style>
+

在 vue/ts 内

import { useDesign } from '/@/hooks/web/useDesign';
+
+const { prefixCls } = useDesign('app-logo');
+
+// prefixCls => vben-app-logo
+

颜色配置

用于预设一些颜色数组

src/settings/designSetting.ts 内配置

//  app主题色预设
+export const APP_PRESET_COLOR_LIST: string[] = [
+  '#0960bd',
+  '#0084f4',
+  '#009688',
+  '#536dfe',
+  '#ff5c93',
+  '#ee4f12',
+  '#0096c7',
+  '#9c27b0',
+  '#ff9800',
+];
+
+// 顶部背景色预设
+export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
+  '#ffffff',
+  '#009688',
+  '#5172DC',
+  '#1E9FFF',
+  '#018ffb',
+  '#409eff',
+  '#4e73df',
+  '#e74c3c',
+  '#24292e',
+  '#394664',
+  '#001529',
+  '#383f45',
+];
+
+// 左侧菜单背景色预设
+export const SIDE_BAR_BG_COLOR_LIST: string[] = [
+  '#001529',
+  '#273352',
+  '#ffffff',
+  '#191b24',
+  '#191a23',
+  '#304156',
+  '#001628',
+  '#28333E',
+  '#344058',
+  '#383f45',
+];
+

组件默认参数配置

src/settings/componentSetting.ts 内配置

// 用于配置某些组件的常规配置,而无需修改组件
+import type { SorterResult } from '../components/Table';
+
+export default {
+  // 表格配置
+  table: {
+    // 表格接口请求通用配置,可在组件prop覆盖
+    // 支持 xxx.xxx.xxx格式
+    fetchSetting: {
+      // 传给后台的当前页字段
+      pageField: 'page',
+      // 传给后台的每页显示多少条的字段
+      sizeField: 'pageSize',
+      // 接口返回表格数据的字段
+      listField: 'items',
+      // 接口返回表格总数的字段
+      totalField: 'total',
+    },
+    // 可选的分页选项
+    pageSizeOptions: ['10', '50', '80', '100'],
+    //默认每页显示多少条
+    defaultPageSize: 10,
+    // 默认排序方法
+    defaultSortFn: (sortInfo: SorterResult) => {
+      const { field, order } = sortInfo;
+      return {
+        // 排序字段
+        field,
+        // 排序方式 asc/desc
+        order,
+      };
+    },
+    // 自定义过滤方法
+    defaultFilterFn: (data: Partial<Recordable<string[]>>) => {
+      return data;
+    },
+  },
+  // 滚动组件配置
+  scrollbar: {
+    // 是否使用原生滚动样式
+    // 开启后,菜单,弹窗,抽屉会使用原生滚动条组件
+    native: false,
+  },
+};
+
+ + + + \ No newline at end of file diff --git a/images/genIcon.png b/images/genIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..020b0a3b309355fd16895bcde7167417a007479c GIT binary patch literal 17473 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 U6^ttUNnsQdk`}Du*Y*E@06|TPH2?qr literal 0 HcmV?d00001 diff --git a/images/i18n.png b/images/i18n.png new file mode 100644 index 0000000000000000000000000000000000000000..5cf77fa3027dd4afe6bd858dab8c9eacaf03f482 GIT binary patch literal 97630 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 Kt}I_^J;4T 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 literal 0 HcmV?d00001 diff --git a/images/report.png b/images/report.png new file mode 100644 index 0000000000000000000000000000000000000000..e86860e96ac211af80a390c8f4575cfa70b01c19 GIT binary patch literal 473612 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

)Hih4z*JZT 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

(xGpltH8BRQuPP6Y@nEZoWC8 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:LKZ--RKrTP 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%0DxCkv)K`W@^?l)zLk%$0aOg%Fh6V-cQlwK57*asG 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 igX^UrGqHq)>AD-;(3?KAQr| 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

8O_zkiCBe>=H_AgQrKC7d zl5WrKFGr+lhf{~c-`ufHIbs+*S^hNl9#zz>brgVKUL{R5)g6K-7<)NO!GZOx2t6Cq zStKxZg`lStn;Q&4ue22dgaiLJu9c%FUF-*Be><3@sV*uNV0VEm4OXq?D5 z%5yFz&}vHZN+4+Qvl%tqUPIvNX(a*&21g(b855mQtAyXxa1Cpuha68R|7?lku@qt~rg_a)5Zn1*r@!fm(Fa{9nGEfIfL2Bwq^B7=QrW}OlP8Z*9d|hB1j9sC_1t)Rr(DX(ljj-D0CKBwls%bU0dRB!z7qb_NB z?Z+Gn+gCxY#8OAK94ld;(2oCFF%Ini_XKBp5lr%h579&V5ip(0(Z^}#o(a6 z(jJm0^ zSgI0tWwcAjE9w%**XQR(u#K6SHb8-zeiLnebDg3ijF8tOk0P4iI5WR7o2R{P^O}AT zc6()fE0ZfMie;tTe3Bk`uj6)(#*QZvAZvUIDYkprAuZD8bjvc~mTQPADjkLGzy%!wuXqYk}gr@5=yXQAJ0_|TZV{pLqQFeHmDmqDbh%=p82 zlS&3s`N1JmB}s;hExK~H18F$_=mlHBX1!D@H$AtTC+d(jG0{iAI22}(6D(Yyb@X%N z;SKJd#!6wBPB~x`Wg8Eq!dwIpp>-xuMJjK+?sS*Pw$`KT##Zh0AJk)M2?>JwC8s?AHL?_P!w2D#H{SM98@53DB#4 z{89-(rwkt9@_IbkOVP*J9nnKdw|nt8+eSm4SE=}U9V8mMpLf5syB0;Wu-lmHVK|<7 z7*8>(_H3A#!0dCHs!v%>Y@lGY!#U=PWd0&gFLo*08HxmDH!K=iu zKl64H8;OeRi@f=}Xc>rHLMg*GpYJg#p&%az8c!in0(m% zlcF%1u`VtIy$5x}P5CczW#CVs2A)KFxt;X&GS-6eC3{ZcG3)bhAN6`dJ5!1-#q0l( zVnz-Fbc)9Hc5mMVE9ms%EjCHCD(2_P-%(Sk!kxOW5N`y%ZU2MDL1u$44=GvrfBGj1 z{R}61)W`f+)BKg?Jw|*&KX^nB%VyV3A@_Q_&!c^xpTECFh5g`+@%$#q+aZ0wh(M6k z`o`@P!{K;L-?jcivIkHO@ahN}DV^OZk4on3{Z1Q$15%c8Y0uc4{?c;y069#rN0*tK zpZPa+OZ|~=7@TgGj4HqlQpw~po~c2^vDcz*vyxLCwEI>w;{CR zc&AbSJXnljht*~v4}XYpQ&v83C+}pFBrW?Va#1DhmiMv8@ofh(P3(XR ze*d8De^G$2wCz#!AhIbe}femQK)|U7MNdul$?RIci(FM7^Y@ zaN?tbJ=aK&V$C@?Dv*9KQP5hz`ix^*7>4~Q2=EYpixky-n{ccma4YE3X8Y8irF(mY zQH&|&7ytdLE8-x+y{{{v(c{^A_sP2Q@EZHsV*P{9=iL2Wg!Q5Drt#QSMm?|gsF@-h;fCpp(YK_w_B)&NiB_jXrCgqy<1j9vYX=no!?vb0Em z8A}6f+XR1y3sy&#g$RcgR zW&+K1(x@6g!5kyk8wZN8vz1pdFYfi&F~Uxtfd|ovRXSzj#QcL5S((+Rl43t_`V6(KfZ(tx z7)*-a^0ImQ2aEZ0w|&7BU_6xGK=!U=Q{`H;-He9dSPvL3*H5>VPiSQupVUB)&=OV(1 z!T#6>?)iy-(eK?4A8pob6+0UYiGKUlO~M6PsApmggS^tLuLvl)%^ATL#72&&hr+f( zo|{1V$!nX19p8wXd97KTs5G0o1v1E%_PJ}334JC{Y|MDp{-He8DeF@?$SHrg9ou9? znDTJ_ohi&fbrGL^gsqZNatj|uAojdP3=S3lNY7e7#P`WSP#yZT(PBT#RD^Y5gd2O z{dh4nqg+;%ra`+0*v2Gsw}Tp2FC{qhAo-rz3Tt141M$0 z5b(LIv&6g^pLBZ{M_x}15<4h495Y)0Q>eSNK!8_vD#Vu*#&a^+*C+Vi&4AZ&4>G9@ zW*>}(Yd!GPsNzRFOoEb*@uEZ#)9$wD?3|eoi+0P47nrZ{37lu&-iXEKY>WuZQRUv~ zM9d>I?d5iB+!D#Dwu`P3_>AexD#0Qk3Gxw9Vi1aghXoe&`0b>EvFOM%wf;ncoBV-C z*x(JXv@qO{Zig*a2hVcg=QM2eB_TqPV+lxZJZ1Ow@~CR&b%OjRKWB5z zen$%l?8QP^mljbGnJ?s>3RE`xvlt{v1OvMAf2~a@x>J3h;{#(TutXZVNH~Dq+|vUt z?C9r}TnVg_)ajB(#)+g-g2g@z zJj6M!-Ffz>l-~rChx%2jaFZW5c$Y&k9w8x{h;srH)SR|}?1sX|x7Z(q8^;c0Y0r!d zsd+T%3@gPa?h^;T=9ep`fq8(DVb?`w7z>e>5)=Pm-3h3q&hwyZPw}!{WqFud3pJff zsF(n?xP;?KzO4{JNeHum^5c$=9a=SRQG0k3aLjSY40aQtX(Slinw@XhwBis3%EZuw z9Zu7}n0P50vHPE27t!qvIH!w2a8zpF4S$Qu?;!x`QlQ+ znAl^PB80`KN=wp4T~i2N2*mwJ9HWU4pjr6ul>{U zNX64g2C&=jlT<}$(eM0^AGYl|ZS4u-aSh2C(xtn2xUH9kikWsQsem;-_w@4@ z(pplrwW6YsFxWza0V(|XF>g&#=_e=4bgAjj8W>_ZM}7#W1+lBadMfr~f^yhk0!=05 z!>_C}t2gEAmZyb?QJAyF72>lJh98JcyMEH+ip2FP70-Ly@)uMO{ZmoBFOoM3blZ-^ zBp7b{kO_SRT;3(D&vR`gPJI&Sh#}IUIpOYUH!bCTt#jT=(Dub0s%!^cZ+G)g|8%(W zHa(#z6jtcy(J~+TVJwPL|LuA|i%{r%Yrx;;zyZtGHIHuCm*?I&y&2*gKCtcok7A8Q zVK*^N*Q$7Js1lIZvbH!(UEl?Gu31APoNBqh{PRda$@ogR`o+6kEoD0tExfm+yWSr0 zN>*+t@^)o$t^H!+WG9L>0xYEA}1LFFmV*t#tfn_5jWZE6@Fp3dSX6Y>LYNnrxKjnd#=e zASIcW#?`8ElQEbIl+H1HXu_P9JYVX*-~b!IlmxI-1V<9YcHqF!YGqXIa%R+?@v&u@ ziV$1Qrw)Zu#McrK69`qTL40giKjjv6aAfpqo%w7se8~T5fFiz?-O$LX|6?o3>M#Ah zs2HR6mRCUuelEq$?66PK%JkfEAc|Mpxu&VZpgm@S&VC*3@DCH4UNeZNtMJKjR^&m| z(d^KhDRoqraC$W@%&NC!n$+#N)nKyG`i1rsgDGP`JF+d@q;<%o)Eu9haBx$A%3@54 zi^O)4OHO-Fdhf+M9y#s)4&;eqh%=tGI(>`-t>;o!>28~REd#v=2Li_5_)18H3tJ5| zCm3C7RvRTHSgV*U8JVZH*&igdmH23+Czug@G^Hj?#5=4kD@Kxu{=0P!ezcRPx1+T< zJ9|Ao+WGQG)>-tZ2zK^o^?|f%?XTtTSL@M{Nt&Ryaffpow>Ac7UlGLilsHmF35;Y3 zTS}~+y)_m)x%bx9DUe(=O%O|bw2#GN3FrQm%;SDJe%|~d;XPqf*MEw$MYmOw9{v*{ zQa{WRX}mG>u?mwN`k1wxoMzyTA|#%z9>H@L{`_vcW9CsE;+$^h#=sZx6y?pO9(& zGuwwN^3i-Mj@&PRDNgNW`-){N=+>86M8kY|H&qnRiGNkA3iTStu!EY;6?Slq}5)m}N z`-IUJnUL@nh-%y);eu~3npqx<2|~v878$|yI@XsxZPJj7D}t6GECQ7|nysKUA2d1J zUzeC9-#Afo(~g0{1~pPb@}HFiue2v5;obh-18v{ZIfHMVnk z?+@2ddG6EcxpN-%C+cIuk5qa|-@9fg-py{gcdIHXxxxHQW)a{nCK>nEXdfk}f&HSy zJjj20FD9(17Bg*OoADcDYA6+g-&ZrR6&I${JoP&u+f?o1A>s7sC&x!~(XzCwSv z>LNVnHa{+crdKaTu=O7(o_qv;DE11UIR7)0tqEOCFf3`2{hCtmvw{P=>k?BRm_$*R z_^1&~_W+jYHy0{s&1=5%i92VHl@JdhSXV#)JC7Q@hJQ>5KT{F7-i=_a{L*zaH3{Hy z-qcQr-?D)sg6bjqmETVmaL1|r_%i;ha||79bciM%If#yUZfdfl+&? zyGxgX%BAiOf012lB1f^!OaGin{3!CdLiX zLs4sIdhXS~yR^m#pz|SKwL}!{ehj=`D%^G;Fz=&5468Io8$y!v&6B5ob%s>@Nir%V zvMLAVUX(m|p?@}R zkNP*SQdPIQEXSvZak1{7h~i*F(@_=(JdrC}So`ELaw0*+2`Zm`KW zz;z^jY;ns5?}WQjK;VPIjdW0HLmuSwb=XpGH87uxNR+sN0pB5b1uwjTA*vq|Ty9Cv zExtzJ4%_Xl<>jAvQzTTMVa4JNAxIJjWe7%!KJtqRK*Ps`DJCRm;FQ7*Nc9~b{=0=hXs~5G7RED6z@Iw{6Rr$>TUE4+qnZtY;B(D>I>yK_E)<>i+?F%MbNdr7k?j) zQD2ueZ#OgpC!HZefv_8dccd`FsT2cxMi|-_z2!PqCeNVcJxn8jhCWipxTIQ<1=qct zQ(Cg0mi8w0H8|D1YGXnw2RY6L?*#Q}K>0aDWW7@IKxs%{Xd5t|Nrl_K!8gwpg;^Q> z1I=BBJ4zx-U-Q%BL;JZq*6$|*C&(fo3YqqTzC_;=!3k_K?lRV?2bf0Yi?Mp9^WiY= z$}JguQ`4X-5l#dItm-vTEABZrB}867{#z9R1=&~dD!PEnWFy$aXIt*A6ik6gD%eA$ zMVX4+nH-m6;g5GfJ)GzJx<=qL>l#E`iY-5em-v*XsWaeHDs?pe$PB`%r)s&|=g=*? z-;HcTx~d2%v-Me^0ftBM3zXcXwpl?RlEND3;rJ!o14!IT9Mi&>?wJIjk}kZ%rG*cP z+bX@7V+zB|UDFmw0tnThmb|a_Tquk2FoK^d%nJqUm4qvv~TOsET5b^^gz${r4*XKEfd;=C#Ot z+y9@?DV40?`R2-^pZmh=Q5lCAot3=s(ehjzdeILQYMaiU#|9gUVATxHe|DU57##7; z8&VB?aL!J^MN{=4KVl{Y;SZlRI5JXcsfi9PsDNmF5iygh75&3zI_TWc{UN=#^<8FK zhO8Gvi&oJ0MUuUIq0~38HYhsbYeUm>66Qzn@QMQ|Q zej$FW$%GWR031zFbkv)CaD{lbFZ4!{03{g$8Z=TOfIjxLnr1GW!TVpbA%~CPjK`m+ zs}B*WERpV=VTk}yYe=6>jr3yvi-|4r_6ln0tV2SyYfTyyCX%8orM54>@x z#I0UNBAc`J7; z72L`lwn6RaAb}{HFEy_Mde@~LE$3`Gv%2yb;rw&{^*57`K6*##&lajLMGX8dkf70C z@uywbdmO=Xy4Q)qhxrSV5f3g8eb#*`qt9q1kDz1xJ|*kC4_0h9OoL5m@C)3lf6Oq5 z^MXoMNH-ldx2IS7#!J^HA`s@MV}d;S+f25_>qTK~DReM&6@q~`U3HK2+p|8Fo_R~t zguwg7gDsm@ofj)BEg#h>;6_F;r>6=p|1y`spOKW@+{-QD0>^eFa;Uur&!JW}lLU^x zuY4To)tQqYSlh5P(E4jV5?+HiZ#XmCP+N)7;~#rlD+coFhsg#_lgh`q9IoPzre!7~OJj^;gxo*mj=A$ktIs%C&_|gv zwoU(dJRY&j_`p5f*`f-FV`FyB&5*h+O=W8JF}osq#2KKzmRDzcE>Iy3hl5r&o&O~n zF~D+z*NGk?+BQ&88>Z0K(@H*0_y*p8pvzR&<02ey9JqJXOByu-en$5~(>7wrs1pYo zid^OQsRmr4Zh|TlRsVm1cl$h;@mx6RErno&L+7f45GJUQfgI*!vs6R3O7X zj~~T+RN!u=7H@evN%hvr6A_(fRJPztwdnBSGkb@~Ws6rjDUG)WQ)_3d2v5p9V-y!8 z->*qG;Gw*y2!s+~embYEk*Dm2uIlh@^vS0o-6pr=kxMV|6^RWInEr90`q)^kHf#*v zuq%mNeE;T9cIC`mZF#BwNH>&{-pJ>HNy@WnNe0IA2P zy!jg)F6{eTy)Rce8X8Fp%z5-F6wEF2deP80+@LxQxKa~2QCoh##k*GH95okvBCPBA zNJf%AIM1h27e7=<)IcqXHsoJ@W^G}+WGU#k6L|^3z1evOmshOP#fPqEl?0pi;7R0sZ&T3;{FpzR+3!HglU7^Z-=~+|m@YD8#0YdkHMtH0@E}iqoo?d+ZzF(`IB7D(6W~Sz zfHA0ES2C}aUxR>&0jG`EcwhsbZLCCOoeFeHn1!aS6k+gbQdh$SmC#pqpNzuT6m~qs zLXTh3WhhAA3|a&E-r`DM8&q3idaSv{ zIxvuA`Vpg)8ncdi^08wLFZy@+t^;@@cVmpMr`q!ap5J^=CqGVdZI_@DDp>Cfg~(#q zZ7gE?-r#P`K#2xv{ukd2gbx4a zB9A4r-xNbM>eEB1#xX(eL#(^9(Uth7mAFUQP^~CY4$}B&b3#hr>>`q?sOLQ$y0C5; zYW#A8z8BpUH7(5v{V_%-f)IT}*k}(R3xNqctPOInXqe}U-K|_Hw!YiZ`6CyQLm6iX z16{Cw7;dQ7d`}k`P0g&Zng9NM@1c)t#a*No2H6s!o8&}nzTx?io#NN-?8Fu{qUM4U zUx;U(BVVF{w^7HPsznfcygHBHVq@IqVj0CvY7;JIb8g}g=BSf~EfjnIK3{iXnOVyD z=kc>L)u;@kn5469Nf~ry_^rUBeR_mN-)?FG^)9eL9v9Brj(Rr?FRubVyvXFGkBY4b zsq(5T{Jl2oAlwxQ{1onezQ#PeeD#5QgqBR2DcA1-?e*n^W%F^n=LoIP=}U9eLaoPG zO9ei?M|t)(rP}@E7g=18UNXrHqlN!vtFA9?tsDU?5nZ72Db0GLoCB--!`leqi!5K&d!aNZs;0_^7( z`@7jrGnj#F#5<@B3u?4e$Yuwy9(Os zyKa(NqsulQAxxmS_>L2*S^T>pODEiNArqrE{25p))KkYHWE!qwyKt+9MLB1z&_2V#6lU2LWBTRlr-3}Z%NyMJ z;w#X5Z+L)zHG|BLBl5|bE)ESBWb=NyG!OgR6Fh>tHGt-Jf!)`=75%oGGAg4a|G16 z;aK8aABkA<_pbI@fU*iltw1YyMcnrd@ZvrAK&XiLjY;+OilOq2{UY%YD12e^_~fhb zFl$yt{F~>!`GYB zgd(J)rj7_)m0yr#Lz^B(L0?uJ%PyNCbp3!|8`Bq$m)vWHM?s3eBRrAenjU-%eZSu! zwr>R$N8@frFuHdKgev1d{1NT9h6z}C1aD5@bmELkt^z(;2-Yz~1*^wqhSdLKE(38r z(1S}=_&e30-c-ow-R_c4M#gL;`7qzjed>37t8XY(~QXe|b^UsVLG6FJFEpbN_uY~A(@ zEA&lgD)xW z)Vk*}p-~;?=#rI1)%Nb)I=WwMDE~2K!Jm`F*9;*IX@A6o+nR>P1ndHjZWwJY3fY%m zZpT4UxpHTYp;ya#G+j2@rBB8Xq))0>=~0({HP-s^E2|} z>S{3-dk$&SxkhdbUYx9nW!Mm)9gmXHvu5dLlU+17?C)vH-@C3=V>pV^&E5TNQJ|&>*k9)04dw;o zpx-p6Mj>%axUXo@8_{HYU%=g+8V1so+qJ7R1@NdE(vR8QVOtcPRqPWM^p0BsD{{Np zWpHk>lYAphP7;xV!7tbUhFsR(-3lo?)H1U?-KS&=h~n#>#A*7rQl+mg$MiA(3QxrxN0hSFrX%R0dr&68slx*LgdR z(pDI845Lhv@%kH?9|SZR(320^luw_rB|ZA>?n=*X6lJfZUh>_@9313%v!dZMI*rd_ zhm9C&L2zrPBg2TWWQyCf@A1p5d&Y;l^qViM=~sQq=)P&OQou+niu(lxZ@*bNA7uph z)DGHPRkc0>1EK47!kqGId<^CL9T#eb1hKE$Zr|}7e$5Soseq~>Qxq`5g}t_lqjns- zi;IgRySe-$@$l!dN>zT>)YHEykFjUtYyp(_7=rZYx^l;exrnk6OT?%l&Wv{zc#o%7 zjS%t%%2mM6hJdF!KQ4oib_ZFn>_#SI;;SM)_FF+mjr}Q4f0^q%!G5R|Y>qUNs`Irm zJ=t=<%`#Jdz1}OCYG-x5Kps=B?RW3VTqjkDjwz}w3`PL6p9mTJ^EW*D5|?VQv5(UR zSDh9ugKuCMrf4Uwj&7qB!0+|HSo$1Va6k1N2zKks|DZ}0<$t&2!o=Of9?!dxFfTU< zzmPl@N=_~QiOib8b{SS*IQcq>#4a-qW`=D3n|qH@k%8RXA78Sr47^MCe<$rq^2>2F zl)&KCl+6?Wm&eX$I&SoXXC8ewJkAE*1!#=Zd4t~8b@Qh7QE;^7Z<^Xfpt|3xp803A(uh|9l z(b`eaF~(iU4W!6MI?@p7XT)UMQY;$73gHdw*5wZo(CW^n-M;Is|?8Cw*!^jh{5N9^)dActr=v{VA5|ONh z0rn?qwbWLEC=t45I8dq_kJVF;E^RC~a(Z6rNwqj4{)E@D$}`>GsI$_FMxv1!v5H7N zQCJPRKDg~(?NkU@=o$YYeHm~hcbU8TXZib0xznL@&rZNN=hTn-31RIHZ+vmH&IwCc zfadpT&{dn=v^*j0FBwU=78uwri?Fc%fox=ZdD|H3^H$)lzenI_@qc?Oj^TTQ0=6vp zO!#7d4ULb+TxemF2_3+j>oFS#w-t?30b5DOg|0O@=DsF#t{a?!uP|MTg;yLg$ zbK3e_KBnL{QS9+uG3^6!XF;o*v75Kd_95uLnBUI}bcV0eIhDvCQt_-Ojr_#|-#8FU zcOQo_N{klw^{zCPV|3ux!3cabrmG4 z4REx*x*jWDr4r76aeuawEN{1HaK7B?&2y+M5mdhUqTI(x@wn$Gn(Q}KgG!t&bC@vj zvNuaUKZ)YCoJbJf7c(A^<&^tsQQwSRg5!ji^1&KC@2y2h(#*_iVq#y?M;{I9W40)aXh@?9qEc?69 z$i&&fdox0&NEY+)j(?V8+QYG&l zcJ6c+1=l0wPfUKY*__I2t8H$WCZ{mnx;;!R?EhmV{phf7+#MA}|8sJm6ky)v^qOv= z5EZx*-&5|7V9glakh}7aL!ugGH%{#JS6@>43IZ{Q$u&2v9m)2bl3WC3i8V}cDyHWb zT7Evobfmv&U~{iT7NAlcsyU$!^n;+IV25u){ZrWted_2veU7MftFtv~Gg!-n6s0zf z+K*Ri_UcvhPGk%NG?CQBHhpC=P}d33T0|jUX?7GT9V!Giro{<)tUHqEf4P#f$7pwp zgp&MRycFAk$Abn;utF!g9YiQjhFBf_LM{sSd96)_!~?k7Et^$EQV*ghBXb@Uup7Ma z#z({@ZmTh&3+G^;?SF7X?%0N3!oY7}P!Jb39xuDW^(*Wj-E0OoyhY45V0M6&ozJq6 z?L;>pIkmE#PUgnQ8fqQhMaemA)#7ac##Nl#KBsmRrP}nSff$x1B7H_w0^ha+d~6iE z4aojDJWjtWxZGXX(!?*{NUWto=tkJm_g4?lZS}^F#@?qT!brfN1UKw3i05O;ZFICh zPL+kM3UYxKSGYvwMtLV#1#ajGTU4RD{QccRW;E5$3gs3mw0(@C6OB65N(oIo0(A9# zNnGy6tN2s0m1c|4EZ_&ao4ke`O;MufnRGQ7W zd}yNclHiu__t;KJSZinHJ_eStn@$f=6eEOjGW(j&hM_{eM|3`0l=2s(JsB5K|G5RYj;6$i!n*qt5VQ_N8Q8#KfCsjOysr8p|JMqVEny zvJ*Mq6pn!DJ&%-jr%5xPbF^F86ysqH+@mc+DoNdX!1XEPmlsmuc zQCH7e+a^WI9kVciwqWQd%`rg@u7@%-T73dg?~_N05nbQ>k9}%bV4>cJf(GhbOyn#93780T*+?Q-4(rVQBr0b`pDwD-C?yd1QH}=Ce4?7c z(XbhXMBwF%S~f}L2)wo>LCa)O2AT<%Kg=`#Qh_SMO_{~)XrxkBH651f8HXVarRYm| z!TQ9H@L=9SJoLe>(y0rsYdok{-oIy;LtiH9UDkW8aN%7hr5w)gPA6)Dk6eE#+s6y$ z6ZorPvel@gG?dT=%TjN^Z1+GxDkXtPg9XrA>pPewZau0d&?FXXYe;H#aE@QDp8I>n zc(mrKhn8zvfl7jv)+Xhe8wc~J?%GO`E>8BTx{UCn?D|8b*S*+(t8=%)f)9&_@pxmn z89`n=^cVJO%d}v9?9zi|5Qiw>t;cmg?Uhz(wrbx!)G1|rTBb0n;LRniaHx*kRofq< zv)Y6RQmV~P3Mz;fkyYr-!cx~5^9_qF!1`_WBSp~z$D6k-UGL8(I z4pNJEvs#bB{v^hHr7V7rJB?#dSZsoteZArtcQ+NH#Sq@k0yiAMb`-1*zgMmSOYod&&v*-+t@?zKl}5!#OjM56)0}l)-_tV*-I1-J5Rzqe(ZLdt!=Y_ z*_#h{;N5{w$?Vpq9%Z~tMW9_Gg4ekNe<^pgZXt35b?V;=`Ms6qz}e*>=0f^BpeoJ7 z!!D;Q62L69lu?641u{|DumNaWBp)K2Z$A>i=1scJKGADTt`nZ^ zd$We;L(O?pwV-{jz`x8RQ)rehC&^0EBu_rR)VZvOOV^mskjVK%QT6N>;FT=MrkB6y z=l#7Rtz5Z`K*OIpDn>zAq%?XC_WknqJE-egUObL5g?%$m{}xa!OxZ04*VUp|U0KP| z_Gt-O4A1!4@T02oCNy!zyq_qUJ`d#LnM=c%?n*nqfw3@2|KAZjii|F5RQ z5$z5C6SE)F8X$R3vt%nav^q(DTc+yz!O2Q)M{&A9EgffC_0xg`PX9)0RbJn4!AqW} z*ODyA`BErz#X(CVA+_VFt_h0z1APtCs=7sdCT)f0JvAr+j8Sz62*C%u=P7q2_yHGf z1cc8}eMFh^JxrXZ6%F`Hy+cL-V>J34wDOLkvFcD72-W621-=B@GSS|!HayVQxV~7P zky``xCW8bvp8NZT)W+>n<>c8iJHLCK)5V0>q-E4bvSNAo%e9>E;Tl)Ze-U4?2Gl7< zt3p>V_{6~8(;5;qT4mhXrrd}-jn%mVAlR`M#{t&`&$+f1BtAC_XUeElm)wQW;xBAmATX)jZbys0dL#RPn=EFN*rF-wwL z8K5VVyhUT1J-A{ChJJ9zu5=HSH-9Yxi2#Qy0ynWEJpf`)FjkeM5?UHF!BewAs85m? z*sfvE<1XL+`pP~MI3DKV6O|`}_$()~{@OhA=~aamk4nuAjqX8c;7O%aVqtOxfoFq^ zmk!C9X0V0gKQ0fuXbfOTiow&BUXhua+l}}e9GXagPNWhsIal)TzSYBL}?|H~5Q|E>4=jDiJ#r)17oul)>F8N`m zQo4&(I!7#1B7?{^VofG}{F;a%_p^(kgT1|d|H%X;3wvj*7NzeO`8gu|@Xiq-Vm1B+ zRW;lg@~BBT5|}qd{E(r`cB0seO&wqLb6D(Epq{3J*bdyE&o_ey< z1-utUw~qu}DTNHwgNR7g8p#Z)WWWwX2jh}>{f0U(6jw3&=)aHP?2u)$X(irM^F<#) zH9nP)khUy+F@CQkSO;|cb`LG<|0AsSqf0=h+lu6^8I zi_SLx$J1K{MA?Pi-zWkCL)QS(-3%=y-7O`}&@Iv-ox{)}C5_VErNj)~DP7X35=#B= z=Y8MrJDH<7xM%Ji*R}UrzqLnu_RPSh<7OEpdbbC>YEkRX*89Dd%xli8#_P^Ffu)1a z`TYay5@upS1tlImSvacH3iwrMVkI@Xfbx>`7Cooc3mLvRFd-*j_yWcA&VX6nj@A}J z-)*-vlF~W2a50p1Knfa)53lvPUBPgK_YX{TdRhLN(DBZiH zRRWzKm_rO2IIOJsradD(`bJoss`(9-_?X9L=z4eE9YS0hq)2_*hW1Pjn9UeS`(XlE zP8%CTutB-}^oI|g`fzX&jVFR15D*XU8ztdeM4&&%I1QQR>e2jD4Aj%oR0aijcq7PRZbgVCmL%?t^wy_4h)6)i^-u$X%?^{w1 zC>xmt$z)sBQy9tR{qLf8NwgtS1gbW&lKaG`GK)quzxfMy zy?VB|IOX(~YACnS0Mnz>!U#+!P-)L;sNh4kUg4KkX0g&C;;(~191>MVjqy@0s8gys zqHfcn%K1O|-OQ3r*5p%$?0eK0ZBl^s41mG@<|pixdAf;kh>?Zc<;6j=Vx%iax!_>V zZYoUQOlpJRuO?euvEY(8l1)$~m|N5U*le5LQqkYX{Ul`(zLG&Xh+$DMRUEKL@G)-U zaIAtZ%Pt-~wYCm8EnL^3k%S#j5TclPTW zAKbYLbC9C=o?lk{Q!dRe*MS!Z-ruTVm*pOhOP?jY_Z;ZjU_j4VJz8CzMPQoW%N9Il$L@a zB4lQ>!V?m=vbOuXgFzXw`RFU`xAy$+;!QYzVAS=!zxQ*h%!Vy7C3 zVRIQUBjRxPu8zYipb!t8PN_F8Q>Ng9) zbn0g?o%sDZZ{5n}3a9RTkJ z53zcigQj^;dcXjM2Ay}7@?-6l*sAYNX^^nyVKf4lrK=mC#cCkOAaG+(MHJij@|)QJ zrssf4uhnYWq+5P(C7$dnM8Z$Vl0`1d+E4_IcK``0_?M_-JxbARxAu+TcDVCA*WD3> zkkX$B!uSqg7&uZoIIPduGO2%lIY?q&sf6GaJ0q`nnaz|^4*1A=sd%?54$ZBRtQgR) z@W4y=O7KO8mAgR6ERa7o_4mDT(+GhqBmBczoU~JU3YqI2y55z!UrH5XlZ+tT25;k1 z8plxWXlnLJjUFk_g#{_Fcr{$EM*(?!$MUCzN`IjOi;vx~qdsPu%8Ahh7r#qk+i(YF znAgS;c6HUJtVPy1+tI8c%lMK(ft3tZD8U4dxk6mc%JlS0A_~@<8r@~dku2S%A3POO zXoAH6=e6|2UK=yYx93Lh4Cjl2^DoGi>-;XcCho8>ltR=ooacI(16J<@u9~x2x80&< zVLsJ>oa0c8z%3SKi{g{t8(+#U^$LS>5PY$YL0tUYuS5%`FR-d;{Lzkvd<;kCT$*sH z%Ups)`$E`3Z^$jLqD|4S-!n|I&)xMJeflUi7X9koi<_jFm&rxY5MI}#bGPr$%>0h7 zg8ZX+-@*QpQbX|JX>QSAVL{=OY2Fyb7c9OK^tcG)s~lTe4Sq$v3h+vFOfMO|=8{5# zp6fs+9Z|{iLE=gYI-d}&;3PkDlOq0Xdr<`{tA?RiHOqjwGVw`y z3sv~OAMPWfa?I^3@Gawy<&?pX#jwdDl2VKJ>P%3zpJ(fZA0fM}-TTeIuxON2rK4OZ zn7+fn8Me%t19jS@w$C4qCKvhNWcLt1J|~~E@lG0l5Yq+E;Q|6-KJ?>_){7d5a-~j4!H|R&D{DfHLm~g92AgnFvJop9st%L==WS&zF!UQt70d z2rJB_txQNhYxScD1OHS<)+zqttc;PC#3x6!B|x3nDk9egAgPb7QNUUKY=#1ldgTie z)W|AU!D$mXR!}2(v*4Z$cdOtvnQpJS=&k(_!v07G8m-#&(oi9?kK!GDqh2lyvbEN2 zQ>5DgD`Zyjz#%Px(VXZ!s&|ld^lJsnB?H-4Rqk|dg_~2; zuk&M)ZwY?2xLzZ`@}Q;`KO!A8|2B)$>dDlI4syI-?uXz+MB)B716BpBze=-ZuT13F ze>CCKji>nNeS+0@n|M07_p?)1)DhK;M1c9nblF~Wd8Fm@4iPr(cNUWsld#1AT6Il8 zln^ceNK0*`Ks)05<$4L=J}^f$bT_7+qHFAD3-U3H{Z=)a=5!!g7oK-vZy5jiTD*9Z zD(^VBx@JuF!6ynR232hd1QvxBRR^hYW|){HYHGiQx{!|J;OM?oYw&QA?H>ZyHSxCR zTXxC!p@_J5_;`3EFK7kA>Q6t82M7qW^p`T%AI(LRF#kba(pHVPL$6>aVQ~49CXL~) zESQ^W>2tGg8U3RZex55KD~lXiYHC9IF_oe*eMpUil2MR8I>*FLs)*1jl|$xiHYHf$GkVnz%Zh@RWsp z^So9ZB`5|8%X#ZD#P_U*37zskfUKi;rUKk+0&++UcniYju_R|$;xhZY({L>LZYYU5 z>ol#WvsE$;7MfJApQiIv;rbz$%iT}}Kfk+Icz&qR=Og9N@5mS@wX7SzyX)G@4&zb5 zj3DRvA>wV`Ne4wfI&_sU@yl6?t}UWJvWA7dWXXg+twcnaZqEbV9xwBEuofS)Q_8%u zv~fv9qTgV8lV2=kun_v4uN=(Eu8T1IYKR!}fUsZ2v$fun=}MR{zcEYzKg-DmhD$>Y zYkC6O%oHvTSV-nl>L2)v#F;vTvn#>|uC`W{ID_UCfnjb~{ATBD{lh;QT9HYS5NSBMb!33Szg4Ek&9h-Tcq-oyIHTnlr(Y5z0*_Egwv$VB z3R<890wS0E@^~zkG0klNA`G{}&u@^Q8Bbvq`>L9~#nrkM@(2b6KV8sO;s!@+QJOZG zxd!?jSqokIHvo8$$!$Ojr|5prFv>7=M9Fk6@E%?RhaD=D2&DkQPeyzSxIY_ux5!mX z-TS>6yO~(~g*aK18_U>B(G&IMU)opNr6!VygPosDY$76pJ+CKiEA!Qfu-%+2J72Jr zSfZAQl|y~C4BJz4x6X5j2SnJ43kA^@h3x>$0N@Ey5a}@Figsl2sJ3fugOi%$@b=h|6AC!|2-t{9|H!|M zkWUP`=!NM+GPOfftCGui6(`E^AysgQTN*FyO*W-{?o7$rf&&_M#}?0r@sLqbrW$%( zxYxqC9vl{AHF6q!Jt5FiK@Z!B9l;R3hrTia3|1)>%?eySnKAWcdK@*eLJNY9#qP1H z$0^|EGgV^YxwHbPmPrh@ev=HMNGiOjKI%)`fPK{*`cKqk`|aRIAAkQzvGZ$5wl2v7 ziJPAG##}MCytc8)r`)U)Jo}Zu)0P%1?9g1k+zm@lwLhyh1ME>_8gG5lX5=77Vk-4r z?Q)=FhfsPwL=rpZP0O7m8zcU^VgTBCZ(Lokv$c+91@UB+J~A<}iqKFi3#$-z44q)S z2tm@EI#bP8D>}6+r(D#Fc-mJ}@K(yE|JzIbGJwu9)SIKeO{J-^jKpWKDNGYj`8dS5 z+*<}F;2R^fr00rscOfCNR)v9AI0jyR(&sDSN=r>YK3sptiClP{HR?R}_$>W05f_z% zV_-?vrivsH9F24C3;s+f(aP~7K?jh4{7cYb-|Z~1l}}5_ro&a$^PXMqzalKRNHIu% zGC<(lvvHI5zeN48qK`(%jK3@uek5esQu|9mb=ZgBnb+CgYiu@#VQ+;?@9;Sjma0Ir z4%j=qM#RBImK{kRDa-0y((2NxW=REz`$;V5ZO0neB!~DC30*@$tHt5qxAFtv0nlH# z`#{XYBI}BFMWCHpmQAqK%EW(Cla_*FuhyU#4Uv;$JAJ892AIgo0hSU;b(?>r20gYjoNS8jRDU97P4kq3#z;Nr~4=cV=hycin z7R>+s;!v?T#L|mOihwtM#|@Cb7`n(eqL%hdkGSsjk~Yy`V=V;O03epAATqxnKI~=h ze7!0`MDW7ZAAYG*E#hlMEMtnwt#PNNe9ImL(`|#h3jt=|?rgW$;L+-P@f0$ZtShAt zKZaa}4^lp>7!UVnT-k`txIye|^A^c}Zg(OZk+uc`q4Z3ZOj3Fr>v2a-jxF zEZOhMUfV0z&?EoqHYrhHl<3nfU;K)7Vbq?eK_hpH06gSUBHNH)7LwULgqUm*IcsBx z`?j7XS`?`hM#{_B2VVNzlIuKY1@WeI=ZspKuo{T6r3pC6eMfFIzjPPSQ1w*9iI{@@ zg;i9eLs|?uflm7P?Wj z*E74TI8(QeqNBoQ|L5|V{~UWXCR`gL>E>d}^Y#|DAdkV9>U=jD6mW^Vc$qF|Jg?X8 z>wjKSHdVJ(gAfxRBwI!g{Jb<@t^K!)#B{VcJDltf^T#JT3Drd+h>F`=WwLwc_Y*GG z+|E>p`-d}4dL-XFRfNE*F2Ev;!R2K>JQM@Yyd4I+7{4E!0f7Riedp_DUB3S`gE97o zbm8M|#dAw(kP76w=6Z*-+W)LH+`Us3O)|*|qIwyN34>HKDoRK zHQwvA%Aj7bHA@~{3%`xgt{;{mIt3qhE3!sdaN&nD2hvrK;kZ8^-g+{5i%p9h5f$EX zLnYhKJD#1*UDG}q6(##&9x8$qg@U#awh4&M;QYa`_}=_3uXoh92{;@(-#Aoxn6=IU zon%el>3j8~&PcpmetKbFclvOS0%G%Xi85eak=6(j5 z6sQ$f(~ZY+=8d0WpUADd!CL38#8{Is^S{9DRT>(a24p*V>P4UY#KWIE_MQU#oi2Z} z9+!li`p0nIOvV9+%+%4J)RasEne2DU59@}r#s=No?7}=$;DgVRBkRnq{tq3)AoKs6FVP(x8CAk(b zAf{rI@y<3YUU@}S4-`wF5sw&JsntUXk7dss{dY*=pmjxxDffDcJ<5B^=Ga0UW~S0y zo4J{g;*C2Lmz5NQNf0rIU}o;}q55&SzM}($Wacz1ngyJ)_^=+R9zo@U3{$?I${%GN z7zY!L^*H9&6D$eciM~A^Q;pZlKCL#g?BLtLW=>>7()G{c#J2v*Ik-=W4=7wm^c2XrVHbW8oRB-ac^c}AzwBSQ7%y}p&GchgMwMp(MP0P zFDe5&J42O#j^(Z`|E}O!e5n6m`*GY_;7>dG8V9On;3Y&S=uPe%UwM3fA_Y{9iV?oY zd;{jSib~vi?8g12HW^rls0jUgb{Og<1q+afXfyZkEZDr|+s$1Migt_#-{6-(zdg@&QhRz7 zJI|%85&KPPe>h)7Liuq(3%*6b@D{=cFsQ~xUP4+<4%gLm^gtgERwJOK3cV#sXP=jA z(!(*!<8nApz+v?X%ZS`zX>2!WVVdZtRRy(!Z)u_(k=3@%Z@1gQ?xL?v`Yiw#9+em` zlLj82odMZsy%k)5;C3X6HwKsNin1P&qj&r9euEb=D%E z7e07@b)YH^fnAQ?(=r5ZbGrMu+ZPRUC>6tvp&3)}_n#`MKMnwn(!KC|zBb}d^c7~;MdL3Oj2if68=7196f7~FcT)Hh6h zu6Sa`Pd7~J!}5B`5G`dr=QXY8W+B2_%^`wZe3QbCas-4?prqO%lyNUV^C!~>FlsmV zpuKj?DQl_b4v`njCFsoXR4Xb(dn`fc+NQbBu`N=^U$&IZpP75sCi@GXD#3zk=cueC z1$BvpiT6USiOa`dD0+!w>@26wn0@cHp+&(tLBz`~ts$^_|8Qd=HlxnDI}zpwp1)57 z-}>4Ex=%J&XC+QGxZ*0RKQB$lYdQ7Obz@U}9t^wNYD-J-rKtxKePdw^lyp(>AqquP zdD(d^<+Ga_0*)@YSDd6b#})M0oO?hmmaxv!JzJ3|gu=Z!kut5z{b<8mK`$xlHahpz z^<$p>ecqDvmtr@RkpdEf_bbLda`&w+d?!1E?3N!pbmQ#n`d^EQA|D2nHpjU80LH&bkL!15FYP&^@)`g zR+DR}@+45HjUBGH#ls*2*nar#$&^Xi`)gj>3dK@(OfLQw1Q)0(llAF8BLR84Kghlv z^{NNct5#RT?ssj`D>bFJicM)n=tH?6t#4yIaaHr*USYBH0Q5rFf}GaT4A_W101P1o zu;Tt5!k@j0CPAMfb-GBP2l%^2l^ncVrAJ=L4s=vY%PPU+ zSBAH9D|c;!F}9B6a*1uQXQ829lmG+M&nOR8*o0-vSX;;-jksL{gybor3TB@4cn2XF z09%|GswOXhjvszp;=6SSsJBe%JHOQZr0W-Kd*82y>f-9Yd-*;sK@@uXgl|(1NbG>E zj)AvQeN`YRpR%US;rz=OBDFk)2Ehm2E%A5c~nR<+*6Zd~J|H(HG2DFM(IB}S2O z=4isbLmb8ka5dG%$*B8+#W8b!oO_!-1SrN4GLSFC_&72Z$JH@~5Al@>=#-4rYvZeL zB+g`|lON3*DMq?#R5D74-q22SLB3z|ZwZ`0zSTP#ZyZ)-1<-c{pZ8g` zbO6n02?)CBdCujJaA1yrI=}CgB9?=PP*Xq*o7o8zJF8 zvLh43Z2qq-aVa7}i568M@}Z@ZfWH}?)@aEycrMLd>G3I{HhWJcpyQ@)9~zPKi4+3H z+=`5H5Nz~H6STX4B%}C!Y!=^f2=%yGyrlIoSs}wml~@m9`Ji--j@N*-0Py%~rI!X#*E4>ieml?h>gB&x`?b+L)pAw8;6{ ziq2#}MpGxVeYh?}j2cs@max79=-m8e*_fFDn*@3aIG9vd@0n+TvO*;_1z}ZBFI*3j z@*^^j^fgw6U<$?R)LJ&Ws>P9mF1*A8Qb!B3B$A9}ejp-BS@`5ts#)hBJ6}_C^-kgn+1wn^Psg5akS#dd2w|DB7rUSmx z_->YP1$?g2yxGGlH&;TRwCL9T9ajV$An30on^xY?WTZu(woJ#?|J}O4)#DS4=_dCx z{clWt!+Nz@)4|~2!!($q+-8axT4H<|L+6=1KxnkuhNu8nalau!Z7l=8<5aK(rqK^T zi22#K`z!p2au1arnfR0jl`rm`_BZ>PZ|66&w1Z4RLg5^b0OK`=?(TKaT3iA}sC*>_)lx#<*rUug}a2(zF1msAGkQeSLt?%Fiv#!J8> zfMiNdY1M-d0?@vZO#blgiPhd@6AwKiTjO~%mhr4_427c)B~n1Nxc35c0_A10*zyp8 zD5-3SB2~AYP_@nc{FUIECYG?S|I3+wdvq%f3dTa;6`7cU+})km=w z)-ZNx##R^h>@M0B@}H{d$2N`6>{d!$EVpU!86pe{9wJAMlkj4mkzVL|zJ7Zj z12((y)zG+!f=NHVuVHx(aM2YnRacT6r-!pc=`n^rZL=ef!B~W0Nq{QRgHym3E7vSE z@xLhCzt|nE32jP}YsOEI3#@I$x;aC5Z>K(*{DGfXeDhatuGY9R##*!&9ASW?FXe1$ zg^88Jhq80+`k&AA3X$DS;7;Ym@^NkOD~1A8{nd{*qib8~Jfwd%)~?pA5 z6I&B|@B;D)FIGR+(FK7r&#y!{!o>=CjGzkF>>Pgh_+8fxi;y zkk)kA-0_ZidqPFKXIX-NdQ^r0{nOC!6`FhTUghxk$2M zpOXkSQ$0KYcBfyHXo@{bRhz@>#vs6LlQ}?Ph?_wg2LYcxynj~?ZY!oLZ7_rb?FMIK zGCg|lmVi%?ZW|_cA*+6%=qu>=Z=UE^!3oP1JQ3mBh*=^%VZjAd-`q${ZEbzk@-pYf zVqGbCH=e!m^!&e4U?5X>e+ukq?eLszn@w0J>f>dP(jhK+WV(sK{H~!Tka?i-#ywHl zN84?5OsL(+J9FvNsKmGrUK{Rma~vP`gS!^z zwfirf`5NSu)S&}d2-=F?8I>``>r0>7cb0crjEeIhLE23H47 zxCAGe#DjjY*|#g=%Xg-W2S&$DBEeDSdZ$)yatOt8UJkiC26JsJ+U_at8q#3;~42-#dWF_1#MJVGR&O2N|O7XIE7ya{HC zsW0)d_-hbJARB?bfl(Kxcpnvb#7JW9V`^C42(HR4!`^?ID}8moI<~#n$Hs|-GPS^>llaMV1F+Z^rr!ObWw zgX@RKQ{+VT_0-nJ_fbZicyQug5DXt~sS65`e|e!G zB=_!*z`tPoHlEXa=>e&pH7;+#-)--)Xv1!f>;Pm)%(LGyp*Mjo?YLfYaE5dG(yabS$!e0I0zrR`)5Z}=PPD5M2 zt@o(u!Z}I*r?sl`jG@a}n8CW`!42QqOA&8yE^lz9hn%3{5WY1_j0xf%a3eIC^p{ z8GETGYhj#k*Gw!MAFLMrBx1d$AG+?zKyRK%f{ub#Cz2P?y3zw>cUa6IgO(4m3HtQ5B~I`78{-0j}7%G97}alV-oGh|$- zn`xBh%_v?(9+5Hxmi02(_Nt`CcD6(9-Jf^P6ecTeNQo;fpvb^NY4M zwBMEqdGo#T%PVZ%)DTxi1!YwB@E@#^PHghH{{D&mK92&Ih?nf>htIoECZs~utuZOq z<6|HNWQ_A&VT3`h`Wx-woO2!$Z567XuZB|X0man#sP$LEg@Khh1-fu?bI@mN8%bR` zwqj@rnBi475HOIEJ-EEG_)5vjU0J6lxb&fzN!q9EV`=xt)IPZNx*~R$u$<*}=3E&! zr`$l9ACH6o{uL7%3By%*^HOx9Xw|Xy7Ezsa7&zxW5yZ?G#dnFq0!7vk$t&JVSv9vB z#zKJlZioFEm8)dbR}=gR3yp-7wrbgOG0Dut;WBJEH?H@ih7>3f*N0b>OKJ1MED>X) z;3f0YZI+YgTX90q$*()tLg=MA*OD-J5Hbx1i?<9~g3loTVr7k>zb$}>VhCr*mx>`aE3F^A zJF~T)t_2D5eR}v&sVH{iB>i7L4AQ-I&Iko{t((NEL{x+7J{NKpZ46?*}DCTcqeYU7FMXax(RQXKuBSIDg$G$ zrA^~{-w^8ViBjB9u8kzllTc$FWi@AJHeaOW2DTmx4Fu zXnq{k%sdf#F_6izb5sMp?Ciq`#If&ZK>xs*NsAO?^#a6-$h(w2*%z<^C~%Mt<=jPQ z*M=-zWk~GwwdtmXMW1k)I*N>;U|MQ$S3<3gR7ZmXXVyA@hSYcXob=YV3`wPxJm612 z@93-szlh;FC|8eDTWu3hkduc`O!a^Tc9MG2YV59#-IY_}^8}?joV{WQim?(3An~TT z2}S@~2VzE1L~o@BO}GG*4+j7woFpqAo9)ggKV4>i{Hk%Y?z3NJB^O6}8f>R{TD7}c z++_#}?oosf|IX*prOtXo^SJ)$@D1e0-#sRuiD1je-=8e$3Putn$*h#VzybcD7`LN#(<)x3C|Tqa0PJo>QxcpFdxpBNhlm;>jjj@w) zD^JSPpBDd1IiD6iKBm`J8={qWTquKewN7SbNOmtQ;%Lf(8E#ox=W}#W?9}1!Haq?^bw9?EsehY>B+fd~#Btv!YG6{rXxRVaI!~~O#c`|6oV~FM16iYMbIS1ZFBlSzB{{N@Ff1kR;sAM*-eg^v9;|p2 zkZcu38!EDC$xPwPA|6upF8gsJ%`w^e+=T~3MXYDZEkeY!itrcjPVi$RkPf=^w-vu0iP8q7skS%0>P;!b8{=?-tBLijL?QWhb9TTN-*7-!0%&pvSk{C zRbtIicq+hhk*{BbbmCRD&vFeu{e5$1nP$f2t)Mh@D28LB9`b zS=BadTA@V`j)V>C;*nyvU+6S_c(*49T8IGy%p_L5lAj=v;C?M@GWar@G8z(nN8j?f zlyc$-6F*^$QMi6rh@=;f31HO6Yw5_{;J8L)#wL0ak4b*r+5FjymGizbjwqaqr^)2! zXUzx|-pw<>EI)^Y&Z`(MWM6jG`J}Pt6#b33rPL7887|W4eqxHtG2@)s*Jts z@@GAp4Hz^-?dkN*%@Zq}sa1aopqJ3Al-UrUOI+54&u65O=MGuXF^ZIi zTdWfY3Vw9Gr~;Pw;oln4DL+rOPMLP1AU>IA*Z^2poS0CInlv5-3WzPQl#A64PTL|0 zK10kaIe2Ok?R(Dp-2zl88#2Lg!(d<1(h7~67DX#oAS=P;)HwN^HK5KXmaZnX4Qka_-DTGWZ!Xbo+ThjihWDvCXk0#@jq`5hkKaZyrcAcombDtb{0@C3m zrQzYsV0(bEIPM_J&5<^hO#(1jGq$B|a|wd@2!oTrQ+cMistra6eU z6)`7bKU+@^6wq_orPrt=ySDAM9s6Fg=@3BZz z=)d&fQ*rJWKZ9HZwe~!2gNPvO^1~iUZ2^m(&qQ@n!sAtQyr5B6IITpo?~p2NmRM*M zzyk&6lT?B!XfiLEp>@;G(Xm%n&mCzo1}levdBobFCpGVir3a%6}fTNha>*?nk;-C2NNa4xa$#(EUd2YMA{x~i%P1h{Xs0xW9JRmBK}15WO| zHp^`cjmDVXWJ{)^$kyRff^g(VJy28xm%*>kz>6#aA_#_M3{iVlv1M!&Qs&pNm+=RZ zaP&-;U$NwE?YV5r)fdgY*zx@t_bflo#u!iHPmVgEZgz6pc+Xnx z>T=idqnMCnr_JWnSP184Qk_AI3W0&S&32QD0z3EX=lZs1Id*xywaj&_0H7rEWCB?& zarDz_dPf^0y`Sy>&VzeE68!q}e|=Q1y!*36WY9{AZ#BT!dLK=c_}6)gvQ#vJRqcp1 zIQbbpGM$`VL60sfmKDe%`JeG@R8_POP2vNpBqcGjSJr_LnXoN)=Fu5_-BX#h#8gja zikN4jKbSLJGg^5){!(C)l#p7PO<+fn^W}1>9Y_$J>LZdIQ=D3zshU~}prFo?X$t-G zYV}9eG!ktX_P$~oVOP>@cQXvqC>R=AE(M=RgH0=w;bfm+1DvD0`nd|Qpbz@M_oK47 z`L5Yx9hMloJLrpmE`0d)JyO1pk`rIF&I^Y60s_`i`D^1uF*QJ&^)p#ZsGGMl^Hof8 zR7bENlvpuMbb|M1JDzUhp~NEFIi&dgH#6_K6|Ty`lkW!b z?d#Z)M2EKMX%)BwtoM4v|M%}5Ri&^a@eARBBn*rsx|jyu>}%treneldXx8}sQNgonN}6C$x3?c8YxUY`cqJS*~3KGw4j*RQ5*7n@5P63q6|^ERTS(M zlTG(hFI!sbKEV^o017w)M|%_1ho&#t&$2I?VP$4r-+o%g@O<+ zudh)2y=SUz>PIX!22!z-x zAj-bErz)cV^L7i5L;KhE1ms@*GcU70O%x(kI4WkoM=xKQA|5 zRvas_GVonwAihxM5B>kzF9N*?21-dR+&P925YTIA`*h@JN#4qrW@4p878wwTuDe6Oq6u8$NAhcrto3vPjxV95&Qw)AD;M-FFCgK z$ha@^kR=&EyCvcsm>$uTcGz~#QJBc zmag4Hw*-2V!W;v!ZMs)sp=R0o;#;H(VgyK6aDBBbTnuFR;&aJyGsQr|BZ=rK4SWCt8=#DtQ zYG=NL=EYe~;E-WWE1th2>32@sCVSA0%8EpH5A}%qtFEDWLVi`92X@?$`a9<{+ZiE( zM=0OFfG-a#UibVO)Te!H{MqT&x+Z65R2)sbEg&E!WTw{~^9>)`+g(-D_5dCocI3Zt zkdkrZx?=H1;b+myc?xsL>aC2j_qyh51{eKc4^+`4{VE9V@|WJ{Xw(^8O@9hUV3zXtGg zltVXXdcb3F9)%Wr+G4elP1q`9XmwPSA1aybKgzHCp9QQP_C_v%`Apol3;6T7f1Xtb z{1IpNrX?Z?=Wm=uyiBbBrCsIo@QRDJmypB0`m#BD(cBz)e1(Sm@y@pK8BCwnWFE!BF4I7jUF(+@!*dq4LK@Ysb`3V=uU7XX=vsfUrgOa2 zO+WO2sL-JUOaipKwM6Hupp7DEUBvFb%;s{P|J4y*&RSG!3c>=L<13W4hqpXa!Yrj7 z({k5nBO>7iFR3^L&##X(P+{O@Fd4$*f49zmoOhn*DtAz&BADd_LTgz6_Z1pjI^rcz zvX%3Wa;I@s4)NGkf``Tx%HiQNK#pRW{QPvlwFwAd%Tt9Dl>QO!GGX?08q#@Yw~|IN zRVzt5Ub;%>`8BVAV5sYBBx(j@x%-TjMt5Df*F>}f9+x8*PzP&ho6hIQP4mpz`|cedp&0$9XDz>|BQ;7-jY$MiE}VIR57PvB!XQ@t{h|zmqtq; z*#dcV_+WL|W1+r$j;xkX(Fc;d6e=`r4SDchlgZ{fHfY?~hMuh}Da3xS)}o!~-|M#N zmDKXJyn5CsG7jgjOR9vvkGhNnIW<>O~%{BuMZwdU~3a*9M~e{luVf z*$xz>=5Sz#k*_3O`TC&;NC$iej9o+44_-o27XXIYH)$uXQ1N;(7s8h6&KUdE@AkA% z=LU^2G%go7o<@yjEoFv%Qao!1Z^zLoo*%AB?D4NeSPPn8p!0JI8tiqFx zg^v$T);RG*?-u(1KNzwhI<}t5Gr8cdJ!s{g4 z_B7Juah!MTQJ|sB8nc0h82FTCb?$+n?wfX*YPP0cQqsRKIqDEH@{T38RZ=A7(Fv@j zTvw5kCU!cyKx1?zGtODeZp-xcwKy4s&>R*5_Q8fqbrgg$m%u}sRJYJ^{iWuNXjC0V z`j=;Xbre#>q3_8l2#V*4X?pVUV3 z#RZt4tmhzb0IUhPHl8wiLr^Mm7Ev|ZO=4Om`v8YQ82iZp18y~eJr4#pN>|f}?B%nVenpl90Re6(m<|wW>cgU-4^>%Y z+~cf{31-?7f$KUouxFkJp8Vf2Ey6XYb@%%dKHe-hG`apCQEwgA^!NUc z6EbR))aZuMj1UBro^&^;FuGH^W8gLf5s;3s&*YCQX z|8Cbg_c?c*J06c#isw!p6z6l%#037O4u8sxwDM=HG-Ex5Nh8WLqW$!0xcJPoXiPO;V5G+;e1A& zA!L1&0XNTZH7aTOo9j;M)dXl3HMcSL5=Agjm~m*6m;SSA>{#@;`|)E-m*2T6ytW{6 z#RYqn7IEWJTVT-Mr#h`o6GgnqW|i@p0dj6h1qt&r2}VEWXbqp}wZs@!Oj_%~d2>*x zKWEP%>EA<%eg~5n*X#XzsvkDUNsqP@fd{7Z>12ugsImEtOEWPKgJq~NxZ#g}UK&75 ze^qj*O{FEg;^VzCOw>Y9N{9uHqYC^r7SY!L(kA7FTGF6}S&@ANnr}<`LPX%s89&K4 z%UWus-@&>$8S39#E!1Cwxc4ausC9@+WLs_w1YXC@!Q0??@!iN+ihx(9z{e2Q5d`F?)TL z7>9{_OU3@p_o%{(e*Iq(hyn|1(?8u9dLvNus7QkzodSa(oHK+@;8VKOl)qAcOQTH_ z^tmTUwV3uJI%E?IC&*ng;xOLl49KNJQL~GnqX+b5yNicjlG-QFkD{u-z3$YJ*N9wx z-+U|A&oC>$UGKey4nsA5ofrJ-9QZ6e$hg{V`R`Xt;PiX~&A>N05{AVX0&&Y;J8bd# zO;AQ3(5*CCC7-&KxRHd4z0m`J8#`dWRS9i>ncN^Xa@Q1M)I4#`h$B89@oGqJfL)$` zPWf*8>-J(@v7ukTrXKz935uJkyi7|7`q6PHeXMd!5l#2J>$@wovW>VLe}PVb77bJX zW;~@^l9|@(v7MOL#_S-=_b9Ajh)gw0%2Nco5#(bIxw&rv>9hof9SDG7y#t|d_vw1n zF-`qz3qX-I7QqXy8yYZN_2x`HMpNz~ zz5Ao8JsgX<8nN-hPwS`CR?)^xgEd-HRD1M>F>k$^rAZ+GLrNEA(w+9<=A!djcWTJR zBf-&WYIrmKV~OMv7ne>^Z`ZUkK2sF*5Thvs{qLM6+9#H~KvfPIW8fM6e&u2gV}X#z z5^7o=GHBCm4@74^ea;_i1g7}q@xk&_@YA~*Q+@_DDeXk>^Izc*5g--@F$`xa-)`p6 z2k2cF8byX-^hnNfeBk z*gnrL6m24v59T&v4WokN;=7Q|M3a#qBTJptprg9DbC{-4NJ%(k9t4S?AK*{^$r!Jj z^nJCNq8e1<>;FvP{uI|s-dI-io0Bl;=QWh^Uv`xnl~}G4mdgwY)6rxsYpX1hM-~#CVUvw4hi0 zbpxvhKMc5k=RcHgvBC)>>~P%0J6=F3bSWy>g9%0WUbP((HI+ogE;+gDZn)Y zM_W6D{l;o){Zn%GGeXTuh!8+q1WhLp_qB9A^M?uftrnt9g7EuxtmqF~{ppCfI&;-GoIuV z>*%wNP_tp2VTR)aAcZ7600tX%jIv;$IFzhUGYfaPrL*%5ATOyQFvhz>udQ9x26r>1 zR8slcgu>>Rkwz()nCkQrIztJ!+ByRkBv;b*ker$j)Mi^luo4H{%{boId|%eA3=&`0 zYn&wgQNMbAyMt zunqS_LyX!RblWf3(0$wI-R_^KId>gGMJ{gn%uug|U?L-Tbfg1jJnXO-L2e;HO+CU- zqq-90lFyWa(R^8!E?`g?K^ZaYeeOMAFoZHb*zB*a9N0UF{CV{V%z(CIx4nzeB+=BO zALzi<%dHpP|2zYJ$Zm`chfL4oFj~;{h**E4Cm#W0$ZE_WGr<; z4lHrWCjwXK9|Jm%pJzpqUBYTOk{j$~_;ET|gXfSYdOk}kVK`h3vS=zp(2RpOwT&VF zxi?SBgXwq6NEIy)9mkAPrBQV3eA7FkXST4(4>YOEzaA^e75>&z2VuqSB?}m2Rf#dVu&ixsm0yJS;IKmV|JfV zvsX;@eA4j!9Bh>GA-zL{=r0PJ#kNS2H`iGC=Zd>oqi#7*vw5({qW#x71q+O1ur|!l zZa2&KU)S>Fm7ulYQp@7ihDRd_I0Ed++`kzTWJ=j9^0pZAr-qbVI2IHX5#KNz52h$W z>KQP&P3+bCiU2Z6>@}^)&vTqx1&2U6ZEya5FSxL3zZqES=($g!_LfQFPE81Is)f-k zR17`M3bg!YhHAk|YHQpjr^-?E)7Bj?XdetR@G0fwCO?0QOPHJ~R)fG9M#BlslLyOm zjbp9h0Z_r#Q6T^iynXqwHh=1MjbC+&k z#Btfnh~7bGRx0^Zq1KP{owP??AH|PukEN&`I(rcGt#%~{kTCI!72&ToGP72i7!s(_ zaYEDUUZ0L$A;7ZgmEKNYbEwR8&vr5@P=%NdITfBc7Z)c}6U;m~7w>EUhj{YLKf2&J zKKaaUhZ3pvh(Trhja&DTf4?*sglT5N{&(IrFTCLYE!r3h#O+q>SWJtvVb1H8S;M=9 z#KDlzZ{^?3cVXCQfLNvpM1(}5wxk|GgR}YX!BlkJVdAWZk=H2VJsx}6z>|}JKoL86yX!WO)+2A zie1P8)J zR|+4H@@6*F7}u)GuH9>f*&gW3YsL+UMbJ2?*!Nn-7=s`|WUvi$HIQsQqYF^aIvhJ9 zesn)N)a?=d`n5Ivdd3@NOj=d0kx(TFXO#_>5tJTPh^coOMv`b#g#k6wjN;AvE^BMy z5N;!Or~JZq4()%B8YbSo#1#Abtk=MBRvKs<(i;Bn_eDLz{>Z)U>lB6*c}o*1_TePe zJA?9IU0@O>Rgw@~DmE@9J&mZThGOggP1muQK|Us_>sv|#B)-ffpUm`<=^h=7HsD8& z#w(o`5SwAXP~oYcdXXzUUxZWKxotD;HSFECCpS=VBt{ziB%IyEiw~PJR79J~=`PsN z2)yzgflF36m;%js^R*^a0Mxif@S6vjD!^B09ae_p z6D%yKU)kft5>0%U{Olmgj*MMV^P@-4>-@g}DrLw_y|8YvEF6OK&8jclc4F5 zIcEN_(hRcf`hs39nnMEy;dJ1o=Ly9HXO~4rufS5>U8$SaQUyY{$1jS~* z)}>aG4mYp|gQHo^_FpOv2*J&xR0YdX*@!i2hnxXKXKJN|zozeTy=3${$AjcH(!l@k!PCIBGRz{tlo)xI*<=__OT6Phc1b($4@(Y?oHyV*Z0m`Nq)m{^#Il?|^5f z<5Y)GvX_{-hv4}2rKIb|t{It8vfP_|ra{B7G$BjdnLR!uv5l; zHuR&_Eu*4>30DJ;WiE~*R1bcU+l9hu?rYy(*@NXdm5GO0yaY_;wkC26Y7;b_AbND| zGZA>vM+PD2*is?zR+^agYw<8esL)6|-!T4Garen$ zsm^NtSB>qySSgB#C(nK}=lD1Cu^U4cd%&Mzc5x1npRM60@{1u*!RMdbj8C|6q}#SH zU7IgFBMN@ZKMx@Nbgpk*vd|Tai@yNn!X|nCamTA`s@b13QgP?sm12fE5nzL9zQ2$>M*1*6p*3Wpd#(`98P%>Ah81hk{5py>D#2R?q>+_^1 zQ$q&!Y;rI&V9IAO0TYIxaqp1XFN78ZahR(Nf3Y+4R0DW!jyHdh?jt;SSA7C7YU(17?|VP{3!!g_UwB zuY$M(<%iDM1mjvBBe{`A+8RJ(NbXC}N&yNNjVq!vJoIy}pEp&O;e__D2d3IpJ}QUK zs9t9(uUc*w!gl^JfsAIgA&f+ywY6HkTtw3JEOitjrr^dL5Zl*f%}^{j6(oG!m^8Tv zL6lXog}PYr2Su+M{CgslIn1>aX;Hbzo5%3avQlxOBf!oZ}vD>63`hW zSu94N0ZAdh6+hq-C=q{!%)rh#W4DR`MY{IV!-}-|e^lYK*H`q>%GsL&HR;4)14=2R zE(RMnTB(0P{#IlX{CeqnPhIB_6_l7s4Dippo`f$t=y3voMjVfEx<30! zM4*aGuC=NoUwfrgduHazA7C=v1k>FWzA3Szr2Bg`45_TwcNBELSFc{9z8$ zmhO_rhsL9=va|Bbn{#W0kmJ?9h4sY;5Qg~LY;H7N=2<1kb4O`$(Go`_pvf@R8a~pa zt;J-HS>5fIZw-Iz-jD2NL~olwD)3>NOlaYb%wlon{tHmDN-3a{Oaa{>*!-p}$%hhz z)-`uJ8!5|t}Rq~U9_xir0SH0bcOxg zt$L|iM?Js?%rwGLAoj%*Q$^W&(*gUKDL%vKzBy;O_aI^`Q9{^Z{z}l-Yy~=0h?F+2 z=CgjVY#PYNnD`JN{8A&zXn$32KgSG6 zA6v4j8kgkH7sOi)s$Nd*r3qHcSkpBrTGt2e6MF9t@?sQImP;3H9 z=Jhbx;m`GYqf~IMx1|_%he-$uo;#Y3f zsrr0Z0JSBTXaFrsGG~JZ4VlX05HyN7;}z-$ajiobWi)_>n9Aj~Fs?8WcouZG3gr7w zr811E96`!d4tf>{6)ZyFKcNu&L)3)@T5h)^SI*{nmz-VBpR2ha4j^G45`0trD1Paqs$+?3^o{ zu}zMgJ%4f(UuP6dgyjr~iM2J`);t zhu@rlR9YiW5gzZmh+t2GrSR$x%LAo+_ens}s*V?w#&8wXGt@*Ed3=DZMtHs7j2;Ci z^dSIwgnm>p^n5Y$-oO9>1n%(?^aRI7)JY-)#ToMWt>Kxr92~W(2JXrTD+n<-XzZB+ zQ~0veAWQOYUW*};+Lva)ldRvHbmy?+f5wbBWygxb@c4hl0t`892Sa?l)P0Y6-?hv3 zxbJHuf^76U>qCEuRAy5jZ}MQz?UIovi;q2M;x)*jK+h52y`2@!ZY{K_1;(zh5ofsD zG)rC&tO1{u*V%5o@PD=@)^W$K9f#;M=Wm4`m*{=S+GL$s6h_wK+zdU)UGALU)sATp z7{X}Hew98O#}~uO8^elkP?K1QZ-W=AydbBlz%~f>>8Yz*N_Gji`U1lG>J_K-auUMY zNXxT@+R}#N^#@8(fr_x{t|f(ybTXVZInHl0lw=+U^OYu;IAvI$^o)Tqd{&r>c20xm zleM^soUqn#iyp7%I4I1)>FtHCHB(CrXMepA93QFnD}TBZ2?{A)4z`bC}g!ZK~&?#aA#@ui$XS`-GpiHBc=ejuyxtn0me zJR8s;p84GDKIdWuCzOfWsC6*Y4kbsoE^!ezQa$zDTSC?-F$+>fG7!3IhZ={X$evA) zg6Z*i{^!8O?R)t=r6COH?Fq2c$ndxc#5&ukiXUZKo&p2l=ALtKMIIJ;w_2R*wlu*M z|1^U1l5^g}wH82PsAjtl=Z{C8&53`*QCdm06W>#|U-_Lw6F(HU2^{oaz;~{k=fwS- z{Be{k-ebw0tsce!qgOY? zZ#Dqer$q%@97{F=C`|{Oj)E#v8v4;N6t$@w5hWYCktUu=4Tpg2EB=4iH{rpb(G!Xl zq|u)$P)nLg`s^zN=Hi2tc5M@DiSbC4C9rDnfboT-_Ku_J*~lo<3kOL4O2i`}K(9U0 zND>4o5w4v2%ejwZ*d8I#A? zz~s20LgJ2+oQazVj-sRR^SRHhH1-if8o;(l*U8IdF5I(|fso<-x?0Sm%hrRQB^zPR8>fXU2gqQ`H&x7PS#tuN(u&6Z zaf=>Z;=5?C{IsAw@qlN8A(HJbv8O7cIOn2TgMJHFrZj~7@&YV?An&##|4hjdB)yt> zmla+syV3>fH{#>1{ks*D&ND^3*e5!W2;}%)mukMLhXKZ;EW~UI*g$f=W zELR=Bt$f`8(kO=&Z=;MO{<0^!E-W@Fq$OmUC(|XI%o9s(!KV z1=z?WWD=iZQ$NcsQ~5ls#!|B{4*s?B>u;RfS#ja#U!^1-S{8vonkx&!>ABu$sS|Sn5AyP@u3Go_oGy({1WQH?#<>ScYqbS}Mdr z$U~75ylBy7ftF;ba@i8aBWu%jdC}99Ysc!I8+w>kpiw%XtH{$shwrW7;y>(% zt;kCyhB4LxnWEmqoE@{c#3#)5#bQ*+ORNy!`q=0`a?K9DiJ+~_rc}tp`43{MW!Oa1 zTdnwEQYJGLOcg3<;5Ov5Rd6!Zl*olQLB!`!VU)8)kn3cSjIm4A5nSj38Ds3222@aN zMjt3T;G8sUR}Z>Tsgwcxg;i`wzvTH^@h9~*zg%|wdlh0BW zPO?}(?tK;Hz_I_*svR{^#m=HDhc(yDi_CLj8APTth))CCtKQ(6bct}-Z)w8m6*OPb#6oLiCbQB^2wFtpkXm8b#*77yCXizXhUpjH`N|&#+m3;X5H6pOa23)PE$eyj=Kw8X0IdC z({Mf5D~Bn#w2N1HrLoiGL_|pn4l&b&$NVSNak1Z0?0aiR+y#hj#{qK*RA$m~Qpa6a z{J}xTpMToay0#X3Gn@59mckwow(R-H*=6&oFf7fFgCey? zmI>lnEK3M)pmF&jL(D#Fhry7&j~>(H5*Gs4Lp4Gy{NV@i|9|y=(}Be!?_hL$%ZFo$ zw)ClJNB_$%X%>_4ui8Q1Gx}2Un>klMlTX{O?s%W`TL{6^(0{r>f4+o6ep;f&Thg~% zXEQ#&E{64*RDi_DQAH1r z{x%KK1KTMYmf`Uv5{YA1m%&vghjFtoh|QmfhVZE-X9=X(6cHNgVG6t;ortg>=_M@E zHJDWej+;&=+o_Af<%s6&uT~}-yeRJ>S|7-`$lEdj2NMc-WecwDwcn{3) z9PFGEpZ#lr-J~)Y2hX_oD+@La4lmq3kP3L6&q<+%g^eoj7PGUS2X#Ct7jbP<^8EPD zsXbr(G3$$nX@xGIm2UB~0~WA1g5QZ3D}%N7{zJ5k@33KuNw$HLnzjhw@h~QlsNxo% zbmdxS!j^7qNHD>GG^#))Bwd7=M zXuxb8O*}E84$7vUAEB0rX=;amre%=;Xls)OI&kYm@VkqOWRpwEqAb*+hO@eWp$_l6bDfM zmJd;MNjBolq87piEKnm)HeJ3S%*%E;LEtE*?rgDoiV)ESE5W&k9d{~hHm5Asm@kYl zoF=Mc@9!;+;S$6DStPYv@o)=TYYUo0#!b<{b!{(sp)Jrg@oebcq_n&Vq?RT_jjv4<(gOJs|Otn_Fg zpySaDtf|WT92ze`gOVtz`Y4!q>-Z6r`QdwgnW;$9{UYd{wZBD%F~}In)f)cobKVj% zwouWiifdLmjyq0D;A(0&0u&jc{r;;6{L!>W1E}1e7Y`WQ$6^V5ORYkO|Lh-XBcY=8 z*#6sJOB9{l_SE_KnY8<{j_;e|FWafH*c!+}p#+z_>6m_||v@8Mq>D=|C z0LRGc?~}y19ijiytrtN(wx#Vh|m0^#WDYd6%db6AtH2o#;`QV`c@{lI@v zj~6YYpl(hR|}Ln)mhiv-r3peyd$UB+d6wVu$7w;|R0XczkDw$Y4D_&G%PAKj|79C^-o$26-x` zdpB2Sck{t~B&yplhuwXp8Sf>vEGobtp7)SzQCfC44tIi50o_bbpH?qp)oXPgPz#w*iZt_x*_!?S)m82MY(y`oq2(KHqkeJc8AGUQzgy(6#5y= zMNw-Ph|$6Q*!PUwP}usP*;<>U93R3E3HHmMF?Voy4V+z=uNyMM2 zac2=|FXOc6q*97Kh{q2d>~g>bn1R`X1+vt=yP0_QY8uC{blqc!DQsGkU^m(M-?K5U zB@FS%a8-U`^Ybj^La*Vo>gZ~yKCQE4rMr@SJ7V~w$euG)CL zWc^p^xu`AV?VK2&6TS0ZWlN#m6;h$qD}4C2sKslcWu_4G6~7Z7X;i%!?)k(|^@5D$ znF!)1@7&AR!AMSWE~d+;GG_Zdfg3?4gMN$3t>He0&1*qNQBLBGpjmoYwsZ}~SF^+m zk7#8r3z$eR`?SG+%mY#*UP;bm=PSsy5m$2Il>a|laOTPf0q+yOmss_sL|chM5t!qp zN7kbFHY_ZE=U&b%E3ArI-pc-w=a6E>V`9U!8=b!#)NBMG1Z1$(lv?7JrcSFbyEkbYK`@u58B{h!|4ibbIRc3Z`BLl{gm9#$PwM6!yJ6sCV8d6 zu|8c5$I4$GyySu=&vA;tc~C( z>!%lz?iN;Iv@s;v^7vEL=Z?&(!ZG&Slk-`Nhiti|Gq5?rZ}+o=UeWKoc}3U<|g-~fx9!rR{|L=*@?nP{Hzm2`YAGAT4moe$z3`; zpvG~mep&n@i`=}pjKr*|9jFD!dKdj`_6iw@Np#Vphl8<7&;RWIc)s9(^;G#UG(4UnBt6be|eYeZHb&p{}=u^R|Olx%g+t6kT)C9s%0`od@AxY!Y(V`0tB|EuIUu6X@V27P3b&G4p*g?ZZ@Z#v0aE*Mp2 zS6iJUM7Kl-X$ZG5^p*Ia^5;wJ{b}PZ^-7w0&@xs@SUa@y(P=Ep`?_;`?5@n+8S9GV zix9_s?7=HJZ*hIy7qo1!xvDo07!Mn4>QNpi4P&j zmnLTpk$q;!)7~_2iBv`%cO>Ty8OsHZmppg*pChq4ud)CzNW*_oZfY0%i2@#It8iz$ zwn`{F)rQ)v~%Vd4PEZz6!B2KQQ9BtGSU6>xs;9_HqrZri^72AH@+Pwutu9rZw}owBeL0R=fU zPG;(f6%cAn0wZ|s+EouSOPVEPx1?d1WOe$@T;{5Kk|b6W0~&?3U1}KZH=Gy{(%B** zX4#Y?*x#5lrg+fdij7!ggJKAR6W+l2Yhlqve9a*;9ppg>QFe&1QdE2x8hK)4G(2=a zVE=lKe`j*u!dpZi%jmezPdPvXfSMFIeG@&xI@G*LF+SDNQwDHvxI7e_+fg372ghqgE_xH#*I%K#6};5Ks5k}w$`Wps!L zi{2{C6Np~<^t-^KCpvO#Jepsi==!m~pX14JBSy(@EjaL6HiihRY##G@jt&8tHTcvz z8~#}vc$t}1@_&0g_o=Q{@_r~1`^*x!h*ZgokVHbLjef-mi{NqB-LGJj40NFfK5A+y zZwAel(w4W)D{BF^U2_%JKwvf%v6NpkKO&A;=-XlQb z);I=Jrs?J!SG6K9ROZoCiT}!{xU`R(I8F5X{)9h@3!sJ)PEBIfnO^}QUnhXNqdcG7 zgD5|to&$w3pkD=QqwFbI0h&N%AU;zZU)`K$|B|1uef1Z8aT)*~v(%Ny3Kzi&O!12~x>@y~{sbQm*R!vGoWW@!V83TbtyOoEs6Mg-|Wb} z5=$9)Sh)V*M@b9UFZUzjmM@jHhghHaio!=8nj;}X@V1X-5M-azsx`82bD2!g?zgZ7 zF7wS&xBTtu9!C=@c8KVd8Yvn@RBPdnk8mME-?MPeHc&QH%2-xREO$GLQ!2Y5<9L*4 zjM98+gT!!x@h5VD{hsOt&?wohj#9hLm&T(o%kXa`h}WF=AlMJBR|v_WDQuzlbbo3s zB?QZ1LkaN~)+d@gHaXciv8w)#mrBFF!*xAvsD>&7Hay)l93^v1}~Jv?tWqZo;Fq7J+cJbRT9?P{224$cm`pqffe)axL;p1 zGoPoOfun){svvb(m_$)pMXzrXxsaV|$&-|4oX8Emza9|EEcige!RIkh^xn?;)8yFd z^W{IP$Nt{WKe@PjCh5s9Dt~HK1=eBk>a%y^Qd}rJN9WJA1#}CfMdOAFIk6>#-y@oS zzr}(4yzHVilMGRZWvg1EIlKbW#cm8)CUH#49!JD2h-flG%Q@@Ep|_W=H1 zqXjGm`}pCRJy~)U+JaOU+FIa>Nz(^k|8D8N1xxma{SYwo6Nm0kq*yE86Js_&eJB?$JD)qLiF zI~+&g;{#748Q!3Rj&qU+d>i91)KMzKEmPFA1ZvczVW-|cA@zCnAQk;rxM11(z%{`x#%C?Q4-^dSi_wR|0|^*GbgLShrJbI3n2`KOa%g)jxMpe03&?8}ri~DaK;~0iQb9sTZ87z|@jkMh% z)C1wYZZ{*#GYL@hduwXh$W^_NZ566GvG^ovQ)gNOp6Vp(fb8VrxYa&2%j1>`YHB(< z|B;`1w(670>eB3;VDDt%cI_Lh8!H+kbwi_*E$WZ^rGMS$#g9g03uGIyV~+2;4=tXW zJ-uB20IO-s`K)rTLh zAa5dAsFW6;$#S71An=933DT>V{gV^f_X6bKE=%}FIV3U5srPdg`>`H(2N}iq-3oZ~ zxYn?!(`lVeSf55D(|-L|rxB3F=hnGJ;^w$^XSN%1d))edINK(A{vGJu;!Vv#i{!;3 zkge;jwnY1N*`4&m@XtrT1UW9v-p*eH2^#o!9z~QTU~E}2^$P#2UeW4Uh6fjcu2&=o z50p(%SbF~lHNoumRq-qohDn=aqH9#q7XwP3ck-&n9gSqFw-(Yt<)9Q{;Z=^A%lio< z`XwJcQf`=SA?{l;NPMC;@`cr zzW2Y!4le!W`)DX=)JMwnjF&9Z9cYcj7utMVUos^2mIq#91zg3~S1x{&dQZ=Sz~hvQ zE*?zT-kvI}9cmzIm70rya<$fd$V)J@vSC^cG%5j6I?!(d1V8jktdFZh3azg9WEFT9 zpUDy-PBtzs-WAB){Y^@&>;hx27Hl@_*9I=mvktef1iJqnG*yo&AO(Um!duUaV4mxC zCaArQ9_#6kgrz5gC_d=deeD*ID!@bV~4 z$k67Z>>dY(PKoaNaI}OgF=rayOV8SnIwO6aZdsNu{HhkTQ zRUlSY%ZgvrHkl@(Y6OIAe?6s|>ttu&!%Fzx(^9fR5gQ(lJx$&C#-=~a=bANO^+bYh zfuBzc7>drABniCGGL-n#sFMtn)2H8hTF6F>X_X|ohayDWLHMWBxqUpI8YF1vwQ z=Vy^7%7!RqoM?gcA!s^kUWeyXoRQS7ZL_d_YTmB!H(xeNT%{peufrXBS$S_hl2s3V zJ{%P|_GWC45Ej|K_4|Qdky*zv*5nuhofu@?Qrdl+KP@VB>Fm}VWmT1f-YHy_fG`hD zWc3#nPBJ_W4^$xY;~WXbX&WNY>u!;Gv#k1v8c*^Cf6mfL_ZQaxe)f81kliDQ?R8ZK zL(#&v*k-D?zaY$i*$DAkaYr4N`7rI(E5Te%)h}>(M{Ly&CBThLRq7wOssN zr(IW?_->4Pc{*c4^&w*i`J=S$7B@uq!A5dD?`Px?jHDr^PfQy&{T}j)?UA!YsPxc% zhZl0I&7fGE+&~nj9uVebJ#~JZ*Yw{D&agJ#A$%CYc)Yz*T zi1xOMU%6VPYTYsbZkw1BLv61%GYi<7Qj9Ik$~v27HP~D@_3llWI3U(s=VK#-u)$fd z&LfSrUw>Nl|5_YAI#DtD*=YhynnI3wiejteMos?!^)F zGei(}1wVex#g*e6GrSg>+e^U~=Pj7}9V}T{&olD*;}*h2E7x5@u#e>-rb+jw9cZ7qtu{CfR+UfWHen~QFJ z{O8LLJtC=#a-GeLRwxHf2B)Orfi6bzx_2E;FPLlR!1OpZj=ha%?|Q;=leGH%O!Ji( zV8TH<=y*q)ZtYWoGnc)*G_-pwH3gyX3M_CmYxaz6QB# zZ@-p3!KmB4D4e-G(X!86qJ7T9BsfD36?WG1&RVYg`{QTl!(U_B+4C3fYJ%|h;*VQj zgsVW(FvpZ7M=1Fg642*l>;LIGE8gTM(9OaFf6%}eNlnHtUD>b=Vg8^jX)sG=#g8Qe zR+8vZi%DJ*lNH)aEP!u^su6SrdOB#6bNs~%OPA6rx zOCX^Y7MaEyI0n*tgs$ltQUazj`(+@#4TX2u+RpX9JhJMp?)Qoe4tx#Q^=fMjG2mE{J&Q68TBnX=S#Ju(dXNsLbYR3-Y_dYuozY&)bKgXe3 z{HfLdH0;K_yIZ;Tl}7uWze8_tkZaZb zTM7#GuCM+g_Kh_uD_r)aO*R3G2|+pN)!%fz{MLxi)6*9QxW->Jeb)DE*}plp-d~b5 zUe4$;I7GIv%ChfBW{MVp{q(`uJP+YpXNa8y=J+0f`u}V?F_A8Wd4~NVs$|68k(P-m zm&*z$2>&8UxXD&Ol@RP}S68n{Dp-*gaw(l7{~||OL_FPWBd%XBl$8A0J6=-zw_~3` z>SXDN2ZklG#7^UwG+uyhP1!PUZ6)1+FTwoa;JrV_iQSNfscMGx{>8<`^G3`yR#>0j zJm*Bmh+n!;i1I^z=wge(K^f@C%DU_U(umtF7lZfe)Bh79VO*gV3VgxN9yev^qIO9{ z(PTT^rKfwo7{aUc*?u<3tw!G!(iBa(YfZvskajPA_G$4@=}s=QpOfm9`l8My*{GW+ zLdo}i_;aEi*Au9qck>YWX^G2TS16k9y=Yn&b-5T4!Wm|SN)RoRjuI+tN-?Q>jO?c} zM5TJtntL&CjG({?9JKDUA||`IPY3As|LsWn!lOQ( z1^O>`zWToKeA1V_#@$(lGjy-08Z1bieUF2+TsDlv?uKOO`dqK*p>tZG_{W&Cnl{NX^&41kgf3GgL;++&Z;jUl%vdd2LnXACFk&>4Z{&5o_$8aOJS$!XG=@}P?lrga z;nQkAG1a3Q@pFDZE}wsQ@2Xd~p1= zqW3C+?|L(>{~uc4=3CM>Dal0&)GTom`Eg$8{gf<+&hK8aw*;&1nrJ5-ZoF&x$4hf% z$G88n{F%zjRQ59RZfu`)@+4cn8N2=s4yip~7*eD^Y!v8y>d`r4jo(r~N2diBKA6UQ z?tir`B!9U_zlWb^;*tq>UP}D%4vfMeea{`#~Nnd^2+}>k$3tnjiU^=y!Y;8 zF3Gqg`*vfuUvkK_Z9jX1Qaf9h>g}qyBolvjcUa^`o~}ez$)mn;yzh=ajql4nyjg6{ z(Fe(fVv0H|%~#y@x7e_e~Dw*q<(JbM2B<_JwU?3jGb&}y#O z-`4&&O?)cHq)Lv6gkHZ=QM&5e#8uuG4#X$FKUm*6v;CdcZNc3&1&PzRvpuhwxXhGM zk(m}N#IUx=*2G!9?%BH6=~Y{$<&Ac>c$&qw?tiq!?;DSOPG)B29IKYni#w|Mm^0R| zTj%#P^fvEXS?~98v9-BpCy6i9*}G-i*JHPCX>YTBHFs8{k{75dB4 zelKa;EVkHXch1Gd?)`GLOMXQpT)FUXduF-*vJ=x|7iy=@^~<=fa4D53Hni{B?#v9k zd1v?SKc(?+_qAgW7V&nAo^jY6BJpD5^uP08%YS=!gC#+tZBfF*vwIw;eG$pp6KQ3> zj){w-WcyL)rvJ%F3=9mto;(Z;4j`5(Vb+3zB%9o_i;N5nw|({}9RX^()%E4bjcg#p zckSG1z)NoT2Qe^QxYQFY5e_o4M%|Esp`jb3P;0UTkO^XCO_KPqExw%v$mD7MwY{#h wn=^xvfuReCO*GjU7#08(I!p#>r(CGOBskF1Q?GL!&`bsfPgg&ebxsLQ08V(Exc~qF literal 0 HcmV?d00001 diff --git a/images/selectIconSet.png b/images/selectIconSet.png new file mode 100644 index 0000000000000000000000000000000000000000..d5835604bc93912d4b82a9803d0ad92a37315ad6 GIT binary patch literal 29413 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

Vben Admin

一个开箱即用的前端框架

💡 最新技术栈

基于Vue3、Vite、TypeScript等最新技术栈开发

⚡️ 轻量快速的热重载

无论应用程序大小如何,都始终极快的模块热重载(HMR)

🛠️ 丰富的示例

常见的Web端插件示例实现

📦 组件封装

对日常使用频率较高的组件二次封装,满足基础工作需求

🔩 主题配置

丰富的主题配置及黑暗主题适配

🔑 权限管理

完善的前后端权限管理方案

MIT Licensed | Copyright © 2021-present Vben

+ + + + \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..cd4c33d8b71f31d32aaed9fefe14f237b81e764f GIT binary patch literal 4042 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 literal 0 HcmV?d00001 diff --git a/other/donate.html b/other/donate.html new file mode 100644 index 00000000..ff3026f2 --- /dev/null +++ b/other/donate.html @@ -0,0 +1,31 @@ + + + + + + 赞助 | Vben Admin + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/other/doubt.html b/other/doubt.html new file mode 100644 index 00000000..0f73ff05 --- /dev/null +++ b/other/doubt.html @@ -0,0 +1,53 @@ + + + + + + 常见疑点说明 | Vben Admin + + + + + + + + + + + + + + + + +

常见疑点说明

该分类主要说明一些地方为什么这样做,以及原因是什么

项目别名

/@/vite 内配置的别名

/@/settings 等同于 src/settings

为什么是/@/

因为项目是从 vite1.0 过渡过来的,vite1.0 只能以 / 开头,所以有一部分从 webpack 用户转过来的可能不习惯。

为什么在本地没有按需引入组件库样式,在生产才引入

在 main.ts 内可以看到,本地开发会全量引入 antd.less,vite-plugin-style-import 在本地是没有作用的。

这样做的原因主要是加快本地开发刷新速度。如果在本地开发中也按需按需引入,则在浏览器控制台内可以看到,平均一个页面大概增加了 100 次 http 请求。如果全量引入,只增加了一个请求,所以为了减少请求数量,才这样种。

// src/main.ts
+if (import.meta.env.DEV) {
+  import('ant-design-vue/dist/antd.less');
+}
+
+// build/vite/plugin/styleImport
+import styleImport from 'vite-plugin-style-import';
+export function configStyleImportPlugin(isBuild: boolean) {
+  if (!isBuild) return [];
+  const styleImportPlugin = styleImport({
+    libs: [
+      {
+        libraryName: 'ant-design-vue',
+        esModule: true,
+        resolveStyle: (name) => {
+          return `ant-design-vue/es/${name}/style/index`;
+        },
+      },
+    ],
+  });
+  return styleImportPlugin;
+}
+

为什么单独把 moment 放到 dataUtil 内

src/utils/dataUtil 内,使用的是 moment,其次在页面中对时间的操作也是使用 dateUtil,而不是直接 import moment from 'moment'

这样做主要是方便后续切换到 dayjs,因为 api 一样,所以在后续切换中,只需更改 dataUtil 内的 import 即可,而不用全部更改。

+ + + + \ No newline at end of file diff --git a/other/faq.html b/other/faq.html new file mode 100644 index 00000000..404fd02e --- /dev/null +++ b/other/faq.html @@ -0,0 +1,87 @@ + + + + + + 常见问题 | Vben Admin + + + + + + + + + + + + + + + + +

常见问题

TIP

列举了一些常见的问题。有问题可以先来这里寻找,如果没有可以在 issue 提。

前言

遇到问题,可以先从以下几个方面查找

  1. 对应模块的 GitHub 仓库 issue 搜索
  2. google搜索问题
  3. 百度搜索问题
  4. 在下面列表找不到问题可以到 issue 提问 issues
  5. 如果不是问题类型的,需要讨论的,请到 discussions 讨论

关于缓存更新问题

vben-admin 的项目配置默认是缓存在 localStorage 内,所以版本更新后可能有些配置没改变。

解决方式是每次更新代码的时候修改 package.json 内的 version 版本号. 因为 localStorage 的 key 是根据版本号来的。所以更新后版本不同前面的配置会失效。重新登录即可

VUE_VBEN_ADMIN__DEVELOPMENT__2.0.3__COMMON__LOCAL__KEY__ key 的组成是 [项目名]+[开发环境]+[版本号]+[key]

关于修改配置文件的问题

当修改 .env 等环境文件及 vite.config.ts 文件时,vite 会自动重启服务。

自动重启有几率出现问题,请重新运行项目即可解决.

esbuild 模式下开启 LEGACY 打包失败

如果将  build.minify 设置为 'esbuild',且不能启用 LEGACY,否则打包将会报错,两者选其一即可打包。

ant-design-vue 控制台警告

在控制台看到以下警告的原因是 ant-design-vue 会检测是否使用了 babel-plugin-import 来判断是否进行了组件库的按需引入。

但是项目使用的是 vite 的插件 vite-plugin-style-import 来进行按需引入。在 vite 内没必要使用 babel 在转换一次代码了。

所以想关闭这个警告,得等 ant-design-vue 提供可以关闭该警告的配置。

You are using a whole package of antd, please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size. Not support Vite !!!
+

添加菜单后没显示

菜单必须和路由匹配才会显示在界面上,所以得确保菜单和对应的路由存在即可显示.

本地运行报错

由于 vite 在本地没有转换代码,且代码中用到了可选链等比较新的语法。所以本地开发需要使用版本较高的浏览器(Chrome 85+)进行开发

tab 页切换后页面空白

这是由于开启了路由切换动画,且对应的页面组件存在多个根节点导致的,在页面最外层添加<div></div>即可

错误示例

<template>
+  <!-- 注释也算一个节点 -->
+  <h1>text h1</h1>
+  <h2>text h2</h2>
+</template>
+

正确示例

<template>
+  <div>
+    <h1>text h1</h1>
+    <h2>text h2</h2>
+  </div>
+</template>
+

提示

  • 如果想使用多个根标签,可以禁用路由切换动画
  • template 下面的根注释节点也算一个节点

组件命名问题

目前在 vite+vue3.0.5 版本中,如果组件命名携带关键字,则可能会导致内存溢出。例如 ImportExcel excel 导入组件。

我的代码本地开发可以,打包就不行了

目前发现这个原因可能有以下,可以从以下原因来排查,如果还有别的可能,可以提交 pr 来告诉我

  1. 使用了 ctx 这个变量,ctx 本身未暴露出在实例类型内,尤大也是说了不要用这个属性。这个属性只是用于内部使用。
import { getCurrentInstance } from 'vue';
+getCurrentInstance().ctx.xxxx;
+

safari 问题

目前在 safari 上面本地开发运行样式会有问题,还未找到原因,有知道的也可以告诉我。

模版区别

  • Vue-Vben-Admin - 是包含 Demo 示例的,个人建议不要在这上面进行开发。当然,你如果动手能力强的话可以直接改。
  • Vue-Vben-Admin-Thin-Next 精简了代码后的模版项目。适合在这基础上进行二次开发。

环境问题

如果出现依赖安装报错,启动报错等。先检查电脑环境有没有安装齐全。

  • Node 版本必须大于12.0.0不支持 13, 推荐 14 版本。
  • Git
  • Yarn 最新版

依赖安装问题

  • 如果依赖安装不了或者启动报错可以先尝试 删除 yarn.locknode_modules,然后重新运行 yarn install
  • 如果依赖安装不了或者报错,可以尝试切换手机热点来进行依赖安装。
  • 如果还是不行,可以自行配置国内镜像安装。
  • 也可以在项目根目录创建 .npmrc 文件,内容如下
# .npmrc
+registry = https://registry.npm.taobao.org
+

然后重新执行yarn run reinstall等待安装完成即可

如何保证我的代码能更新到最新代码

如果你使用了该项目进行项目开发。开发之中想同步最新的代码。你可以设置多个源的方式

  1. 克隆代码
git clone https://github.com/vbenjs/vben-admin-thin-next.git
+
  1. 添加自己的公司 git 源地址
# up 为源名称,可以随意设置
+# gitUrl为开源最新代码
+git remote add up gitUrl;
+
  1. 提交代码到自己公司 git
# 提交代码到自己公司
+# main为分支名 需要自行根据情况修改
+git push up main
+
+# 同步公司的代码
+# main为分支名 需要自行根据情况修改
+git pull up main
+
  1. 如何同步开源最新代码
git pull origin main
+

TIP

同步代码的时候会出现冲突。只需要把冲突解决即可

打包文件过大

  • 首先,完整版由于引用了比较多的库文件,所以打包会比较大。可以使用精简版来进行开发

  • 其次建议开启 gzip,使用之后体积会只有原先 1/3 左右。

gzip 可以由服务器直接开启。如果是这样,前端不需要构建 .gz 格式的文件

如果前端构建了 .gz 文件,以 nginx 为例,nginx 需要开启 gzip_static: on 这个选项。

  • 开启 gzip 的同时还可以同时开启 brotli,比 gzip 更好的压缩。两者可以共存

注意

  • gzip_static: 这个模块需要 nginx 另外安装,默认的 nginx 没有安装这个模块。

  • 开启 brotli 也需要 nginx 另外安装模块

运行错误

如果出现类似以下错误,请检查项目全路径(包含所有父级路径)不能出现中文、日文、韩文。否则将会出现路径访问 404 导致以下问题

[vite] Failed to resolve module import "ant-design-vue/dist/antd.css-vben-adminode_modulesant-design-vuedistantd.css". (imported by /@/setup/ant-design-vue/index.ts)
+

为什么是 moment.js

很多人问为什么不用dayjs。在项目依赖中可以看到,它是 Ant-Design-Vue 内部自带的。

目前还没有基于 Vite 的 dayjs 替换 momentjs 方案,webpack 已经有了。等以后出现了在进行替换。

控制台路由警告问题

如果看到控制台有如下警告,且页面能正常打开 可以忽略该警告。

后续 vue-router 可能会提供配置项来关闭警告

2.6.1 及以上版本已移除此警告

[Vue Router warn]: No match found for location with path "xxxx"
+

启动报错

当出现以下错误信息时,请检查你的 nodejs 版本号是否符合要求

TypeError: str.matchAll is not a function
+at Object.extractor (vue-vben-admin-main\node_modules@purge-icons\core\dist\index.js:146:27)
+at Extract (vue-vben-admin-main\node_modules@purge-icons\core\dist\index.js:173:54)
+
+

页面报错

当页面出现以下报错,是因为 /xxx 对应的路由组件内部出现了错误。

 Uncaught (in promise) Error: Couldn't resolve component "default" at "/xxx"
+
+

可以尝试从以下几点排查

  1. 检查对应组件内部 import 的所有文件是否正确
  2. 检查引入方式是否错误。
// 正确的
+import { cloneDeep } from 'lodash-es';
+
+// 报错
+import _ from 'lodash-es';
+
  1. 检查样式是否使用变量及有没有引入对应的变量文件
  2. 检查代码明显的语法错误

这样就不会是使用的取值忘记 xxx.value 来进行数据获取

跨域问题

参考跨域问题

接口请求问题

proxy 代理不成功,没有代理到实际地址?

代理只是服务请求代理,这个地址是不会变的。 原理可以简单的理解为,在本地启了一个服务,你先请求了本地的服务,本地的服务转发了你的请求到实际服务器。所以你在浏览器上看到的请求地址还是 http://localhost:8000/xxx。以服务端是否收到请求为准。

组件库问题

跟组件库相关的问题可以查看常见问题

动态调整菜单问题

菜单数据的值被存放在 store/modules/permission store 中, 你可以在这里进行修改

更灵活的菜单路由权限控制

你可以在 store/modules/permission下, 修改 routeFilter 方法来进行更灵活的菜单路由权限控制

 const routeFilter = (route: AppRouteRecordRaw) => {
+    const { meta } = route;
+    // 抽出角色
+    const { roles } = meta || {};
+
+    // 添加你的自定义逻辑来过滤路由和菜单
+    if (xxx) {
+      return false;
+    }
+
+    if (!roles) return true;
+    // 进行角色权限判断
+    return roleList.some((role) => roles.includes(role));
+  };
+
+
+ + + + \ No newline at end of file diff --git a/other/project.html b/other/project.html new file mode 100644 index 00000000..ba9b6334 --- /dev/null +++ b/other/project.html @@ -0,0 +1,31 @@ + + + + + + 相关项目 | Vben Admin + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/other/server.html b/other/server.html new file mode 100644 index 00000000..73bc65e1 --- /dev/null +++ b/other/server.html @@ -0,0 +1,40 @@ + + + + + + 测试服务器 | Vben Admin + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file

2L}erKZ(3m=CR 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 S$-ex|j+l^?U>U!T@Baa|V1Hx) literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 00000000..f9f34f63 --- /dev/null +++ b/index.html @@ -0,0 +1,31 @@ + + + + + + Vben Admin + + + + + + + + + + + + + + + + +

cE9>)App7JVqoHjbk8V{0aaQ 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