Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

基于svelte3.x+svelteKit+svelte-ui网页后台管理系统SvelteAdmin

Svelte-Ui-Admin 基于svelte3.x+svelteKit+vite3+echarts搭配使用Svelte UI组件库开发的一套轻量级前端中后台管理系统解决方案。Svelte Ui Admin遵循Svelte Ui组件设计和开发规范,高颜值的组件让整体风格细腻统一。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

技术框架

  • 开发工具:Vscode
  • 框架技术:svelte3.x+svelteKit+vite3
  • UI组件库:svelte-ui (基于svelte自定义pc端UI组件库)
  • 样式处理:sass^1.54.4
  • 图表组件:echarts^5.3.3
  • 编辑器组件:wangeditor^4.7.15
  • 国际化方案:svelte-i18n^3.4.0
  • 数据模拟:mockjs^1.1.0

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

功能特性

  1. 最新前端技术栈Svelte3、SvelteKit、Vite3、SvelteUI、Svelte-i18n、Echarts5.x、MockJs。
  2. 支持中文/英文/繁体多语言解决方案。
  3. 支持表格单选/多选、边框/隔行换色、横向/纵向虚拟滚动条等功能。
  4. 整体搭配高颜值的Svelte Ui组件库,风格更加统一。
  5. 高效率开发,整个框架已经搭建完毕,只需新增相应模块即可。
  6. 动态路由及菜单联动控制。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

项目目录结构

整体遵循标准的svelteKit项目结构目录及编码规范。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

效果预览

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui组件库

基于svelte3.x开发的桌面pc端UI组件库SvelteUI。超过30+组件,覆盖了大多数组件应用场景,遵循svelte.js语法规范开发。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

通过如下方式快速引入组件。

import {     Button,     Input,     Radio,     Select,     Checkbox,     ... } from 'svelte-ui'

具体的用法及介绍,可以去看看下面的这篇分享文章。

https://www.cnblogs.com/xiaoyan2017/p/16585254.html

Svelte Ui Admin页面布局结构

项目公共布局模板+layout.svelte,错误页+error.svelte

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

+layout.svelte整体分为顶部栏+左侧菜单+右侧主体内容三大板块。

<div class="svadmin__container" style="--themeSkin: {$skin}">     <div class="svadmin__wrapper-layout flexbox flex-col">         <div class="sv__layout-header">             <Header />         </div>                  <div class="sv__layout-body flex1 flexbox">             <!-- //侧边栏 -->             {#if rootRouteEnable}             <div class="sv__bd-sidebar">                 <SideMenu routes={mainRoutes} {activeRoute} />             </div>             {/if}              {#if (rootRouteEnable && route != '/') || !rootRouteEnable}             <div class="sv__bd-menus" class:collapsed={collapsed&&!rootRouteEnable}>                 <RouteMenu                     routes={getAllRoutes}                     {activeRoute}                     {activeRootRoute}                     {rootRouteEnable}                     {collapsed}                 />             </div>             {/if}              <div class="sv__bd-main flex1 flexbox flex-col">                 <!-- 面包屑导航 -->                 <BreadCrumb routes={getAllRoutes} {activeRoute} {activeRootRoute} />                                  <!-- 主内容区 -->                 <Scrollbar autohide gap={2}>                     <div class="sv__main-wrapper">                         <slot />                     </div>                 </Scrollbar>             </div>         </div>     </div> </div>

+error.svelte错误页处理。

<script>     import { page } from '$app/stores'     import { goto } from '$app/navigation'     import { Button } from '$lib/svelte-ui'      function goHome() {         goto('/home/index')     } </script>  <svelte:head>     <title>{$page.status} Error!</title> </svelte:head>  <div class="svadmin__pageErr flexbox flex-col flex-alignc flex-justifyc">     <div class="svadmin__pageErr-img"><i class="sv-icon-round_close_fill_light"></i></div>     <div class="svadmin__pageErr-content">         <div class="c-red fs-18">┗| {$page.status} |┛  Page Error~~</div>         <div class="c-999 mt-10 mb-10">{$page.error.message}</div>         <Button size="small" on:click={goHome}>Go Home</Button>     </div> </div>

自定义路由菜单Menu

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

如上图:使用了svelte-ui组件库中的Menu组件来动态生成菜单。

<Menu     class="svadmin__menu-list"     data={getNewRoutes}     active={activeRoute}     trigger="click"     collapse={collapsed}     backgroundHover="#e2f2ff" >     {#each getNewRoutes as route}         <svelte:component this={routeMenuItem} item={route} {activeRootRoute} {rootRouteEnable} />     {/each} </Menu>

<!-- 二级菜单 --> <script>     import { goto } from '$app/navigation'     import { _ } from 'svelte-i18n'      import { Menu, MenuItem, MenuSub } from '$lib/svelte-ui'     import routeMenuItem from './routeMenuItem.svelte'      import utils from '@/utils'     import { getCurrentRootRoute, hasChildrenRoute } from '@/utils/routes'      export let item = []     // 根菜单     export let activeRootRoute = ''     // 是否开启一级路由菜单     export let rootRouteEnable = true      function changeRoute(path) {         if(utils.isExternal(path)) {             window.open(path, '_blank')         }else {             goto(path)         }     } </script>  {#if !item.meta.hidden}     {#if activeRootRoute !== getCurrentRootRoute(item) && rootRouteEnable === true}     <div></div>     {:else}         {#if item.children && Array.isArray(item.children) && hasChildrenRoute(item.children)}             <MenuSub key={item.key}>                 <span slot="icon"><i class={item.meta.icon}></i></span>                 <div slot="title">{$_(`menu.${item.meta.title}`)}</div>                  {#each item.children || [] as route2}                 <svelte:component this={routeMenuItem} item={route2} {activeRootRoute} {rootRouteEnable} />                 {/each}             </MenuSub>         {:else}             <MenuItem key={item.key} title={$_(`menu.${item.meta.title}`)} on:click={changeRoute(item.path)}></MenuItem>         {/if}     {/if} {/if}

/**  * 路由菜单Layout.js  */ export function load() {     return {         mainRoutes: [             // 主页模块             {                 key: 'home', // 标识Menu组件匹配路径                 path: '/home', // 跳转路由                 redirect: '/home/index', // 重定向路由                 meta: {                     auth: true, // 是否验证状态                     icon: 'sv-icon-homefill', // 路由图标                     title: 'layouts__main-menu__home', // 路由标题                     hidden: false, //是否隐藏菜单项                 },                 children: [                     // 首页                     {                         key: 'home_index',                         path: 'index',                         meta: {                             auth: true,                             icon: 'sv-icon-home',                             title: 'layouts__main-menu__home_index'                         }                     },                     // 工作台                     {                         key: 'home_workplace',                         path: 'workplace',                         meta: {                             auth: true,                             icon: 'sv-icon-dashboard',                             title: 'layouts__main-menu__home_dashboard'                         }                     },                     // 自定义面包屑                     {                         key: 'home_breadcrumb',                         path: 'breadcrumb',                         meta: {                             auth: true,                             icon: 'sv-icon-breadcrumb',                             title: 'layouts__main-menu__home_breadcrumb',                             // 自定义面包屑                             breadcrumb: [                                 {                                     meta: {title: 'layouts__main-menu__home_breadcrumb'},                                     path: '/home/breadcrumb',                                 },                                 {                                     meta: {title: 'layouts__main-menu__home'},                                     path: '/home',                                 },                                 {                                     meta: {title: 'layouts__main-menu__home_breadcrumb-links'},                                 }                             ]                         }                     },                     // 外部链接                     {                         key: 'https://svelte.dev/',                         path: 'https://svelte.dev/',                         meta: {                             icon: 'sv-icon-openlink',                             title: 'layouts__main-menu__home_apidocs',                             rootRoute: '/home'                         }                     }                 ]             },                      // 组件模块             {                 key: 'component',                 path: '/component',                 redirect: '/component/table/all',                 meta: {                     auth: true, //是否验证状态                     icon: 'sv-icon-apps-fill',                     title: 'layouts__main-menu__component',                     hidden: false, //是否隐藏菜单项                 },                 children: [                     {                         key: 'component_table',                         path: 'table',                         redirect: '/component/table/all',                         meta: {                             auth: true,                             icon: 'sv-icon-table',                             title: 'layouts__main-menu__component_table',                         },                         children: [                             {                                 key: 'component_table_all',                                 path: 'all',                                 meta: {                                     title: 'layouts__main-menu__component_table-all'                                 }                             },                             {                                 key: 'component_table_custom',                                 path: 'custom',                                 meta: {                                     title: 'layouts__main-menu__component_table-custom'                                 }                             },                             {                                 key: 'component_table_search',                                 path: 'search',                                 redirect: '/component/table/search/list',                                 meta: {                                     title: 'layouts__main-menu__component_table-search',                                 },                                 children: [                                     {                                         key: 'component_table_search_list',                                         path: 'list',                                         meta: {                                             title: 'layouts__main-menu__component_table-search-list'                                         }                                     }                                 ]                             }                         ]                     },                     {                         key: 'component_list',                         path: 'list',                         meta: {                             icon: 'sv-icon-sort',                             title: 'layouts__main-menu__component_list',                         }                     },                     {                         key: 'component_form',                         path: 'form',                         redirect: '/component/form/all',                         meta: {                             auth: true,                             icon: 'sv-icon-forms',                             title: 'layouts__main-menu__component_form',                         },                         children: [                             {                                 key: 'component_form_all',                                 path: 'all',                                 meta: {                                     title: 'layouts__main-menu__component_form-all',                                 }                             },                             {                                 key: 'component_form_custom',                                 path: 'custom',                                 meta: {                                     title: 'layouts__main-menu__component_form-custom',                                 }                             }                         ]                     },                     {                         key: 'component_editor',                         path: 'editor',                         meta: {                             icon: 'sv-icon-editor',                             title: 'layouts__main-menu__component_editor',                         }                     }                 ]             },                      // 配置模块             {                 key: 'setting',                 path: '/setting',                 redirect: '/setting/mine',                 meta: {                     icon: 'sv-icon-setting',                     title: 'layouts__main-menu__setting',                     hidden: false,                 },                 children: [                     ...                 ]             },                      // 权限验证模块             {                 key: 'permission',                 path: '/permission',                 redirect: '/permission/all',                 meta: {                     auth: true,                     icon: 'sv-icon-secret',                     title: 'layouts__main-menu__permission',                     hidden: false,                 },                 children: [                     ...                 ]             },                      // 错误页面模块             {                 key: 'error',                 path: '/error',                 redirect: '/error/403',                 meta: {                     icon: 'sv-icon-roundclosefill',                     title: 'layouts__main-menu__error',                     hidden: false,                 },                 children: [                     ...                 ]             },         ]     } }

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

svelte-i18n国际化解决方案

项目中采用svelte-i18n实现国际化,支持中文/英文/繁体字三种语言。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

npm i svelte-i18n -D

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

/**  * 国际化语言配置  * @author YXY  */  import { addMessages, init, getLocaleFromNavigator } from 'svelte-i18n' import { browser } from '$app/env' import Storage from '@/utils/storage'  // 引入语言配置 import cn from '@/locale/zh-CN' import tw from '@/locale/zh-TW' import en from '@/locale/en-US'  export const langKey = 'lang' export const langVal = 'cn'  addMessages('cn', cn) addMessages('tw', tw) addMessages('en', en)  const lang = getLang() console.log('当前国际化:', lang) init({     fallbackLocale: lang,     initialLocale: getLocaleFromNavigator() }) setHtmlLang(lang)  /* 获取语言 */ export function getLang() {     const lang = Storage.get(langKey)     return lang || langVal }  /* 持久化存储 */ export function setLang(lang, reload = false) {     if(lang != getLang()) {         Storage.set(langKey, lang || '')         setHtmlLang(lang)          // 重载页面         if(reload) {             window.location.reload()         }     } }

svelte动态图表Hooks

由于项目中多个地方使用了Echarts图表组件,于是单独抽离了一个hooks文件来初始化echarts组件。

针对自适应图表,则使用了 "element-resize-detector": "^1.2.4" 来实时监听DOM尺寸改变。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

/**  * @title    动态图表Hooks  * @author    YXY */ import * as echarts from 'echarts' import elementResizeDetector from "element-resize-detector" import utils from '@/utils'  export const useCharts = async(node, options) => {     let chartInstance     let chartNode = null     let erd = elementResizeDetector()      const resizeFn = utils.debounce(() => {         chartInstance.resize()     }, 100)      if(node) {         chartInstance = echarts.init(node)         chartInstance.setOption(options)         chartNode = chartInstance     }     erd.listenTo(node, resizeFn) }

通过如下方式即可快速调用图表hooks。

<script>     import { useCharts } from '@/hooks.js'          function useBarChart(node) {         useCharts(node, {             ...         })     }      function useStackChart(node) {         useCharts(node, {             ...         })     } </script>  <div class="card-charts" use:useBarChart></div> <div class="card-charts" use:useStackChart></div>

项目中还有一大亮点就是Table表格组件,支持固定表头/列,单选及多选,边框/隔行换色,支持动态slot插槽等功能。

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

<script> /**  * 表格组件  * @author YXY  * Q:282310962 WX:xy190310  */  let tableNode let curpage = 1 let limit = 10 let selectRows = [] let tableData = Mock.mock({     total: 100,     page: 1,     pagesize: 5,     'list|10': [         {             id: '@integer(1, 1000)',             author: '@cname()',             title: '@ctitle(10, 15)',             image: `https://cdn2.thecatapi.com/images/@integer(200, 300).jpg`,             summary: '@ctitle(20, 70)',             'role|1': ['admin', 'test', 'dev'],             topmost: '@boolean()',             progress: '@integer(30, 90)',             date: '@datetime()'         }     ] }) let tableColumns = [     {type: 'selection', align: 'center', width: 60, fixed: true}, // 多选     // {type: 'index', align: 'center', width: 60}, // 索引序号     {prop: 'id', label: 'id', align: 'center', width: 60}, // 索引序号     {prop: 'author', label: '作者', align: 'center', width: 100},     {slot: 'title', label: '标题', align: 'left', width: 250},     {slot: 'image', label: '图像', align: 'center', width: 120},     {slot: 'summary', label: '详细内容', align: 'left', width: 450},     {slot: 'role', label: '角色', align: 'center', width: 100},     {slot: 'topmost', label: '置顶', align: 'center', width: 100},     {slot: 'progress', label: '热度', align: 'center', width: 150},     {prop: 'date', label: '发布时间', align: 'left', width: 200}, // 时间     {slot: 'btns', label: '操作', align: 'center', width: 200, fixed: 'right'}, // 操作 ] // 获取选中行数据 function getSelectionRow() {     svLayer({         title: '信息',         content: JSON.stringify(selectRows),         xclose: true,         area: '640px'     }) } // 选中第3行 function updateRow() {     tableNode.setCurrent(2) } // 取消选择 function cancelSelection() {     tableNode.setCurrent() } // 当前页 function handleChangePage(e) {     console.log('当前页:', e.detail)     curpage = Number(e.detail) } // 页码 function handleChangeSize(e) {     console.log('每页:', e.detail)     limit = Number(e.detail) } // 点击行 function handleSelectionChange(e) {     console.log('selection change选中行数据>>:', e.detail)     selectRows = e.detail } </script>  <Table     dataSource={tableData.list}     columns={tableColumns}     stripe={isStripe}     border={isBorder}     size={tableSizeCmd}     highlightCurrentRow     let:row     let:col     let:index     on:selectionChange={handleSelectionChange}     on:headerClick={handleHeaderClick}     bind:this={tableNode}     style="height: 500px; margin-bottom: 15px;" >     {#if col.slot == 'title'}         <Link href="https://svelte.dev/" target="_blank" isUnderline color="#06f">{row.title}</Link>     {:else if col.slot == 'image'}         <img src={row.image} style="height: 50px; width: 50px;" alt="" />     {:else if col.slot == 'summary'}         <Tooltip content={row.summary} placement="top-start">             <div class="clamp2">{row.summary}</div>         </Tooltip>     {:else if col.slot == 'role'}         {#if row.role == 'admin'}             <Tag type="success" effect="dark" size="mini">{row.role}</Tag>         {:else if row.role == 'test'}             <Tag type="primary" size="mini">{row.role}</Tag>         {:else}             <Tag type="warning" effect="dark" size="mini">{row.role}</Tag>         {/if}     {:else if col.slot == 'topmost'}         <Switch checked={row.topmost} activeColor="#ff4079" size="small" />     {:else if col.slot == 'progress'}         <Progress percent={row.progress} color="#ffa222" showtext="false" strokeWidth={10} style="width: 100px;" />     {:else if col.slot == 'btns'}         <Link type="primary" icon="sv-icon-attention_light" gap="5" on:click={handleTableView}>查看</Link>         <Link type="success" icon="sv-icon-edit" gap="5" on:click={handleTableEdit(row)}>编辑</Link>         <Link type="danger" icon="sv-icon-delete" gap="5" on:click={handleTableDel(row)}>删除</Link>     {/if} </Table> <Pagination     layout="total, sizes, prev, pager, next, jumper"     currentPage={curpage}     pageSize={limit}     pageSizes={[10, 50, 100]}     total="500"     size="mini"     position="center"     on:changePage={handleChangePage}     on:changeSize={handleChangeSize} />

Ok,基于svelte+svelteUI开发后台管理系统就分享到这里,希望对大家有所帮助~~

最后附上一个svelte.js网页聊天实例项目

https://www.cnblogs.com/xiaoyan2017/p/16272097.html

Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

 

发表评论

评论已关闭。

相关文章