Vite 安裝router自動生成與設置
Vite版本必須小於Vite6,
安裝router自動生成
1
| npm install -D vue-router vite-plugin-pages vite-plugin-vue-layouts
|
router.ts
在src新增router資料夾,新增router.ts
1 2 3 4 5 6 7 8 9
| import { Router,createRouter, createWebHistory } from 'vue-router' import { setupLayouts } from 'virtual:generated-layouts' import generatedRoutes from 'virtual:generated-pages' const options= { history: createWebHistory(), routes: setupLayouts(generatedRoutes) } const router: Router = createRouter(options); export default router
|
Ssr 專案 router.ts
改為 createMemoryHistory
history: createMemoryHistory(),
1 2 3 4 5 6 7 8 9
| import { Router,createRouter, createMemoryHistory } from 'vue-router' import { setupLayouts } from 'virtual:generated-layouts' import generatedRoutes from 'virtual:generated-pages' const options= { history: createMemoryHistory(), routes: setupLayouts(generatedRoutes) } const router: Router = createRouter(options); export default router
|
錯誤訊息:找不到模組 'virtual:generated-layouts' 或其對應的型別宣告。ts(2307)
處理方式:tsconfig.json檔案內compilerOptions加入以下
1 2 3 4
| "types": [ "vite-plugin-pages/client", "vite-plugin-vue-layouts/client" ]
|
tsconfig.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| { "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ESNext", "DOM"], "skipLibCheck": true,
/* Bundler mode */ "moduleResolution": "node", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve",
/* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "types": [ "vite-plugin-pages/client", "vite-plugin-vue-layouts/client" ] }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], "references": [{ "path": "./tsconfig.node.json" }] }
|
全局設置於main.ts
1 2 3 4 5 6 7 8 9
| import { createApp } from 'vue'
import App from './App.vue' + import router from "./router/router"
+ const app = createApp(App); + app.use(router); + app.mount("#app");
|
全局設置於main.ts
Ssr 專案 全局設置於main.t
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { createSSRApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const pinia = createPinia() + import router from "./router/router.ts"
export function createApp() { const app = createSSRApp(App); app.use(pinia) + app.use(router); return { app } }
|
vite.config.ts 設置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| + import Pages from 'vite-plugin-pages' + import Layouts from 'vite-plugin-vue-layouts' export default defineConfig({ plugins: [ vue(), + Pages({ + dirs: [ + { dir: 'src/views/frontdesk/', baseRoute: '/' },//前台 + // { dir: 'src/views/admin/', baseRoute: 'admin' }, + ] + }), + Layouts(), ] })
|
vite.config.ts 設置
App.vue 新增router-view
1 2 3 4 5
| <template> <main class="main"> <router-view></router-view> </main> </template>
|
設置layouts
新增layouts資料夾內新增
frontLayout.vue,
LayoutBack.vue,
Layout404.vue
layouts資料夾內容
按前後台設置layout:
views/index.vue 內容
前台必須重新導向到/frontdesk/index;
1 2 3 4 5 6 7
| <route lang="yaml"> path: "/", redirect: "/frontdesk/index", meta: layout: frontLayout </route>
|
新增frontdesk資料夾(這是前台的內頁檔案),
新增index.vue,
aboutme.vue;
1 2 3 4
| <route lang="yaml"> meta: layout: frontLayout </route>
|
佈局頁面的製作
src/layouts/內有兩個frontLayout.vue,Layout404.vue
frontLayout.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| //frontLayout.vue <template> <Nav :navLists="navLists" ></Nav> <router-view /> </template>
<script setup lang="ts"> import { ref, onMounted } from 'vue' import Nav from '../components/Nav.vue' interface navListType { id?: number, name?: string, href?: string, } const navLists = ref<navListType[]>([ { id: 0, name: '首頁', href: '/' }, { id: 2, name: '關於', href: '/about' }, ]) </script>
|
Layout404.vue
1 2 3 4 5 6
| <template> <router-view></router-view> </template>
<script setup lang="ts"> </script>
|
404頁面
新增[…all].vue
route lang=”yaml” =>meta:layout: Layout404
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //這個檔案要注意別命名錯誤[...all].vue <template> <main class="flex flex-col items-center space-y-3"> <span class="text-2xl"> 404 </span> <router-link class="text-xl border p-1" to="/">回首頁</router-link> </main> </template> <route lang="yaml"> meta: layout: Layout404 </route>
|
動態router
新增user資料夾與資料夾內新增[id].vue
例如:edit[id].vue,
獲取動態id => route.params.id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> {{title}} </div> </template>
<route> { path: '/user/:id', name: 'User', meta: { layout: 'frontLayout', } } </route>
<script setup lang="ts"> import {ref,onMounted} from 'vue' import { useRoute, useRouter } from 'vue-router'; const route = useRoute(); const router = useRouter() const title =ref<string>('ID'); onMounted(() => { const id = route.params.id; console.log('讀取動態參數id',id) }) </script>
|
router params
1 2 3 4 5 6 7 8 9
| <route> { path: '/user/:userId', name: 'User', meta: { layout: 'frontLayout', } } </route>
|
要連結到一個命名的路由,可以傳遞一個物件到 router-link 元件的 to 屬性:
1 2 3
| <router-link :to="{ name: 'User', params: { userId: 'erina' }}"> User </router-link>
|
這跟程式碼呼叫 router.push() 是一樣:
1
| router.push({ name: 'user', params: { userId: 'erina' } })
|
router 重定向
1 2 3 4 5 6 7 8 9 10 11
| <route> { path: '/user/:userId', name: 'User', redirect: '/' //redirect: { name: 'homepage' } meta: { layout: 'frontLayout', } } </route>
|
Vercel 404錯誤
Vercel 平台出現404頁面無法導到正確位置
新增vercel.json在根目錄 加入以下代碼
1 2 3 4 5 6
| vercel.json { "rewrites": [ {"source": "/(.*)", "destination": "/"} ] }
|
參考資料:
Vite Vecel 404
github