• 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组件设计和开发规范,高颜值的组件让整体风格细腻统一。

    技术框架

    • 开发工具: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

    功能特性

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

    项目目录结构

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

    效果预览

    Svelte Ui组件库

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

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

    复制代码
    import {
        Button,
        Input,
        Radio,
        Select,
        Checkbox,
        ...
    } from 'svelte-ui'
    复制代码

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

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

    Svelte Ui Admin页面布局结构

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

    +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组件库中的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-i18n国际化解决方案

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

    npm i svelte-i18n -D

    复制代码
    /**
     * 国际化语言配置
     * @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尺寸改变。

    复制代码
    /**
     * @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插槽等功能。

    复制代码
    
    
    <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'}
            
        {: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

     

  • 相关阅读:
    【Java学习Note】第8章 多线程
    Jmeter性能综合实战 —— 签到及批量签到
    java毕业设计基于精细化考核的离散数学课程教学目标达成系统Mybatis+系统+数据库+调试部署
    【小程序项目开发-- 京东商城】uni-app之自定义搜索组件(下) -- 搜索历史
    北大青鸟培训后端培训第二天
    python 异常
    XSS跨站脚本攻击
    黑莓手机时代落幕;阿里巴巴为 Linux 内核调度器提出新概念;清理 Linux 内核“依赖地狱” | 开源日报
    贪心,队列,运算符重载,牛客:连环爆炸
    depends工具查看exe和dll依赖关系
  • 原文地址:https://www.cnblogs.com/xiaoyan2017/p/16701624.html