最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3動態(tài)路由踩坑實戰(zhàn)記錄

 更新時間:2026年05月22日 10:08:30   作者:Struggle_zy  
當在開發(fā)各種系統(tǒng)應用時,我們常常需要根據不同用戶角色來展示不同的菜單頁面,動態(tài)路由提供了靈活的路由規(guī)則,可以根據需要輕松添加、修改或者刪除路由,這篇文章主要介紹了Vue3動態(tài)路由踩坑實戰(zhàn)的相關資料,需要的朋友可以參考下

一、問題背景

最近在開發(fā)一個基于 Vue 3 + Element Plus + Koa 后端的航天管理系統(tǒng)時,遇到了一個令人困擾的問題:無論點擊哪個菜單,頁面始終顯示固定頁面,也就是我寫的首頁內容。

下面我將詳細記錄整個排查過程,既是項目復盤,也希望能幫到遇到同類問題的開發(fā)者。

二、問題現(xiàn)象

核心現(xiàn)象非常典型,具體表現(xiàn)為:

點擊菜單 "用戶管理" → URL 變?yōu)?/system/user → 頁面顯示 "我是首頁內容"
點擊菜單 "運載火箭" → URL 變?yōu)?/space/rocket → 頁面依然顯示 "我是首頁內容"

關鍵特征:

  • 路由地址正確變化,說明路由跳轉邏輯正常;

  • 頁面內容始終不變,始終顯示我寫的首頁內容,說明路由匹配成功,但對應組件未正確渲染;

  • 控制臺無明顯報錯,排查難度增加。

三、項目基礎結構

src/
├── router/
│   ├── index.js        # 基礎路由 + 路由守衛(wèi)
│   └── dynamicRoutes.js # 動態(tài)路由注冊邏輯
├── layout/
│   └── index.vue       # 公共布局(側邊欄 + 主內容區(qū))
├── views/
│   ├── Home.vue        # 首頁組件(我寫的首頁內容)
│   ├── Login.vue       # 登錄頁組件
│   ├── system/         # 系統(tǒng)管理相關頁面
│   ├── space/          # 航天器相關頁面
│   └── 其他功能模塊頁面
├── store/
│   └── index.js        # 用戶狀態(tài)管理(登錄、角色等)
└── 其他配置文件
server/
└── routes/
    └── menu.js         # 后端菜單接口,返回動態(tài)菜單數據

四、排查過程(從易到難,逐步定位)

第一步:檢查基礎路由配置

首先排查最基礎的靜態(tài)路由配置,查看 src/router/index\.js

// src/router/index.js (主路由配置)
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/layout/index.vue' // 公共布局組件
import { useUserStore } from '@/store/index.js'

// 基礎路由
const baseRoutes = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/Login.vue')
  },
  {
    path: '/',
    component: Layout, // 全局唯一布局
    name: 'HomeLayout', // 關鍵:給父路由命名,用于動態(tài)路由掛載
    redirect: '/home',
    children: [
      {
        path: 'home',
        name: 'Home',
        component: () => import('@/views/Home.vue'), // 對應我寫的首頁內容
        meta: { requiresAuth: true }
      }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes: baseRoutes
})

// 路由守衛(wèi):權限攔截
router.beforeEach((to, from, next) => {
  const userStore = useUserStore()
  console.log('=== 路由守衛(wèi)調試 ===')
  console.log('要去的位置:', to.path)
  console.log('用戶角色:', userStore.roles)
  console.log('路由元信息:', to.meta)
  
  if (to.path === '/login') {
    next()
    return
  }

  // 檢查是否登錄
  if (!userStore.isLoggedIn) {
    next('/login')
    return
  }

  // 檢查路由權限
  if (to.meta.requiresAuth) {
    // 如果路由需要特定角色
    if (to.meta.roles && to.meta.roles.length > 0) {
      const hasRole = to.meta.roles.some(role => userStore.roles.includes(role))
      if (!hasRole) {
        next('/403') // 無權限頁面(可自行實現(xiàn))
        return
      }
    }
  }

  next()
})

export default router

排查結論:基礎路由配置無問題,我寫的首頁內容能正常顯示,登錄頁跳轉正常,路由守衛(wèi)邏輯嚴謹,排除基礎路由導致的問題。

第二步:檢查動態(tài)路由注冊(核心坑 1)

接下來排查動態(tài)路由注冊邏輯,查看 src/router/dynamicRoutes\.js 最初的寫法:

// 最初的錯誤寫法 ?
router.addRoute({
  path: child.path,           // 例如:/system/user
  component: Layout,          // 錯誤:重復創(chuàng)建 Layout 組件
  children: [...]
})

問題原因:

動態(tài)路由被注冊為 獨立的頂層路由,而非掛載到已有的 HomeLayout 父路由下,導致系統(tǒng)中存在多個獨立的 Layout 組件,路由匹配混亂,子頁面無法嵌入主布局,最終 fallback 到我寫的首頁內容。

修復方案:將動態(tài)路由掛載到已有的 HomeLayout 父路由下(通過父路由 name 掛載):

// 正確寫法 ?
router.addRoute('HomeLayout', {
  path: routePath,
  name: routePath.replace(/\//g, '-'),
  component: () => import(...),
  meta: child.meta
})

第三步:檢查組件路徑拼接(核心坑 2)

修復路由掛載方式后,問題依然存在,打開控制臺發(fā)現(xiàn) Vite 報錯:

[plugin:vite:vue] src/views/views/space/rocket.vue At least one <template> or <script> is required

問題原因:組件路徑拼接錯誤,使用相對路徑導致路徑重復:

// 錯誤寫法 ?
const importPath = `../views${child.path}.vue`
// child.path = '/space/rocket'
// 最終解析結果:../views/space/rocket.vue → 實際路徑為 src/views/views/space/rocket.vue(重復 views)

修復方案:使用項目根目錄絕對路徑,避免路徑解析錯誤:

// 正確寫法 ?
const importPath = `/src/views${child.path}.vue`

第四步:檢查 Vite 動態(tài) import 別名解析(核心坑 3)

嘗試使用項目中常用的 @ 別名簡化路徑,發(fā)現(xiàn)動態(tài) import 中別名無法生效:

// 錯誤寫法 ? Vite 無法解析動態(tài)路徑中的 @ 別名
import(`@/views${child.path}.vue`)

// 正確寫法 ? 使用絕對路徑
import(`/src/views${child.path}.vue`)

問題原因:Vite 的別名解析的在靜態(tài) import 中能正常工作,但在動態(tài) import 中,由于路徑是動態(tài)拼接的,無法被 Vite 靜態(tài)分析,導致別名解析失敗,組件加載失敗,最終顯示我寫的首頁內容。

解決方案:動態(tài) import 一律使用絕對路徑 /src/views/xxx,放棄 @ 別名。

第五步:檢查登錄后動態(tài)路由重新加載(核心坑 4)

修復路徑問題后,頁面依然不切換,控制臺出現(xiàn) 401 錯誤:

401 Unauthorized - 請求菜單數據被拒絕

問題原因:動態(tài)路由最初在應用啟動時就加載,但此時用戶尚未登錄,沒有 Token,請求后端菜單接口被拒絕,導致動態(tài)路由未成功注冊,路由匹配時只能匹配到我寫的首頁內容。

修復方案:在登錄成功后,拿到 Token 再重新初始化加載動態(tài)路由:

// Login.vue 登錄邏輯(關鍵代碼)
const handleLogin = async () => {
  try {
    await loginFormRef.value.validate()
    loading.value = true

    // 調用登錄接口
    const response = await axios.post('http://localhost:3000/api/auth/login', {
      username: loginForm.username,
      password: loginForm.password
    })

    if (response.data.code === 200) {
      // 登錄成功,保存用戶信息到 store
      userStore.login(response.data.data)
      
      // 設置 axios 默認請求頭(攜帶 Token)
      axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.data.token}`
      
      // 關鍵:登錄后重新加載動態(tài)路由
      await initDynamicRoutes(router)
      
      ElMessage.success(response.data.message)
      router.push('/')
    } else {
      ElMessage.error(response.data.message)
    }
  } catch (error) {
    console.error('登錄失敗:', error)
    const message = error.response?.data?.message || '登錄失敗,請重試'
    ElMessage.error(message)
  } finally {
    loading.value = false
  }
}

第六步:清理不存在的頁面(隱性坑)

最后,排查發(fā)現(xiàn)后端返回的菜單數據中,有部分菜單項對應的前端頁面并不存在(例如:空間站、衛(wèi)星等頁面),導致動態(tài) import 加載組件失敗,路由匹配降級到我寫的首頁內容。

修復方案:注釋掉后端菜單中不存在的菜單項,保證后端菜單路徑與前端 views 目錄下的文件一一對應:

// server/routes/menu.js - 注釋掉不存在的頁面
{
  key: '航天器',
  icon: '??',
  children: [
    { name: '運載火箭', path: '/space/rocket', meta: { ... } },
    { name: '載人飛船', path: '/space/spaceship', meta: { ... } },
    // { name: '空間站', path: '/space/station', meta: { ... } }, // 不存在,注釋
    // { name: '衛(wèi)星', path: '/space/satellite', meta: { ... } }, // 不存在,注釋
  ]
}

五、問題總結(一張表看懂所有坑)

問題現(xiàn)象根本原因解決方案
路由跳轉頁面不變,始終顯示我寫的首頁內容動態(tài)路由注冊為頂層路由,重復創(chuàng)建 Layout將動態(tài)路由掛載到父路由 HomeLayout 下
Vite 報錯,組件路徑重復(views/views)相對路徑拼接錯誤,導致路徑解析異常使用 /src/views 絕對路徑拼接組件路徑
動態(tài) import 別名 @ 失效Vite 無法靜態(tài)分析動態(tài)路徑中的別名放棄別名,統(tǒng)一使用絕對路徑導入
加載動態(tài)路由接口 401應用初始化時未登錄,無 Token 無法請求菜單登錄成功后再重新加載動態(tài)路由
組件加載失敗,路由降級到我寫的首頁內容后端菜單與前端實際頁面文件不匹配清理無效菜單項,保持路徑一致

六、最終完整可運行源碼

1. 動態(tài)路由注冊 src/router/dynamicRoutes.js

import axios from 'axios'
import Layout from '@/layout/index.vue'

export async function initDynamicRoutes(router) {
  console.log('?? 開始加載動態(tài)路由...')
  
  try {
    const token = localStorage.getItem('token')
    console.log('?? token:', token ? '存在' : '不存在')
    
    if (token) {
      axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
    }

    console.log('?? 正在請求菜單數據...')
    const res = await axios.get('http://localhost:3000/api/menu/list')
    const menuList = res.data.data
    console.log('?? 獲取到菜單數據:', JSON.stringify(menuList, null, 2))

    let count = 0
    menuList.forEach(group => {
      group.children.forEach(child => {
        if (child.path === '/') return

        // 組件路徑:絕對路徑,避免解析錯誤
        const importPath = `/src/views${child.path}.vue`
        console.log('?? 組件路徑:', importPath)

        // 路由路徑(移除開頭的 /,避免路由層級錯誤)
        const routePath = child.path.startsWith('/') ? child.path.slice(1) : child.path
        console.log('??? 路由路徑:', routePath)

        // 注冊動態(tài)路由(掛載到 HomeLayout 父路由下)
        router.addRoute('HomeLayout', {
          path: routePath,
          name: routePath.replace(/\//g, '-'), // 路由 name 去斜杠,避免沖突
          component: () => import(/* @vite-ignore */ importPath).catch(() => {
            console.warn(`?? 組件不存在: ${importPath}`)
            return import('/src/views/Home.vue') // 降級到我寫的首頁內容
          }),
          meta: child.meta // 繼承菜單的權限元信息
        })

        count++
        console.log(`? 已注冊路由 ${count}:`, routePath)
      })
    })

    const allRoutes = router.getRoutes()
    console.log('?? 所有注冊的路由:', allRoutes.map(r => ({ path: r.path, name: r.name, parentName: r.parentName })))
    console.log('? 所有動態(tài)路由加載完成,共注冊', count, '個路由')
    
  } catch (err) {
    console.error('? 路由加載失敗', err.message || err)
    if (err.response?.status === 401) {
      // 401 清除 Token,跳轉登錄頁
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
    }
  }
}

2. 登錄頁完整代碼 Login.vue

<template>
  <div class="login-container">
    <div class="login-form">
      <h2 class="login-title">航天管理系統(tǒng)</h2>
      <el-form
        ref="loginFormRef"
        :model="loginForm"
        :rules="loginRules"
        label-width="0px"
        class="login-form-content"
      >
        <el-form-item prop="username">
          <el-input
            v-model="loginForm.username"
            placeholder="請輸入用戶名"
            size="large"
            prefix-icon="User"
          />
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            v-model="loginForm.password"
            type="password"
            placeholder="請輸入密碼"
            size="large"
            prefix-icon="Lock"
          />
        </el-form-item>
        <el-form-item prop="role">
          <el-select
            v-model="loginForm.role"
            placeholder="選擇角色"
            size="large"
            style="width: 100%"
          >
            <el-option label="普通用戶" value="user" />
            <el-option label="管理員" value="admin" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            size="large"
            style="width: 100%"
            :loading="loading"
            @click="handleLogin"
          >
            登錄
          </el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/index.js'
import { initDynamicRoutes } from '@/router/dynamicRoutes.js'
import axios from 'axios'

const router = useRouter()
const userStore = useUserStore()

const loginFormRef = ref()
const loading = ref(false)

const loginForm = reactive({
  username: '',
  password: '',
  role: ''
})

const loginRules = {
  username: [
    { required: true, message: '請輸入用戶名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '請輸入密碼', trigger: 'blur' }
  ],
  role: [
    { required: true, message: '請選擇角色', trigger: 'change' }
  ]
}

const handleLogin = async () => {
  try {
    await loginFormRef.value.validate()
    loading.value = true

    // 調用真實的登錄API
    const response = await axios.post('http://localhost:3000/api/auth/login', {
      username: loginForm.username,
      password: loginForm.password
    })
    
    console.log('=== 登錄返回數據 ===')
    console.log('完整響應:', response.data)
    console.log('用戶數據:', response.data.data)
    
    if (response.data.code === 200) {
      // 登錄成功,保存用戶信息到store
      userStore.login(response.data.data)
      
      // 設置axios默認header(攜帶Token)
      axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.data.token}`
      
      // 關鍵:重新加載動態(tài)路由
      await initDynamicRoutes(router)
      
      ElMessage.success(response.data.message)
      router.push('/')
    } else {
      ElMessage.error(response.data.message)
    }
  } catch (error) {
    console.error('登錄失敗:', error)
    const message = error.response?.data?.message || '登錄失敗,請重試'
    ElMessage.error(message)
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
.login-container {
  min-height: 100vh;
  background: linear-gradient(135deg, rgba(8, 19, 47, 0.85), rgba(2, 12, 31, 0.65)), url('/images/1.jpeg') no-repeat center center;
  background-size: cover;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 24px;
}

.login-container::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at top left, rgba(255, 255, 255, 0.14), transparent 30%), radial-gradient(circle at bottom right, rgba(255, 255, 255, 0.08), transparent 25%);
  z-index: 1;
}

.login-form {
  position: relative;
  z-index: 2;
  width: 360px;
  max-width: 100%;
  padding: 12px 38px 22px 38px;
  background: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(16px);
  border-radius: 24px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 28px 90px rgba(0, 0, 0, 0.22);
}

.login-title {
  text-align: center;
  margin-bottom: 23px;
  color: #1f2a3c;
  font-size: 26px;
  font-weight: 700;
}

.login-form-content {
  max-width: 100%;
}

.el-form-item {
  margin-bottom: 18px;
}

.el-input__inner,
.el-select .el-input__inner {
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid rgba(31, 42, 60, 0.16);
  border-radius: 10px;
  box-shadow: inset 0 1px 2px rgba(31, 42, 60, 0.06);
}

.el-input__inner:focus,
.el-select .el-input__inner:focus {
  border-color: #409eff;
}

.el-input__inner:hover,
.el-select .el-input__inner:hover {
  border-color: rgba(31, 42, 60, 0.24);
}

.el-button {
  border-radius: 10px;
  font-weight: 600;
  background: #409eff;
  border-color: #409eff;
}

.el-button:hover {
  background: #3a8de0;
}
</style>

3. 后端菜單接口 server/routes/menu.js

// server/routes/menu.js - 菜單路由相關
const Router = require('koa-router')

const router = new Router()

// 完整的菜單數據
const allMenus = [
  {
    key: '首頁',
    icon: '??',
    children: [
      { name: '首頁', path: '/', meta: { title: '首頁', requiresAuth: false } }
    ]
  },
  {
    key: '航天器',
    icon: '??',
    children: [
      { name: '運載火箭', path: '/space/rocket', meta: { title: '運載火箭', requiresAuth: true, roles: ['user', 'admin'] } },
      { name: '載人飛船', path: '/space/spaceship', meta: { title: '載人飛船', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '空間站', path: '/space/station', meta: { title: '空間站', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '衛(wèi)星', path: '/space/satellite', meta: { title: '衛(wèi)星', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '探測器', path: '/space/probe', meta: { title: '深空探測器', requiresAuth: true, roles: ['user', 'admin'] } }
    ]
  },
  {
    key: '發(fā)射任務',
    icon: '??',
    children: [
      { name: '任務規(guī)劃', path: '/mission/plan', meta: { title: '任務規(guī)劃', requiresAuth: true, roles: ['user', 'admin'] } },
      { name: '發(fā)射記錄', path: '/mission/record', meta: { title: '發(fā)射記錄', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '在軌任務', path: '/mission/orbit', meta: { title: '在軌任務', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '返回任務', path: '/mission/return', meta: { title: '返回任務', requiresAuth: true, roles: ['user', 'admin'] } }
    ]
  },
  {
    key: '測控通信',
    icon: '??',
    children: [
      { name: '地面測控', path: '/tracking/ground', meta: { title: '地面測控', requiresAuth: true, roles: ['user', 'admin'] } },
      { name: '航天測控網', path: '/tracking/network', meta: { title: '航天測控網', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '數據傳輸', path: '/tracking/data', meta: { title: '數據傳輸', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '深空通信', path: '/tracking/deepspace', meta: { title: '深空通信', requiresAuth: true, roles: ['user', 'admin'] } }
    ]
  },
  {
    key: '航天員',
    icon: '?????',
    children: [
      { name: '航天員列表', path: '/astronaut/list', meta: { title: '航天員列表', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '訓練計劃', path: '/astronaut/training', meta: { title: '訓練計劃', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '出艙活動', path: '/astronaut/eva', meta: { title: '出艙活動', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '生活保障', path: '/astronaut/life', meta: { title: '生活保障', requiresAuth: true, roles: ['user', 'admin'] } }
    ]
  },
  {
    key: '科學實驗',
    icon: '??',
    children: [
      { name: '微重力實驗', path: '/experiment/gravity', meta: { title: '微重力實驗', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '生命科學', path: '/experiment/life', meta: { title: '生命科學', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '材料科學', path: '/experiment/material', meta: { title: '材料科學', requiresAuth: true, roles: ['user', 'admin'] } },
      // { name: '天文觀測', path: '/experiment/astronomy', meta: { title: '天文觀測', requiresAuth: true, roles: ['user', 'admin'] } }
    ]
  },
  {
    key: '系統(tǒng)管理',
    icon: '??',
    children: [
      { name: '用戶管理', path: '/system/user', meta: { title: '用戶管理', requiresAuth: true, roles: ['admin'] } },
      { name: '角色管理', path: '/system/role', meta: { title: '角色管理', requiresAuth: true, roles: ['admin'] } },
      { name: '菜單管理', path: '/system/menu', meta: { title: '菜單管理', requiresAuth: true, roles: ['admin'] } },
      // { name: '權限管理', path: '/system/permission', meta: { title: '權限管理', requiresAuth: true, roles: ['admin'] } },
      { name: '崗位管理', path: '/system/position', meta: { title: '崗位管理', requiresAuth: true, roles: ['admin'] } }
    ]
  }
]

// 根據用戶權限動態(tài)返回菜單
router.get('/api/menu/list', async (ctx) => {
  // 從認證中間件獲取用戶信息(需自行實現(xiàn)認證中間件)
  const userRoles = ctx.state.user?.roles || []

  // 過濾菜單:根據用戶角色
  const filteredMenus = allMenus.map(group => {
    const filteredChildren = group.children.filter(child => {
      const meta = child.meta
      // 不需要認證的菜單(如首頁)
      if (!meta.requiresAuth) return true
      // 需要認證但沒有角色限制的菜單
      if (!meta.roles) return false
      // 檢查用戶是否有權限訪問
      return meta.roles.some(role => userRoles.includes(role))
    })

    // 如果分組下有子菜單,則保留分組;否則過濾掉
    return filteredChildren.length > 0 ? {
      ...group,
      children: filteredChildren
    } : null
  }).filter(Boolean)

  ctx.body = {
    code: 200,
    message: 'success',
    data: filteredMenus
  }
})

module.exports = {
  router,
  allMenus
}

七、經驗教訓與避坑要點

  1. 路由結構要統(tǒng)一:所有功能頁面應共享同一個 Layout 組件,動態(tài)路由必須掛載到父路由下,避免重復創(chuàng)建 Layout,導致路由匹配混亂,最終始終顯示我寫的首頁內容。

  2. 動態(tài) import 注意事項:Vite 環(huán)境下,動態(tài) import 無法解析@ 別名,使用絕對路徑 /src/views/xxx 更可靠,避免路徑解析錯誤,防止組件加載失敗后顯示首頁內容。

  3. 權限相關動態(tài)路由:動態(tài)路由依賴用戶 Token 和菜單接口,必須在登錄成功、拿到 Token 后再重新加載,不能在應用初始化時加載,否則動態(tài)路由注冊失敗,會一直顯示我寫的首頁內容。

  4. 數據與文件要同步:后端返回的菜單數據,必須與前端 views 目錄下的實際頁面文件一一對應,避免出現(xiàn)“菜單存在但頁面不存在”的情況,防止組件加載失敗降級到首頁內容。

  5. 排查技巧:遇到“URL 變、頁面不變,始終顯示我寫的首頁內容”的問題,優(yōu)先排查 3 點:① 動態(tài)路由掛載是否正確;② 組件導入路徑是否正確;③ 動態(tài)路由是否成功注冊。

八、結束語

這個看似簡單的“頁面始終顯示我寫的首頁內容”問題,牽扯到路由配置、動態(tài)導入、權限校驗、前后端數據同步等多個層面,也讓我深刻體會到:前端開發(fā)中,細節(jié)決定成敗。

如果你也遇到了類似的動態(tài)路由問題,希望這篇文章能幫你快速定位問題、解決問題,少走彎路。

到此這篇關于Vue3動態(tài)路由踩坑實戰(zhàn)記錄的文章就介紹到這了,更多相關Vue3動態(tài)路由踩坑內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 關于Element-UI中slot的用法及說明

    關于Element-UI中slot的用法及說明

    這篇文章主要介紹了關于Element-UI中slot的用法及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue+Ant Design進行大數據量下拉框卡頓與表單提交優(yōu)化

    Vue+Ant Design進行大數據量下拉框卡頓與表單提交優(yōu)化

    在現(xiàn)代前端開發(fā)中,處理大數據量渲染和表單交互是常見的挑戰(zhàn),本文將探討如何優(yōu)化 Ant Design Vue 下拉框在大數據量情況下的性能問題,并解決表單提交后重復提示的問題,需要的可以了解下
    2025-03-03
  • vite框架下大屏適配方案的幾種實現(xiàn)方法

    vite框架下大屏適配方案的幾種實現(xiàn)方法

    本文主要介紹了vite框架下大屏適配方案小結,包括相對單位適配、媒體查詢適配和縮放適配,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-10-10
  • Vue中的偵聽器及使用場景

    Vue中的偵聽器及使用場景

    Vue中的偵聽器是一種響應式機制,可以對指定的數據進行監(jiān)聽,并在數據變化時執(zhí)行相應的回調函數。常用于監(jiān)聽復雜數據類型的變化,如對象和數組。通過偵聽器,可以實現(xiàn)數據的自動更新和邏輯處理等功能,提高代碼的可讀性和可維護性
    2023-05-05
  • vue 掛載路由到頭部導航的方法

    vue 掛載路由到頭部導航的方法

    本篇文章主要介紹了vue 掛載路由到頭部導航的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • vue項目打包上傳github并制作預覽鏈接(pages)

    vue項目打包上傳github并制作預覽鏈接(pages)

    這篇文章主要介紹了vue項目打包上傳github并制作預覽鏈接(pages)的相關資料,需要的朋友可以參考下
    2019-04-04
  • Vue組件傳值方式(props屬性,父到子,子到父,兄弟傳值)

    Vue組件傳值方式(props屬性,父到子,子到父,兄弟傳值)

    這篇文章主要介紹了Vue組件傳值方式(props屬性,父到子,子到父,兄弟傳值),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • antd vue table跨行合并單元格,并且自定義內容實例

    antd vue table跨行合并單元格,并且自定義內容實例

    這篇文章主要介紹了antd vue table跨行合并單元格,并且自定義內容實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Vue 中使用vue2-highcharts實現(xiàn)top功能的示例

    Vue 中使用vue2-highcharts實現(xiàn)top功能的示例

    下面小編就為大家分享一篇Vue 中使用vue2-highcharts實現(xiàn)top功能的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • 五種Vue實現(xiàn)加減乘除運算的方法總結

    五種Vue實現(xiàn)加減乘除運算的方法總結

    這篇文章主要為大家詳細介紹了五種Vue實現(xiàn)加減乘除運算的方法,文中的示例代碼簡潔易懂,對我們深入了解vue有一定的幫助,需要的可以了解下
    2023-08-08

最新評論

灵宝市| 金堂县| 东乌珠穆沁旗| 青河县| 齐齐哈尔市| 林周县| 绵竹市| 石河子市| 重庆市| 乌什县| 塔河县| 寿阳县| 营山县| 黄石市| 保定市| 屏南县| 桃园市| 四会市| 昌平区| 文成县| 铅山县| 垫江县| 安顺市| 两当县| 武威市| 古田县| 柳林县| 尚志市| 大余县| 连云港市| 宾阳县| 台湾省| 漯河市| 普兰县| 山东| 醴陵市| 潢川县| 翁源县| 来宾市| 长海县| 石棉县|