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

功能特性

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

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

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

项目目录结构

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

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

效果预览

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Svelte Ui组件库

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

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

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

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

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中后台前端解决方案插图26

+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 HomeButton>
    div>
div>

自定义路由菜单Menu

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

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

如上图:使用了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中后台前端解决方案插图29

svelte-i18n国际化解决方案

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

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

npm i svelte-i18n -D

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

/**
 * 国际化语言配置
 * @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中后台前端解决方案插图32

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

/**
 * @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。



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

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



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'}
        {row.title}
    {:else if col.slot == 'image'}
        Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案插图35
    {:else if col.slot == 'summary'}
        
            
{row.summary}
{:else if col.slot == 'role'} {#if row.role == 'admin'} {row.role} {:else if row.role == 'test'} {row.role} {:else} {row.role} {/if} {:else if col.slot == 'topmost'} {:else if col.slot == 'progress'} {:else if col.slot == 'btns'} 查看 编辑 删除 {/if} 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中后台前端解决方案插图36

 

文章来源于互联网:Svelte Ui Admin后台管理系统|svelte3+svelteUI中后台前端解决方案

THE END
分享
二维码