国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

這篇具有很好參考價(jià)值的文章主要介紹了Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

基于vite4.x+vue3+pinia前端后臺(tái)管理系統(tǒng)解決方案ViteAdmin。

前段時(shí)間分享了一篇vue3自研pc端UI組件庫(kù)VEPlus。這次帶來(lái)最新開(kāi)發(fā)的基于vite4+vue3+pinia技術(shù)棧搭配ve-plus組件庫(kù)構(gòu)建的中后臺(tái)權(quán)限管理系統(tǒng)框架。支持vue-i18n國(guó)際化多語(yǔ)言、動(dòng)態(tài)路由鑒權(quán)、4種布局模板及tab頁(yè)面緩存等功能。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

技術(shù)棧

  • 編碼工具:Cursor+Sublime
  • 框架技術(shù):vite4+vue3+pinia+vue-router
  • UI組件庫(kù):ve-plus (基于vue3自研ui組件庫(kù))
  • 樣式處理:sass^1.58.3
  • 圖表組件:echarts^5.4.2
  • 國(guó)際化方案:vue-i18n^9.2.2
  • 富文本編輯器組件:wangeditor^4.7.15
  • markdown編輯器:md-editor-v3^2.11.0
  • 數(shù)據(jù)模擬:mockjs^1.1.0

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

功能點(diǎn)

  1. 最新前端技術(shù)棧vite4、vue3、pinia、vue-router、vue-i18n、ve-plus。
  2. 支持中文/英文/繁體多語(yǔ)言模式切換。
  3. 支持表格單選/多選、邊框/隔行換色、橫向/縱向虛擬滾動(dòng)條等功能。
  4. 搭配高顏值的vue3-plus組件庫(kù),風(fēng)格更加統(tǒng)一。
  5. 內(nèi)置多個(gè)模板布局樣式
  6. 支持動(dòng)態(tài)路由權(quán)限控制
  7. 支持tabs動(dòng)態(tài)路由緩存
  8. 高效率開(kāi)發(fā),整個(gè)框架已經(jīng)搭建完畢,只需定制化相應(yīng)模塊即可。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

項(xiàng)目頁(yè)面結(jié)構(gòu)

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

整體采用vue3 setup語(yǔ)法糖模式開(kāi)發(fā),搭配ve-plus輕量級(jí)組件庫(kù),使得界面清新且運(yùn)行極速。

效果圖

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vue3 UI? VEPlus組件

ve-plus:基于vue3開(kāi)發(fā)的pc端組件庫(kù),包含了40+常用的功能組件,易于上手。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

veplus整合了vue3.js開(kāi)發(fā)的兩個(gè)獨(dú)立插件vue3-layer彈窗、vue3-scrollbar虛擬滾動(dòng)條組件。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

快速安裝

npm install ve-plus -S
cnpm install ve-plus -S
yarn add ve-plus

具體的使用方法,大家可以去看看這篇分享文章。

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

Vite-Admin布局模塊

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

公共布局文件在layouts目錄,提供了4種經(jīng)典的布局模板。

<script setup>
    import { computed } from 'vue'
    import { appStore } from '@/store/modules/app'

    // 引入布局模板
    import Classic from './layout/classic/index.vue'
    import Columns from './layout/columns/index.vue'
    import Vertical from './layout/vertical/index.vue'
    import Transverse from './layout/transverse/index.vue'

    const store = appStore()
    const config = computed(() => store.config)

    const LayoutConfig = {
        classic: Classic,
        columns: Columns,
        vertical: Vertical,
        transverse: Transverse
    }
</script>

<template>
    <div class="veadmin__container" :style="{'--themeSkin': store.config.skin}">
        <component :is="LayoutConfig[config.layout]" />
    </div>
</template>

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

主模板main.vue提供了Permission權(quán)限控制及KeepAlive路由緩存。

<!-- 主緩存模板 -->
<script setup>
    import { ref } from 'vue'
    import { useRoutes } from '@/hooks/useRoutes'
    import { tabsStore } from '@/store/modules/tabs'

    import Permission from '@/components/Permission.vue'
    import Forbidden from '@/views/error/forbidden.vue'

    const { route } = useRoutes()
    const store = tabsStore()
</script>

<template>
    <Scrollbar autohide gap="2">
        <div class="ve__layout-main__wrapper">
            <!-- 路由鑒權(quán) -->
            <Permission :roles="route?.meta?.roles">
                <template #tips>
                    <Forbidden />
                </template>
                <!-- 路由緩存 -->
                <router-view v-slot="{ Component }">
                    <transition name="ve-slide-right" mode="out-in" appear>
                        <KeepAlive :include="store.cacheViews">
                            <component v-if="store.reload" :is="Component" :key="route.path" />
                        </KeepAlive>
                    </transition>
                </router-view>
            </Permission>
        </div>
    </Scrollbar>
</template>

自定義路由菜單RouteMenu

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例?Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例?Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

如上圖:路由菜單組件只需傳入配置參數(shù),即可切換不同的模式。

<RouteMenu :rootRouteEnable="false" />
<RouteMenu
    rootRouteEnable
    collapsed
    background="#292d3e"
    backgroundHover="#353b54"
    color="rgba(235,235,235,.7)"
/>
<RouteMenu
    mode="horizontal"
    background="#292d3e"
    backgroundHover="#353b54"
    color="rgba(235,235,235,.7)"
/>

RouteMenu.vue模板

<!-- 路由菜單 -->
<script setup>
  import { ref, computed, h, watch, nextTick } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { Icon, useLink } from 've-plus'
  import { useRoutes } from '@/hooks/useRoutes'
  import { appStore } from '@/store/modules/app'

  // 引入路由集合
  import mainRoutes from '@/router/modules/main.js'

  const props = defineProps({
    // 菜單模式(vertical|horizontal)
    mode: { type: String, default: 'vertical' },
    // 是否開(kāi)啟一級(jí)路由菜單
    rootRouteEnable: { type: Boolean, default: true },
    // 是否要收縮
    collapsed: { type: Boolean, default: false },

    // 菜單背景色
    background: String,
    // 滑過(guò)背景色
    backgroundHover: String,
    // 菜單文字顏色
    color: String,
    // 菜單激活顏色
    activeColor: String
  })

  const { t } = useI18n()
  const { jumpTo } = useLink()
  const { route, getActiveRoute, getCurrentRootRoute, getTreeRoutes } = useRoutes()
  const store = appStore()

  const rootRoute = computed(() => getCurrentRootRoute(route))
  const activeKey = ref(getActiveRoute(route))
  const menuOptions = ref(getTreeRoutes(mainRoutes))
  const menuFilterOptions = computed(() => {
    if(props.rootRouteEnable) {
      return menuOptions.value
    }
    // 過(guò)濾掉一級(jí)菜單
    return menuOptions.value.find(item => item.path == rootRoute.value && item.children)?.children
  })
  console.log('根路由地址::>>', rootRoute.value)
  console.log('過(guò)濾后路由地址::>>', menuFilterOptions.value)

  watch(() => route.path, () => {
    nextTick(() => {
      activeKey.value = getActiveRoute(route)
    })
  })

  // 批量渲染圖標(biāo)
  const batchRenderIcon = (option) => {
    return h(Icon, {name: option?.meta?.icon})
  }

  // 批量渲染標(biāo)題
  const batchRenderLabel = (option) => {
    return t(option?.meta?.title)
  }

  // 路由菜單更新
  const handleUpdate = ({key}) => {
    jumpTo(key)
  }
</script>

<template>
  <Menu
    class="veadmin__menus"
    v-model="activeKey"
    :options="menuFilterOptions"
    :mode="mode"
    :collapsed="collapsed && store.config.collapse"
    iconSize="18"
    key-field="path"
    :renderIcon="batchRenderIcon"
    :renderLabel="batchRenderLabel"
    :background="background"
    :backgroundHover="backgroundHover"
    :color="color"
    :activeColor="activeColor"
    @change="handleUpdate"
    style="border: 0;"
  />
</template>

vue-i18n國(guó)際化解決方案

vite-admin支持中英文/繁體三種語(yǔ)言模式,使用?"vue-i18n": "^9.2.2"?組件。

?Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

/**
 * 國(guó)際化配置
 * @author YXY
 */

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

// 引入語(yǔ)言配置
import enUS from './en-US'
import zhCN from './zh-CN'
import zhTW from './zh-TW'

// 默認(rèn)語(yǔ)言
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模板

<script setup>
  import { ref } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { appStore } from '@/store/modules/app'
  
  const { locale } = useI18n()
  const store = appStore()

  const langVal = ref(locale.value)
  const langOptions = ref([
    {key: "zh-CN", label: "簡(jiǎn)體中文"},
    {key: "zh-TW", label: "繁體字"},
    {key: "en", label: "英文"},
  ])

  const changeLang = () => {
    // 設(shè)置locale語(yǔ)言
    locale.value = langVal.value
    store.lang = locale.value
    // store.setLang(locale.value)
  }
</script>

<template>
  <Dropdown v-model="langVal" :options="langOptions" placement="bottom" @change="changeLang">
    <div class="toolbar__item"><Icon name="ve-icon-lang" size="20" cursor /></div>
    <template #label="{item}">
      <div>
        {{item.label}} <span style="color: #999; font-size: 12px;">{{item.key}}</span>
      </div>
    </template>
  </Dropdown>
</template>

Vue3動(dòng)態(tài)圖表Hooks

vite-admin支持動(dòng)態(tài)圖表,使用?"echarts": "^5.4.2"?組件。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

/**
 * 動(dòng)態(tài)圖表Hooks
 * @author YXY
 */

import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as echarts from 'echarts'
import { useResizeObserver } from 've-plus'

export function useEcharts(node, options) {
    let chartNode
    let chartRef = ref(null)

    const resizeHandle = () => {
        chartNode && chartNode.resize()
    }

    onMounted(() => {
        if(node.value) {
            chartNode = echarts.init(node.value)
            chartNode.setOption(options)
            chartRef.value = chartNode
        }
    })

    onBeforeUnmount(() => {
        chartNode.dispose()
    })
    // 自適應(yīng)圖表
    useResizeObserver(node, resizeHandle)

    return chartRef
}

通過(guò)useResizeObserver函數(shù),支持圖表自適應(yīng)大小。

網(wǎng)站動(dòng)態(tài)標(biāo)題title

通過(guò)監(jiān)聽(tīng)路由route更改,動(dòng)態(tài)設(shè)置網(wǎng)站標(biāo)題。

/**
 * 設(shè)置網(wǎng)站標(biāo)題
 * @author YXY
 */

import { watch, unref } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'

export function useTitle() {
    const { VITE_APP_TITLE } = import.meta.env
    const { currentRoute } = useRouter()
    const { t, locale } = useI18n()
    
    watch(
        () => [currentRoute.value.path, locale.value],
        () => {
            console.log('開(kāi)始監(jiān)聽(tīng)標(biāo)題變化........')
            
            const route = unref(currentRoute)
            const title = route?.meta?.title ? `${t(route?.meta?.title)} - ${VITE_APP_TITLE}` : VITE_APP_TITLE
            console.log('監(jiān)聽(tīng)標(biāo)題', title)
            document.title = title
        },
        {immediate: true}
    )
}

動(dòng)態(tài)路由緩存

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

ve-admin支持keepalive路由緩存功能。使用?pinia?替代?vuex?狀態(tài)管理,使用?pinia-plugin-persistedstate?持久化存儲(chǔ)。

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

TabsView.vue模板

<script setup>
  import { ref, computed, watch, nextTick, h } from 'vue'
  import { useRouter, useRoute } from 'vue-router'
  import { useI18n } from 'vue-i18n'
  import { appStore } from '@/store/modules/app'
  import { tabsStore } from '@/store/modules/tabs'

  const { t } = useI18n()
  const router = useRouter()
  const route = useRoute()

  const app = appStore()
  const store = tabsStore()

  const tabKey = ref(route.path)
  const tabOptions = computed(() => store.tabViews)

  // 滾動(dòng)到當(dāng)前路由
  const scrollToActiveRoute = () => {
    nextTick(() => {
      const activeRef = scrollbarRef.value.scrollbarWrap.querySelector('.actived').offsetLeft
      scrollbarRef.value.scrollTo({left: activeRef, top: 0, behavior: 'smooth'})
    })
  }

  // 監(jiān)聽(tīng)路由(增加標(biāo)簽/緩存)
  watch(() => route.path, () => {
    tabKey.value = route.path

    const params = {
      path: route.path,
      name: route.name,
      meta: {
        ...route.meta
      }
    }
    store.addTabs(params)
    scrollToActiveRoute()
  }, {
    immediate: true
  })

  // 右鍵菜單
  const scrollbarRef = ref()
  const selectedTab = ref({})
  const contextmenuRef = ref()
  const contextmenuOptions = ref([
    { key: 'refresh', icon: 've-icon-reload', label: 'tabview__contextmenu-refresh' },
    { key: 'close', icon: 've-icon-close', label: 'tabview__contextmenu-close' },
    { key: 'closeLeft', icon: 've-icon-logout', label: 'tabview__contextmenu-closeleft' },
    { key: 'closeRight', icon: 've-icon-logout1', label: 'tabview__contextmenu-closeright' },
    { key: 'closeOther', icon: 've-icon-retweet', label: 'tabview__contextmenu-closeother' },
    { key: 'closeAll', icon: 've-icon-close-square', label: 'tabview__contextmenu-closeall' },
  ])
  const handleRenderLabel = (option) => {
    return t(option?.label)
  }

  // 是否第一個(gè)標(biāo)簽
  const isFirstTab = () => {
    return selectedTab.value.path === store.tabViews[0].path || selectedTab.value.path === '/home/index'
  }
  // 是否最后一個(gè)標(biāo)簽
  const isLastTab = () => {
    return selectedTab.value.path === store.tabViews[store.tabViews.length - 1].path
  }

  const openContextMenu = (tab, e) => {
    selectedTab.value = tab
    contextmenuOptions.value[1].disabled = tab.meta?.isAffix
    contextmenuOptions.value[2].disabled = isFirstTab()
    contextmenuOptions.value[3].disabled = isLastTab()

    // 設(shè)置坐標(biāo)
    contextmenuRef.value.setPos(e.clientX, e.clientY)
    contextmenuRef.value.show()
  }

  const changeContextMenu = (v) => {
    if(v.key == 'refresh') {
      if(tabKey.value !== selectedTab.value.path) {
        router.push(selectedTab.value.path)
      }
      store.reloadTabs()
      return
    }else if(v.key == 'close') {
      store.removeTabs(selectedTab.value)
    }else if(v.key == 'closeLeft') {
      store.removeLeftTabs(selectedTab.value)
    }else if(v.key == 'closeRight') {
      store.removeRightTabs(selectedTab.value)
    }else if(v.key == 'closeOther') {
      store.removeOtherTabs(selectedTab.value)
    }else if(v.key == 'closeAll') {
      store.clearTabs()
    }
    updateTabRoute()
  }

  // 跳轉(zhuǎn)更新路由
  const updateTabRoute = () => {
    const lastTab = store.tabViews.slice(-1)[0]
    if(lastTab && lastTab.path) {
      router.push(lastTab.path)
    }else {
      router.push('/')
    }
  }
  // 切換tab
  const changeTab = (tab) => {
    router.push(tab.path)
  }
  // 關(guān)閉tab
  const closeTab = (tab) => {
    store.removeTabs(tab)
    updateTabRoute()
  }
</script>

<template>
  <div v-if="app.config.tabsview" class="veadmin__tabsview">
    <Scrollbar ref="scrollbarRef" mousewheel>
      <ul class="tabview__wrap">
        <li
          v-for="(tab,index) in tabOptions" :key="index"
          :class="{'actived': tabKey == tab.path}"
          @click="changeTab(tab)"
          @contextmenu.prevent="openContextMenu(tab, $event)"
        >
          <Icon class="tab-icon" :name="tab.meta?.icon" />
          <span class="tab-title">{{$t(tab.meta?.title)}}</span>
          <Icon v-if="!tab.meta?.isAffix" class="tab-close" name="ve-icon-close" @click.prevent.stop="closeTab(tab)" />
        </li>
      </ul>
    </Scrollbar>
  </div>
  <!-- 右鍵菜單 -->
  <Dropdown
    ref="contextmenuRef"
    trigger="manual"
    :options="contextmenuOptions"
    fixed="true"
    :render-label="handleRenderLabel"
    @change="changeContextMenu"
    style="height: 0;"
  />
</template>

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

/**
 * 狀態(tài)管理 Pinia
 */

import { createPinia } from 'pinia'
// 引入pinia本地持久化存儲(chǔ)
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

export default pinia
/**
 * 標(biāo)簽欄緩存狀態(tài)管理
 * 在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([]) // 標(biāo)簽欄列表
        const cacheViews = ref([]) // 緩存列表
        const reload = ref(true) // 刷新標(biāo)識(shí)

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

        /*actions*/
        // 新增標(biāo)簽
        const addTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value.map(item => {
                    if(item.path == route.path) {
                        // 當(dāng)前路由緩存
                        return Object.assign(item, route)
                    }
                })
            }else {
                tabViews.value.push(route)
            }

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

        // 移除標(biāo)簽
        const removeTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value.splice(index, 1)
            }
            updateCacheViews()
        }

        // 移除左側(cè)標(biāo)簽
        const removeLeftTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i >= index)
            }
            updateCacheViews()
        }

        // 移除右側(cè)標(biāo)簽
        const removeRightTabs = (route) => {
            const index = tabIndex(route)
            if(index > -1) {
                tabViews.value = tabViews.value.filter((item, i) => item?.meta?.isAffix || i <= index)
            }
            updateCacheViews()
        }

        // 移除其它標(biāo)簽
        const removeOtherTabs = (route) => {
            tabViews.value = tabViews.value.filter(item => item?.meta?.isAffix || item?.path === route?.path)
            updateCacheViews()
        }

        // 移除所有標(biāo)簽
        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
        }
    },
    // 本地持久化存儲(chǔ)(默認(rèn)存儲(chǔ)localStorage)
    {
        // persist: true
        persist: {
            storage: localStorage,
            paths: ['tabViews', 'cacheViews']
        }
    }
)

vite.config.js配置文件

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { wrapEnv } from './src/utils/env'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
    const viteEnv = loadEnv(mode, process.cwd())
    const env = wrapEnv(viteEnv)

    return {
        plugins: [vue()],

        // base: '/',
        // mode: 'development', // development|production

        /*構(gòu)建選項(xiàng)*/
        build: {
            // minify: 'esbuild', // 打包方式 esbuild(打包快)|terser
            // chunkSizeWarningLimit: 2000, // 打包大小警告
            // rollupOptions: {
            //     output: {
            //         chunkFileNames: 'assets/js/[name]-[hash].js',
            //         entryFileNames: 'assets/js/[name]-[hash].js',
            //         assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
            //     }
            // }
        },
        esbuild: {
            // 打包去除 console.log 和 debugger
            drop: env.VITE_DROP_CONSOLE ? ['console', 'debugger'] : []
        },

        /*開(kāi)發(fā)服務(wù)器選項(xiàng)*/
        server: {
            // 端口
            port: env.VITE_PORT,
            // 是否瀏覽器自動(dòng)打開(kāi)
            open: env.VITE_OPEN,
            // 開(kāi)啟https
            https: env.VITE_HTTPS,
            // 代理配置
            proxy: {
                // ...
            }
        },

        resolve: {
            // 設(shè)置別名
            alias: {
                '@': resolve(__dirname, 'src'),
                '@assets': resolve(__dirname, 'src/assets'),
                '@components': resolve(__dirname, 'src/components'),
                '@views': resolve(__dirname, 'src/views'),
                // 解決vue-i18n警告提示:You are running the esm-bundler build of vue-i18n.
                'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js'
            }
        }
    }
})

Okra,基于 vite4.x+pinia+vePlus 開(kāi)發(fā)后臺(tái)管理系統(tǒng)模板就分享到這里,希望對(duì)大家有些幫助哈~~ ??

最后附上兩個(gè)最近實(shí)例項(xiàng)目

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

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

Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-412559.html

到了這里,關(guān)于Vite-Admin后臺(tái)管理系統(tǒng)|vite4+vue3+pinia前端后臺(tái)框架實(shí)例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3.3 + Vite4.3 + TypeScript5+ Element-Plus:從零到一構(gòu)建企業(yè)級(jí)后臺(tái)管理系統(tǒng)(前后端開(kāi)源)

    Vue3.3 + Vite4.3 + TypeScript5+ Element-Plus:從零到一構(gòu)建企業(yè)級(jí)后臺(tái)管理系統(tǒng)(前后端開(kāi)源)

    vue3-element-admin 是基于 vue-element-admin 升級(jí)的 Vue3 + Element Plus 版本的后臺(tái)管理前端解決方案,技術(shù)棧為 Vue3 + Vite4 + TypeScript + Element Plus + Pinia + Vue Router 等當(dāng)前主流框架。 相較于其他管理前端框架,vue3-element-admin 的優(yōu)勢(shì)在于 一有一無(wú) (有配套后端、無(wú)復(fù)雜封裝): 配套完整 Java 后

    2024年02月09日
    瀏覽(96)
  • 開(kāi)源后臺(tái)管理系統(tǒng)Geekplus Admin

    開(kāi)源后臺(tái)管理系統(tǒng)Geekplus Admin

    本系統(tǒng)采用前后端分離開(kāi)發(fā)模式,后端采用springboot開(kāi)發(fā)技術(shù)棧,mybatis持久層框架,redis緩存,shiro認(rèn)證授權(quán)框架,freemarker模版在線生成代碼,websocket消息推送等,后臺(tái)管理包含用戶管理,角色管理,菜單權(quán)限管理,部門(mén)組織管理,通知管理,日志管理,系統(tǒng)監(jiān)控,在線用戶,

    2024年02月12日
    瀏覽(27)
  • 開(kāi)源后臺(tái)管理系統(tǒng) (go-vue-admin)

    go-vue-admin 是一套基于go語(yǔ)言開(kāi)源的后臺(tái)管理系統(tǒng)。功能參考諾依網(wǎng)站 ,前后端分離。 前端采用vue3、Element Plus 、RuoYi-Vue3 后端采用gofrome 框架、mysql、redis、Jwt 實(shí)現(xiàn)了一鍵生成前后端代碼,高效開(kāi)發(fā)。 用戶管理:用戶是系統(tǒng)操作者,該功能主要完成系統(tǒng)用戶配置。 部門(mén)管理:

    2024年02月07日
    瀏覽(20)
  • 后臺(tái)管理系統(tǒng)模板推薦(vue-element-admin)

    后臺(tái)管理系統(tǒng)模板推薦(vue-element-admin)

    vue-element-admin 是基于vue 和 Element-ui 的一套后臺(tái)管理系統(tǒng)集成的模板 GitHub地址: https://github.com/PanJiaChen/vue-element-admin 項(xiàng)目在線預(yù)覽: https://panjiachen.gitee.io/vue-element-admin 由尚硅谷提供的 登錄頁(yè)面 主頁(yè)面 element-ui 是餓了么前端出品的基于 Vue.js的 后臺(tái)組件庫(kù),方便程序員進(jìn)行頁(yè)

    2024年02月16日
    瀏覽(22)
  • Naive UI Admin后臺(tái)管理系統(tǒng)的組件BasicTable使用指南

    Naive Ui Admin 是一個(gè)基于 Vue3.0、 Vite、 Naive UI、 TypeScript 的中后臺(tái)解決方案,它使用了最新的前端技術(shù)棧,并提煉了典型的業(yè)務(wù)模型,頁(yè)面,包括二次封裝組件、動(dòng)態(tài)菜單、權(quán)限校驗(yàn)、粒子化權(quán)限控制等功能,它可以幫助你快速搭建企業(yè)級(jí)中后臺(tái)項(xiàng)目, 相信不管是從新技術(shù)使用

    2024年02月09日
    瀏覽(91)
  • Tauri-Admin通用后臺(tái)管理系統(tǒng)|tauri+vue3+pinia桌面端后臺(tái)EXE

    Tauri-Admin通用后臺(tái)管理系統(tǒng)|tauri+vue3+pinia桌面端后臺(tái)EXE

    基于 tauri+vite4+pinia2 跨端后臺(tái)管理系統(tǒng)應(yīng)用實(shí)例 TauriAdmin 。 tauri-admin 基于最新跨端技術(shù)? Tauri Rust webview2? 整合? Vite4? 構(gòu)建桌面端通用后臺(tái)管理解決方案。 搭載輕量級(jí)ve-plus組件庫(kù) 、支持 多窗口切換管理、vue-i18n多語(yǔ)言包、動(dòng)態(tài)路由權(quán)限、常用業(yè)務(wù)功能模塊、3種布局模板及動(dòng)

    2024年02月15日
    瀏覽(29)
  • 搭建后臺(tái)管理系統(tǒng)模板(v3+ts+vite)

    目錄 項(xiàng)目初始化 環(huán)境準(zhǔn)備 初始化項(xiàng)目 項(xiàng)目配置 一、eslint配置 .eslint.cjs配置文件 ?vue3環(huán)境代碼校驗(yàn)插件 安裝指令 修改.eslintrc.cjs配置文件? .eslintignore忽略文件 1.4運(yùn)行腳本? 二、配置prettier? 2.1安裝依賴包 2.2.prettierrc.json添加規(guī)則? 2.3.prettierignore忽略文件 ?三、配置stylelint

    2024年02月07日
    瀏覽(18)
  • vite-admin框架搭建,ESLint + Prettier 語(yǔ)法檢測(cè)和代碼格式化

    vite-admin框架搭建,ESLint + Prettier 語(yǔ)法檢測(cè)和代碼格式化

    開(kāi)發(fā)工具: vs code node: 20.10.0 npm: 10.2.3 UI框架: Element-plus gitee地址: 搭建一個(gè)新的vite項(xiàng)目 搭建完成執(zhí)行命令后如圖所示 安裝完后項(xiàng)目目錄為 1.1 安裝插件 1.2 初始化ESLint 安裝后生成 .eslintrc.cjs 文件, 配置如下: 2.1 安裝插件 2.2 配置Prettier 根目錄下創(chuàng)建.prettierrc.cjs文件 .prett

    2024年02月02日
    瀏覽(46)
  • 基于react18+vite4+arco.design搭建極簡(jiǎn)版后臺(tái)管理模板

    基于react18+vite4+arco.design搭建極簡(jiǎn)版后臺(tái)管理模板

    趁著國(guó)慶前夕整了一個(gè) vite4 結(jié)合 react18 搭建后臺(tái)管理模板,搭配上字節(jié)團(tuán)隊(duì)react組件庫(kù) ArcoDesign ,整體操作功能非常絲滑。目前功能 支持多種模板布局、暗黑/亮色模式、國(guó)際化、權(quán)限驗(yàn)證、多級(jí)路由菜單、tabview標(biāo)簽欄快捷菜單、全屏控制 等功能。極簡(jiǎn)非凡的布局界面、高定

    2024年02月08日
    瀏覽(22)
  • vue-element-admin:基于element-ui 的一套后臺(tái)管理系統(tǒng)集成方案

    vue-element-admin:基于element-ui 的一套后臺(tái)管理系統(tǒng)集成方案

    1.1簡(jiǎn)介 vue-element-admin是基于element-ui 的一套后臺(tái)管理系統(tǒng)集成方案。 GitHub地址:https://github.com/PanJiaChen/vue-element-admin 項(xiàng)目在線預(yù)覽:https://panjiachen.gitee.io/vue-element-admin 1.2安裝 如果上面的install報(bào)錯(cuò) 則先執(zhí)行下面的命令,再install 2.1簡(jiǎn)介 vueAdmin-template是基于vue-element-admin的一套

    2023年04月16日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包