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

[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑

這篇具有很好參考價值的文章主要介紹了[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1.動態(tài)路由

? ? ? ? 1.因為我們左側(cè)權(quán)限菜單是根據(jù)不同用戶顯示不一樣的 所以我們需要使用動態(tài)路由 來動態(tài)生成右側(cè)路由信息

? ? ? ? ? ? ? ? 在總體布局頁面添加router

  • <router-view> 是 Vue Router 提供的組件,用于動態(tài)展示匹配到的路由組件內(nèi)容。
  • 通過在合適的位置放置 <router-view>,你可以根據(jù)路由路徑動態(tài)地渲染對應(yīng)的組件內(nèi)容。

[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? ?2.router里面需要添加children?

? ? ? ? ? ? ? ? ? ? 因為我們是多級頁面 之后動態(tài)路由也是多級的 如果這里不提前寫children 之后動態(tài)生成的時候找不到Children

[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? ?3.做動態(tài)路由是否生成判斷 盡量減少生成次數(shù)

? ? ? ? ??1.在store里面添加全局狀態(tài)

[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? 4.permission.js

router.beforeEach((to,from,next)=>{
    const whiteList=['/login'] // 白名單
    let token=store.getters.GET_TOKEN;
    let hasRoutes = store.state.hasRoutes;
    let menuList = store.getters.GET_MENULIST
    if(token){
        if(!hasRoutes){
            bindRoute(menuList);
            store.commit("SER_ROUTES_STATE",true)
//注意這一行代碼 在這一篇文章 詳細(xì)解釋了 如不過寫會刷新白屏
            next({ ...to, replace: true })
        }else{
            next();
        }

    }else{
        if(whiteList.includes(to.path)){
            next();
        }else{
            next("/login");
        }
    }
})
const bindRoute=(menuList)=>{
    let newRoutes = router.options.routes;
    menuList.forEach(menu=>{
        if(menu.children){
            menu.children.forEach(m=>{
                let route = menuToRoute(m,menu.name)
                if(route){
                    newRoutes[0].children.push(route);
                }
            })
        }
    })
    //重新添加到路由
    newRoutes.forEach(route=>{
        router.addRoute(route)
    })
}
const menuToRoute=(menu,parentName)=>{
    if(!menu.component){
        return null;
    }else{
        let route={
            name:menu.name,
            path:menu.path,
            meta:{
                parentName:parentName
            }
        }
        route.component=()=>import('@/views/'+menu.component+'.vue')
        return route
    }
}

? ? ? ? 1.menuList是我們在登錄時候得到的 樹形結(jié)構(gòu) 表結(jié)構(gòu)[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? ?2.menuToRounte是動態(tài)生成路由? 我們傳入menu和父級名字(因為父級名字之后會用到)

? ? ? ? ? ? ?生成route對象 包括 name? path? 和父級名字?

? ? ? ? ? ? ?component對應(yīng)著目錄結(jié)構(gòu)[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? ? 3.生成之后 然后把他們添加到路由里面

? ? ? ?

  1. bindRoute 函數(shù)用于將菜單列表轉(zhuǎn)換為路由配置,并添加到路由實例中。它遍歷菜單列表,并根據(jù)每個菜單項生成對應(yīng)的路由配置,然后將這些路由配置添加到 newRoutes 數(shù)組中。最后,通過 router.addRoute 方法將所有路由配置添加到路由實例中。

  2. menuToRoute 函數(shù)用于將菜單項轉(zhuǎn)換為路由配置。如果菜單項沒有指定組件,則返回 null;否則,生成一個包含菜單名、路徑和父菜單名的路由配置對象,并設(shè)置組件為異步加載形式。

2.動態(tài)標(biāo)簽頁

????????[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

?1.store里面添加標(biāo)簽頁數(shù)組 一個是當(dāng)前標(biāo)簽頁 一個是全部打開的

?????????

    state: {
        hasRoutes: false,
        editableTabsValue: '/index',
        editableTabs: [
            {
                title: '首頁',
                name: '/index'
            }
        ]
    },

???????

        ADD_TABS: (state, tab) => {
            if (state.editableTabs.findIndex(e => e.name == tab.path) === -1) {
                state.editableTabs.push({
                    title: tab.name,
                    name: tab.path
                })
            }
            state.editableTabsValue = tab.path
        },
        RESET_TABS: (state) => {
            state.editableTabsValue = '/index',
                state.editableTabs = [
                    {
                        title: '首頁',
                        name: '/index'
                    }
                ]
        },

安全退出時候 調(diào)用RESET_TABS這個方法 清空

  if(result.data.code===200){
    store.commit("SER_ROUTES_STATE",false)
    store.commit("RESET_TABS")
    store.dispatch('logout')
  }

在menuIndex里面添加 click點擊事件

[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

2.tabIndex具體實現(xiàn)

? ? ? ? 1.關(guān)聯(lián)store里面數(shù)據(jù)

? ? ? ? ? ? ? ? 涉及到路由 使用useRouter

const router = useRouter();
const editableTabsValue = ref(store.state.editableTabsValue)
const editableTabs = ref(store.state.editableTabs)

? ? ? ? ? ? ? ? ?因為我們關(guān)聯(lián)的是store里面的數(shù)據(jù) 所以當(dāng)我們store里面數(shù)據(jù)發(fā)生更改之后 頁面并沒有發(fā)生改變 所以我們需要對數(shù)據(jù)進(jìn)行監(jiān)聽 當(dāng)發(fā)生更改之后 重新賦值

<template>

<!--  選中-->
  <el-tabs
      v-model="editableTabsValue"
      type="card"
      class="demo-tabs"
      closable
      @tab-remove="removeTab"
      @tab-click="clickTab"
  >
<!-- 所有tab-->
    <el-tab-pane
        v-for="item in editableTabs"
        :key="item.name"
        :label="item.title"
        :name="item.name"
    >
      {{ item.content }}
    </el-tab-pane>
  </el-tabs>
</template>
<script  setup>
import {ref, watch} from 'vue'
import store from '@/store'
import {useRouter} from "vue-router";

const router = useRouter();

const editableTabsValue = ref(store.state.editableTabsValue)
const editableTabs = ref(store.state.editableTabs)


const removeTab = (targetName) => {
  const tabs = editableTabs.value
  let activeName = editableTabsValue.value

  // 這里是Path  使得無法刪除首頁
  if(targetName==='/index'){
    return
  }

  if (activeName === targetName) {
    tabs.forEach((tab, index) => {
      if (tab.name === targetName) {
        const nextTab = tabs[index + 1] || tabs[index - 1]
        if (nextTab) {
          activeName = nextTab.name
        }
      }
    })
  }

  editableTabsValue.value = activeName
  editableTabs.value = tabs.filter((tab) => tab.name !== targetName)

  store.state.editableTabsValue = editableTabsValue.value
  store.state.editableTabs=editableTabs.value

  // 這個獲取的是path
  router.push({path:activeName})
}

const refreshTabs =()=>{
  editableTabsValue.value=store.state.editableTabsValue;
  editableTabs.value=store.state.editableTabs;
}

// 可以拿到標(biāo)簽名稱 可以根據(jù)Name  也可以根據(jù)path
const clickTab =(target)=>{
  router.push({name:target.props.label})
}

// 監(jiān)聽變化
watch(store.state,()=>{
  refreshTabs();
},{deep:true,immediate:true})
// 深度監(jiān)聽

</script>
<style>
.demo-tabs > .el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.el-main{
  padding:0px;
}


.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{
  background-color: lightgray;
}

.el-tabs{
  height:45px
}
</style>

3.動態(tài)面包屑實現(xiàn)

? ? ? ? 面包屑[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

? ? ? ? ?這里就使用到了我們前面提到的parentName?

? ? ? ? 三個if??

? ? ? ? 如果是父級名字 并且index大于一 顯示并且加 /? 系統(tǒng)管理/

? ? ? ? 如果是最后一個直接顯示? ? ? 角色管理

<template>
  <el-icon><HomeFilled /></el-icon>
    <el-breadcrumb separator="/">

      <el-breadcrumb-item v-for="(item,index) in breadcrumbList" :key="index">
        <span class="root" v-if="parentName && index>0">{{parentName}}&nbsp;&nbsp;/&nbsp;&nbsp;</span>
        <span class="leaf" v-if="index==breadcrumbList.length-1">{{item.name}}</span>
        <span class="root" v-else>{{item.name}}</span>
      </el-breadcrumb-item>

    </el-breadcrumb>
</template>

<script setup>
import { ref,watch } from 'vue'
import {HomeFilled} from '@element-plus/icons-vue'
import {useRoute} from 'vue-router'
import store from "@/store";

const route=useRoute();
const breadcrumbList=ref([]);
const parentName=ref("")

const initBreadcrumbList=()=>{
  breadcrumbList.value=route.matched;
  parentName.value=route.meta.parentName;
}

watch(route,()=>{
  initBreadcrumbList();
},{deep:true,immediate:true})


</script>

<style lang="scss" scoped>
.leaf{
  cursor:text;
}
.root{
  color:#666;
  font-weight:600;
}
</style>

4.路由與導(dǎo)航動態(tài)綁定實現(xiàn)

? ? ? ? ? ? ?為了防止有人不點擊 直接輸入Url跳轉(zhuǎn)? 首先App.vue里面監(jiān)聽 然后添加標(biāo)簽頁數(shù)據(jù)? 此時標(biāo)簽頁可以動態(tài)變化

import { ref ,watch} from 'vue'
import { useRoute,useRouter } from 'vue-router'
const route=useRoute();
const router=useRouter();
const whitePath=['/login','/index','/']


watch(route,(to,from)=>{
  console.log("to"+to.name)
  console.log(to.path)

  if (whitePath.indexOf(to.path)===-1) {
    console.log("to.path="+to.path)
    let obj = {
      name: to.name,
      path: to.path
    }

    store.commit("ADD_TABS", obj)
  }

},{deep:true,immediate:true})

? ? ? ? 修改menu使得菜單欄也可以動態(tài)變化[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑,vue.js,前端,學(xué)習(xí)

?文章來源地址http://www.zghlxwxcb.cn/news/detail-541195.html

到了這里,關(guān)于[VUE學(xué)習(xí)]權(quán)限管理系統(tǒng)前端vue實現(xiàn)9-動態(tài)路由,動態(tài)標(biāo)簽頁,動態(tài)面包屑的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包