vite4-admin:基于vue3+vite4+pinia中后台管理系统

前言

随着 vite.js 快速迭代升级,越来越多的开发者倾向于使用vite.js来搭建vue3项目。今天给大家分享 vite4+pinia+ve-plus 开发轻量级后台管理系统项目ViteAdmin

Vite4-Vue3-Admin 使用前端最新技术vite4+pinia+vue-router@4+搭建中后台管理模板。

技术框架

  • 编码工具:Vscode
  • 框架技术:vite4.x+vue3+pinia+vue-router
  • UI组件库:vePlus (基于vue3自定义组件库)
  • 样式处理:sass^1.58.3
  • 图表组件:echarts^5.4.2
  • 国际化方案:vue-i18n^9.2.2
  • 富文本编辑器组件:wangeditor^4.7.15
  • markdown编辑器:md-editor-v3^2.11.0

功能特性

  • 支持中文+英文+繁体多语言模式切换。
  • 支持表格单选/多选、边框/隔行换色、横向/纵向虚拟滚动条等功能。
  • 搭配高颜值vue3组件库VEPlus,风格更加统一。
  • 内置多个模板布局样式
  • 支持动态路由权限控制
  • 支持keepalive路由缓存
  • ...

项目结构

vue3组件库ve-plus

ve-plus:一款基于vue3开发的轻量级高定制化UI组件库,包含超过40+常用功能组件。

image.png

至于如何安装使用,大家可以去看看之前的这篇分享文章。
https://blog.csdn.net/yanxinyun1990/article/details/129312570

布局模板

vite-admin后台管理提供了4种常用的布局模板。

image.png



image.png



自定义路由菜单RouteMenu

根据ve-plus组件库提供的Menu组件,结合路由JSON配置,生成路由菜单。

image.png

RouteMenu.vue模板




调用方式



vue3国际化多语言vue-i18n

vite-admin支持中英文+繁体切换语言。通过pinia-plugin-persistedstate存储功能。

image.png

import { createI18n } from 'vue-i18n'
import { appStore } from '@/store/modules/app'

// 引入语言配置
import enUS from './en-US'
import zhCN from './zh-CN'
import zhTW from './zh-TW'

// 默认语言
export const langVal = 'zh-CN'

export default async (app) => {
    const store = appStore()
    const lang = store.lang || langVal

    const i18n = createI18n({
        legacy: false,
        locale: lang,
        messages: {
            'en': enUS,
            'zh-CN': zhCN,
            'zh-TW': zhTW
        }
    })
    
    app.use(i18n)
}

lang.vue模板



keepAlive路由缓存

项目支持开启keep-alive动态路由页面缓存功能。

image.png

image.png

项目中使用pinia2状态管理,pinia-plugin-persistedstate进行本地存储。

/**
 * 标签栏缓存状态管理
 * 在setup store中
 * ref() 就是 state 属性
 * computed() 就是 getters
 * function() 就是 actions
 * @author YXY
 * Q:282310962 WX:xy190310
 */

import { ref, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { defineStore } from 'pinia'
import { appStore } from '@/store/modules/app'

export const tabsStore = defineStore('tabs', () => {
        const currentRoute = useRoute()
        const store = appStore()

        /*state*/
        const tabViews = ref([]) // 标签栏列表
        const cacheViews = ref([]) // 缓存列表
        const reload = ref(true) // 刷新标识

        // 判断tabViews某个路由是否存在
        const tabIndex = (route) => {
            return tabViews.value.findIndex(item => item?.path === route?.path)
        }

        /*actions*/
        // 新增标签
        const addTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value.map(item => {
                    if(item.path == route.path) {
                        // 当前路由缓存
                        return Object.assign(item, route)
                    }
                })
            }else {
                tabViews.value.push(route)
            }

            // 更新keep-alive缓存
            updateCacheViews()
        }

        // 移除标签
        const removeTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value.splice(index, 1)
            }
            updateCacheViews()
        }

        // 移除左侧标签
        const removeLeftTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i >= index)
            }
            updateCacheViews()
        }

        // 移除右侧标签
        const removeRightTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i <= index)
            }
            updateCacheViews()
        }

        // 移除其它标签
        const removeOtherTabs = (route) => {
            tabViews.value = tabViews.value.filter(item => item?.meta?.isAffix || item?.path === route?.path)
            updateCacheViews()
        }

        // 移除所有标签
        const clearTabs = () => {
            tabViews.value = tabViews.value.filter(item => item?.meta?.isAffix)
            updateCacheViews()
        }

        // 更新keep-alive缓存
        const updateCacheViews = () => {
            cacheViews.value = tabViews.value.filter(item => store.config.keepAlive || item?.meta?.isKeepAlive).map(item => item.name)
            console.log('cacheViews缓存路由>>:', cacheViews.value)
        }

        // 移除keep-alive缓存
        const removeCacheViews = (route) => {
            cacheViews.value = cacheViews.value.filter(item => item !== route?.name)
        }

        // 刷新路由
        const reloadTabs = () => {
            removeCacheViews(currentRoute)
            reload.value = false
            nextTick(() => {
                updateCacheViews()
                reload.value = true
                document.documentElement.scrollTo({ left: 0, top: 0 })
            })
        }

        // 清空缓存
        const clear = () => {
            tabViews.value = []
            cacheViews.value = []
        }

        return {
            tabViews,
            cacheViews,
            reload,
            addTabs,
            removeTabs,
            removeLeftTabs,
            removeRightTabs,
            removeOtherTabs,
            clearTabs,
            reloadTabs,
            clear
        }
    },
    // 本地持久化存储(默认存储localStorage)
    {
        // persist: true
        persist: {
            storage: localStorage,
            paths: ['tabViews', 'cacheViews']
        }
    }
)

image.png



OK,今天就先分享这里,希望大家能喜欢哟~~

https://segmentfault.com/a/1190000042710924

https://segmentfault.com/a/1190000041357547

你可能感兴趣的:(vitevue3)