91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue怎么一步到位實現動態路由

發布時間:2022-06-02 08:39:52 來源:億速云 閱讀:197 作者:iii 欄目:開發技術

今天小編給大家分享一下vue怎么一步到位實現動態路由的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

首先呢,先看看靜態路由的配置,簡單預覽一下,熟悉的可以直接跳過,說這部分,是為了熟悉一下路由的配置,配置動態路由其實就是把靜態路由存到數據庫,在取出來放進路由表(靜態是直接寫在路由表里)。

靜態路由的回顧

1.創建router/index.js文件,這里只有一些簡單的頁面

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/view/login/Login'
import Index from '@/layout/Index'
import Welcome from '@/layout/welcome/Welcome'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/',
      component: Index,
      redirect: '/welcome',
      meta: {requireAuth: true},
      children: [
        {
          path: '/welcome',
          component: Welcome,
          name: '首頁',
          meta: {title: '首頁', requireAuth: true}
        }
      ]
    }
  ]
})

2.創建router/permission.js文件,配置導航守衛,可以在每次路由跳轉前做一些操作,待會獲取動態路由操作也在這里配置

import router from '@/router/index'
import 'element-ui/lib/theme-chalk/index.css'
import '@fortawesome/fontawesome-free/css/all.min.css'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
 
NProgress.configure({
  easing: 'ease', // 動畫方式
  speed: 500, // 遞增進度條的速度
  showSpinner: false, // 是否顯示加載ico
  trickleSpeed: 200, // 自動遞增間隔
  minimum: 0.3 // 初始化時的最小百分比
})
// 白名單
const whiteList = ['/login'] // no redirect whitelist
 
// 導航守衛
router.beforeEach((to, from, next) => {
  NProgress.start()
  if (to.meta.requireAuth) {
    // 判斷該路由是否需要登錄權限
    if (sessionStorage.getItem('loginName') !== null) {
      // 判斷本地是否存在token
      next()
      // 這里是待會獲取異步路由的地方
    } else {
      // 未登錄,跳轉到登陸頁面
      next({
        path: '/login'
      })
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      if (sessionStorage.getItem('loginName') !== null) {
        // 判斷本地是否存在token
        next(`/?redirect=${to.path}`)
      } else {
        next(`/login?redirect=${to.path}`)
      }
    }
  }
})
 
router.afterEach(() => {
  // 在即將進入新的頁面組件前,關閉掉進度條
  NProgress.done()
})

這里引用了一個插件,Nprogress,就是下圖的藍色小進度條。不用也可以

vue怎么一步到位實現動態路由

 3.在main.js里引入剛才創建的router下的index.js文件和permission.js文件,如下

import router from '@/router'
import './router/permission'
 
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

4.在App入口中放入路由跳轉的視圖區,跳轉的路由頁面都顯示在這里

// APP.vue文件
<div id="app">
    <router-view />
</div>

現在靜態路由就配好了,可以正常的跳轉了!

文件夾長這樣

vue怎么一步到位實現動態路由

動態路由的配置

接下來開始配置動態路由了!

有坑的地方我會說明一下。

1.首先呢,router/index.js,沒有什么需要改的,把你需要動態獲取的路由信息刪除掉即可,可以留一部分靜態路由,如登錄頁,首頁等等,若全刪,routes賦為[]即可。

2.創建一個文件,我命名為getAsyncRouter.js,用來處理獲取到的動態路由信息。

// 用于處理動態菜單數據,將其轉為 route 形式
export function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
  // 用于保存普通路由數據
  let temp = []
  // 用于保存存在子路由的路由數據
  let route = []
  // 遍歷數據
  for (let i = 0; i < menuList.length; i++) {
    // 存在子路由,則遞歸遍歷,并返回數據作為 children 保存
    if (menuList[i].children && menuList[i].children.length > 0) {
      // 獲取路由的基本格式
      route = getRoute(menuList[i])
      // 遞歸處理子路由數據,并返回,將其作為路由的 children 保存
      route.children = fnAddDynamicMenuRoutes(menuList[i].children)
      // 保存存在子路由的路由
      routes.push(route)
    } else {
      // 保存普通路由
      temp.push(getRoute(menuList[i]))
    }
  }
  // 返回路由結果
  return routes.concat(temp)
}
 
// 返回路由的基本格式
function getRoute (item) {
  // 路由基本格式
  let route = {
    // 路由的路徑
    path: item.url,
    // 路由名
    name: item.name,
    // 路由所在組件
    // component: (resolve) => require([`@/layout/Index`], resolve),
    component: (resolve) => require([`@/view${item.curl}`], resolve),
    meta: {
      id: item.id,
      icon: item.icon
    },
    // 路由的子路由
    children: []
  }
  // 返回 route
  return route
}

這里是兩個函數,把獲取到的數據處理成路由表數據,將其變化成 route 的形式。

  • fnAddDynamicMenuRoutes 用于遞歸菜單數據。

  • getRoute 用于返回某個數據轉換的 路由格式。

注釋寫的應該算是很詳細了,主要講一下思路:

  • 對數據進行遍歷,

  • 定義兩個數組(temp,route),temp 用于保存沒有子路由的路由,route 用于保存存在子路由的路由。

  • 如果某個數據存在 子路由,則對子路由進行遍歷,并將其返回結果作為當前數據的 children。并使用 route 保存路由。

  • 如果某個數據不存在子路由,則直接使用 temp 保存路由。

  • 最后,返回兩者拼接的結果,即為轉換后的數據。

route 格式一般如下:

  • path:指路由路徑(可以根據路徑定位路由)。

  • name:指路由名(可以根據路由名定位路由)。

  • component:指路由所在的組件。

  • children:指的是路由組件中嵌套的子路由。

  • meta:用于定義路由的一些元信息。

這里有個大坑!!! 在配置component的時候,需要動態導入組件,也就是vue異步組件,查看文檔如下

vue怎么一步到位實現動態路由

 可知,有兩種導入方式,import和require方式。這里簡單說一下,

1 import屬于es6導入方式,只支持靜態導入,也就是說,你不能夠使用變量或表達式,只能使用字符串。

2 require屬于commonJS方式,可以支持動態的導入,但筆者嘗試中,可以使用``模板字符串方式,貌似也無法直接使用變量。這里盡量用字符串拼接,而不是用變量去代替拼接的字符串!

由于import不支持動態導入方式,筆者采用的是require的方式,并且在webpack文檔中有這樣一段話。

vue怎么一步到位實現動態路由

綜上所述,就是說,組件的導入可以使用字符串拼接的方式導入,可以使用模板字符串導入(字符串中含有變量),但是使用模板字符串導入時不能夠只使用變量!!必須指定一個目錄,不能全用變量代替!

// 字符串拼接方式
component: import('@/view'+'/sys/user')
// 模板字符串方式,webpack4+版本需使用require方式,注意,`@${item.curl}`,是不行的!必須指定一個目錄,不能全用變量代替
component: (resolve) => require([`@/view${item.curl}`], resolve),

這個現象其實是與webpack import()的實現高度相關的。由于webpack需要將所有import()的模塊都進行單獨打包,所以在工程打包階段,webpack會進行依賴收集。

此時,webpack會找到所有import()的調用,將傳入的參數處理成一個正則,如:

import('./app'+path+'/util') => /^\.\/app.*\/util$/

也就是說,import參數中的所有變量,都會被替換為【.*】,而webpack就根據這個正則,查找所有符合條件的包,將其作為package進行打包。

所以動態導入的正確姿勢,應該是盡可能靜態化表達包所處的路徑,最小化變量控制的區域。

3.有了處理動態路由數據的函數,那就需要在合適的地方調用,以發揮作用。這時就需要用到beforeEach了,在router/permission.js文件,配置導航守衛,可以在每次路由跳轉前做一些操作,這里就是獲取動態路由了

import router from '@/router/index'
import 'element-ui/lib/theme-chalk/index.css'
import '@fortawesome/fontawesome-free/css/all.min.css'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import {fnAddDynamicMenuRoutes} from '@/router/getAsyncRouter'
import {getRouter} from '@/api/sys/Menu'
import store from '@/store' 
 
NProgress.configure({
  easing: 'ease', // 動畫方式
  speed: 500, // 遞增進度條的速度
  showSpinner: false, // 是否顯示加載ico
  trickleSpeed: 200, // 自動遞增間隔
  minimum: 0.3 // 初始化時的最小百分比
})
// 白名單
const whiteList = ['/login'] // no redirect whitelist
 
// 導航守衛
router.beforeEach((to, from, next) => {
  NProgress.start()
  try {
    // 判斷是否已經獲取過動態菜單,未獲取,則需要獲取一次
    if (store.getters.dynamicRoutes.length === 0) {
      if (whiteList.indexOf(to.path) !== -1) {
        next()
      } else {
        getRouter().then(res => {
          if (res.code === 0) {
            let menuRouter = fnAddDynamicMenuRoutes(res.data[0].children)
            store.dispatch('app/dynamicRoutes', menuRouter).then(() => {
              router.addRoutes(store.getters.dynamicRoutes)
              next({...to, replace: true})
            })
          } else {
            console.log('獲取動態路由失敗!')
            next({path: '/login'})
          }
        })
      }
    } else {
      // 路由已存在或已緩存路由
      if (to.meta.requireAuth) {
        if (sessionStorage.getItem('loginName') !== null) {
          // 判斷本地是否存在token
          next()
        } else {
          // 未登錄,跳轉到登陸頁面
          next({path: '/login'})
        }
      } else {
        if (whiteList.indexOf(to.path) !== -1) {
          next()
        } else {
          if (sessionStorage.getItem('loginName') !== null) {
            // 判斷本地是否存在token
            next(`/?redirect=${to.path}`)
          } else {
            next(`/login?redirect=${to.path}`)
          }
        }
      }
    }
  } catch (error) {
    console.log('出錯了')
    next(`/login?redirect=${to.path}`)
  }
})
 
router.afterEach(() => {
  // 在即將進入新的頁面組件前,關閉掉進度條
  NProgress.done()
})

注釋寫的比較詳細了,主要說下思路:

首先確定獲取動態菜單數據的時機。一般在登錄成功跳轉到主頁面時,獲取動態菜單數據。

  • 由于涉及到路由的跳轉(登錄頁面 -> 主頁面),所以可以使用 beforeEach 進行路由導航守衛操作。    

  • 但由于每次路由跳轉均會觸發 beforeEach ,所以為了防止頻繁獲取動態路由值,這里采用vuex方式存儲了獲取的路由信息,如果已獲取路由,就直接跳轉,否則就獲取一次動態菜單數據并處理。

如果不采用vuex方式也可以存到sessionStorage里面,總之就是保存一下獲取的路由信息,以免重復獲取。

4接下來看一看,store的寫法

const state = {
  dynamicRoutes: []
}
 
const mutations = {
  DYNAMIC_ROUTES (state, routes) {
    state.dynamicRoutes = routes
  }
}
 
const actions = {
  dynamicRoutes ({commit}, routes) {
    commit('DYNAMIC_ROUTES', routes)
  }
}

注意:vue是單頁面應用程序,所以頁面一刷新數據部分數據也會跟著丟失,所以我們需要將store中的數據存儲到本地,才能保證路由不丟失。

到這里,動態路由就已經配置好了,總體來說不是很難,主要是有坑!但只要理清了思路,寫起代碼就會很清晰。

說一些筆者遇到的問題

1.首先是component動態導入的問題,由于webpack的版本不同,需要根據情況來采用import和require方式來導入,如果導入不正確多半會報錯,找不到module等等。或者不報錯,但路由跳轉是空白頁。如果導入正確則一定可以跳轉正常,否則,請查找正確的導入方法!路由跳轉正確,能顯示跳轉的組件,就完成了一大半!

2.路由的跳轉的地方,由于我們項目采用的是左側菜單欄,有二級菜單,所以當路由跳轉正常時,還需確定路由跳轉所渲染的位置是否正確!

后記

在刷新頁面時遇到一個問題,動態路由表會隨著vuex的刷新而消失。

處理:這里在app.vue頁面刷新時利用sessionStorage存儲一下store,防止刷新丟失vuex。

如下:

export default {
  name: 'App',
  created () {
    // 在頁面加載時讀取sessionStorage里的狀態信息
    if (sessionStorage.getItem('storeData')) {
      this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('storeData'))))
    }
    // 在頁面刷新時將vuex里的信息保存到sessionStorage里
    window.addEventListener('beforeunload', () => {
      sessionStorage.setItem('storeData', JSON.stringify(this.$store.state))
    })
    // 兼容iphone手機
    window.addEventListener('pagehide', () => {
      sessionStorage.setItem('storeData', JSON.stringify(this.$store.state))
    })
  }
}

另外,在登錄成功后也獲取了一下動態路由。這樣處理下來,刷新時也不會丟失路由了!

// 獲取動態路由
getRouter().then(res => {
  if (res.code === 0) {
    let menuRouter = fnAddDynamicMenuRoutes(res.data[0].children)
    store.dispatch('app/dynamicRoutes', menuRouter).then(() => {
      router.addRoutes(store.getters.dynamicRoutes)
    })
    console.log(store.getters.dynamicRoutes)
  } else {
    console.log('獲取動態路由失敗!')
    router.push('/login')
  }
})

以上就是“vue怎么一步到位實現動態路由”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

来安县| 佛冈县| 宁明县| 成都市| 临潭县| 浪卡子县| 波密县| 德昌县| 南江县| 石城县| 通辽市| 南通市| 大埔区| 溧阳市| 渝中区| 凌源市| 明水县| 马公市| 四会市| 米林县| 收藏| 清丰县| 奈曼旗| 永丰县| 吉木乃县| 潼关县| 北宁市| 东乌珠穆沁旗| 霍城县| 大洼县| 昂仁县| 佛坪县| 杂多县| 卫辉市| 江油市| 鹤庆县| 卢湾区| 五大连池市| 海丰县| 武宁县| 宝山区|