vue3 快速入門系列 —— vue3 路由

来源:https://www.cnblogs.com/pengjiali/p/18123646
-Advertisement-
Play Games

vue3 快速入門系列 - vue3 路由 在vue3 基礎上加入路由。 vue3 需要使用 vue-router V4,相對於 v3,大部分的 Vue Router API 都沒有變化。 Tip:不瞭解路由的同學可以看一下筆者之前的文章:vue2 路由 參考:vue2 路由官網、vue3 路由官網 ...


vue3 快速入門系列 - vue3 路由

vue3 基礎上加入路由。

vue3 需要使用 vue-router V4,相對於 v3,大部分的 Vue Router API 都沒有變化。

Tip:不瞭解路由的同學可以看一下筆者之前的文章:vue2 路由

參考:vue2 路由官網vue3 路由官網

vue-router V4

在 Vue Router API 從 v3(Vue2)到 v4(Vue3)的重寫過程中,大部分的 Vue Router API 都沒有變化,但是在遷移你的程式時,你可能會遇到一些破壞性的變化 —— 從 Vue2 遷移

vue3 需要使用 vue-router 4.x.x 版本。安裝:

PS hello_vue3> npm i vue-router

changed 37 packages, and audited 69 packages in 3s

8 packages are looking for funding
  run `npm fund` for details

1 moderate severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

版本:

"dependencies": {
    "vue": "^3.4.15",
    "vue-router": "^4.3.0"
  },

第一個示例

在vue3項目中加入路由。

步驟如下:

  • 創建路由 src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

// new Router 變成 createRouter
const router = createRouter({
  // mode: 'history' 配置已經被一個更靈活的 history 配置所取代
  // 必填。否則報錯:Uncaught Error: Provide the "history" option when calling "createRouter()"
  history: createWebHistory(),
  routes
})

export default router

Tip:new Router 變成 createRouter 來創建路由;其中模式需要通過調用方法創建,必填

  • 創建兩個組件
<template>
  <div>
    <h1>About</h1>
    // 可以通過設置router-link-active類來為被選中的路由添加樣式
    <router-link to="/">to Home</router-link>
  </div>
</template>
<template>
  <div>
    <h1>Home</h1>
    <router-link to="/about">to About</router-link>
  </div>
</template>
  • App.vue 中引入 <router-view> 告訴 Vue Router 在哪裡渲染匹配到的組件。
<template>
  <router-view></router-view>
</template>

<script lang="ts" setup name="App">

</script>
  • main.ts 通過 use 使用路由
import {createApp} from 'vue'
import App from './App.vue'
// 會自動載入 ./router/index.ts
import router from './router'

createApp(App)
// 將 Vue Router 插件安裝到 Vue 實例中,以便在整個應用程式中使用 Vue Router 的功能
// Vue.use(MyPlugin) - 調用 `MyPlugin.install(Vue)`
.use(router)
.mount('#app')

接著就可以通過瀏覽器體驗:

Home
// 點擊,調整到 about 路由
to About
About
// 點擊,調整到 home 路由
to Home

Tip: 通過 .use(router) 在 vue 開發者工具中就會看到路由tab

命名路由

Tip: vue2 路由 -> 命名路由

路徑有時太麻煩,可以使用命名路由替代。

例如將 About 從路徑改為名稱跳轉。核心代碼如下:

// 定義 name
{ path: '/about', component: About, name: 'guanyu' },

// 跳轉
:to="{name: 'guangyu'}"

Tip:to 目前有2種寫法,感覺字元串方式很痛快,對象還需要寫好多,但是到子路由或傳遞參數,會發現還是對象好用。

// 傳遞字元串 - 理解為目標路由的路徑
to="/"
// 傳遞對象
:to="{path: '/'}"
:to="{name: 'guangyu'}"

嵌套路由

Tip:和 vue2 中路由用法相同,詳情請看:vue2 路由 -> 嵌套路由

新建一個 Article 組件,裡面定義一個 router-view。請看示例:

  • Article.vue
<template>
    <div>
        <h1>Article</h1>
        // path 需要將一級路由路徑加上,例如 /article,不能只寫 detail。該 name 也方便。
        // query 效果:http://localhost:5173/article/detail?id=1
        <router-link :to="{ path: '/article/detail', query: { id: 1 } }">文章 id1 詳情</router-link><br>
        <router-link :to="{ path: '/article/detail', query: { id: 2 } }">文章 id2 詳情</router-link><br>
        // 註:將對象換成字元串,效果相同
        <router-link to="/article/detail?id=3">文章 id3 詳情</router-link><br>
        <router-view></router-view>
    </div>
</template>

<script lang="ts" setup name="App">
// 可以不引入
// import {RouterView,RouterLink} from 'vue-router'
</script>

Tip:可以不引入 import {RouterView,RouterLink} from 'vue-router'

  • Detail.vue
<template>
    <div>
        <h1>文章id: {{ $route.query.id }}</h1>
    </div>
</template>
  • 增加路由和子路由。子路由的 path 無需增加 /
const routes = [
  { path: '/home', component: Home,},
  {
    path: '/article',
    component: Article,
    children: [
      {
        path: 'detail',
        component: Detail
      }
    ]
  },
]
  • Home.vue 增加Article入口
<router-link :to="{name: 'guanyu'}">About</router-link>
<br>
<router-link :to="{path: '/article'}">Article</router-link>

測試:進入Home,點擊 Article,點擊 文章 id1 詳情,顯示 文章id: 1,測試通過。

路由 query 參數

在”嵌套路由“中我們是這樣取得 query 參數:<h1>文章id: {{ $route.query.id }}</h1>

js 中通過 useRoute hooks 取得 $route。請看示例:

<template>
    <div>
        <h1>文章id: {{ $route.query.id }}</h1>
        <h1>文章id: {{ query.id }}</h1>
    </div>
</template>

<script lang="ts" setup name="App">
import {toRefs} from 'vue'
// 返回當前的路由地址。相當於在模板中使用 $route。
// useRouter 返迴路由器實例。相當於在模板中使用 $router
import {useRoute} from 'vue-router'

const route = useRoute()

// route: Proxy
console.log('route: ', route);

// 錯誤:解構需要用到 toRefs,否則頁面不會更新
// const {query} = route

// 正確:解構
const {query} = toRefs(route)

</script>

Tip:如果需要解構,需使用 toRefs。若想將 query.id 中的 query 去掉,可以使用後面章節的 路由 props 屬性,代碼將更優雅

路由 params 參數

Tip:請看 vue2 路由 -> $route.params

將上節 query 參數示例改成 params。

  • params需要增加占位符,比如:id
{
    path: '/article',
    component: Article,
    children: [
      {
        name: 'xiangxi',
        path: 'detail/:id',
        component: Detail
      }
    ]
},
  • id傳遞方式調整一下,不用 query 那種方式:
<router-link to="/article/detail/4">文章 id4 詳情</router-link><br>
  • 接收 id
<h1>文章id: {{ $route.params.id }}</h1>

:params 不能傳數組或對象;/a/:b/:c,則你必須傳 /a/1/2,如果傳 /a/1 則報錯,如果有時沒有c 可傳,可以改成 /a/:b/:c?

對象形式

將 to 改成對象形式:

 <router-link :to="{
    path: '/article/detail/4',
    params: {
        id: 5
    }
}">文章 id5 詳情</router-link><br>

瀏覽器報錯更容易理解,說 path 被忽略:

// vscode 報錯:
對象字面量只能指定已知屬性,並且“params”不在類型“RouteLocationPathRaw”中。

// 瀏覽器報錯
[Vue Router warn]: Path "/article/detail/4" was passed with params but they will be ignored. Use a named route alongside params instead.

將 path 改成 name即可:

<router-link :to="{
    // path: '/article/detail/4',
    name: 'xiangxi',
    params: {
        id: 5
    }
}">文章 id5 詳情</router-link><br>

路由 props 屬性

不就是想接收 params 或 query 傳來的參數的,還得寫這麼一大塊代碼,太麻煩:

<template>
    <div>
        <h1>文章id: {{ query.id }}</h1>
    </div>
</template>

<script lang="ts" setup name="App">
import {toRefs} from 'vue'
import {useRoute} from 'vue-router'

const route = useRoute()
const {query} = toRefs(route)
</script>

可以通過 props 解決。細節如下:

props 布爾

  • 定義 props
{
    name: 'xiangxi',
    path: 'detail/:id',
    component: Detail,
    // 通過 props 屬性來將路由參數傳遞給組件
    // 底層好些這樣:<Detail id=5/>
    props: true
}
  • 直接通過 defineProps 接收
<template>
    <div>
        <h1>文章id: {{id }}</h1>
    </div>
</template>

<script lang="ts" setup name="App">
    defineProps(['id'])
</script>

props 函數

如果需要接收 query,需要用 props 函數,參數是 route,返回需要接收的對象:

// RouteLocationNormalized 是 Vue Router 中的一個類型,它用於描述路由的位置信息
import { type RouteLocationNormalized } from 'vue-router';

{
    name: 'xiangxi',
    path: 'detail',
    component: Detail,
    // 通過 props 屬性來將路由參數傳遞給組件
    // props: true
    props(route: RouteLocationNormalized ) {
        return route.query
    }
}
  • 觸發路由從 params 改成 query:
<router-link :to="{
    name: 'xiangxi',
    query: {
        id: 5
    }
}">文章 id5 詳情</router-link><br>
  • 接收方式不變:
<template>
    <div>
        <h1>文章id: {{id }}</h1>
    </div>
</template>

<script lang="ts" setup name="App">
    defineProps(['id'])
</script>

Tip:其實 props: true 就相當於下麵這段代碼:

props(route: RouteLocationNormalized ) {
    return route.params
}

props 對象

props 還可以寫成對象,但用得較少:

props: {
    id: 100
}

replace

HTML5的歷史API包含了pushState(),replaceState()和popstate事件

路由預設是 push。比如啟動第一個示例,未點擊 home 或 about 導航時,瀏覽器左上方既不能前進也不能後退,因為棧中只有當前頁面,指針沒地方去。在你點擊home和about導航後,就可以前進和後退,即使刷新頁面,這個歷史記錄也不會變。

<router-link :to="{name: 'guanyu'}">About</router-link>
<br>
<router-link :to="{path: '/article'}">Article</router-link>

vue-router 的 replace 作用和用法和 react replace 相同。

現在點 About 就會直接替換

<router-link replace :to="{name: 'guanyu'}">About</router-link>

編程式導航

Tipvue2 路由 -> 編程式導航

三秒後跳轉到 article:

<script lang="ts" setup name="App">
import { useRouter } from 'vue-router'
const router = useRouter()

type Path = string

// 說vue2 中編程式導航重覆跳轉會報錯,vue3中沒這個問題
function to(path: Path){
  router.push(path)
}
setTimeout(() => {
  to('/article')
}, 3000)
</script>

編程式導航使用頻率大於聲明式導航(<router-link :to="...">

to也支持對象,和聲明式導航用法相同,更多介紹請看:vuer-router v4 編程式導航

其他

路由組件和一般組件

路由組件通常放在 pages 或 views 文件夾中,一般組件通常放在 components 文件夾中 —— 一般開源的項目都會這樣分類

看一個組件是哪種,需要看其如何用。比如定義一個 Demo.vue,如果通過標簽 <Demo/> 這種寫法來使用,就屬於一般組件,如果該組件通過路由渲染,則稱為路由組件。

卸載和掛載

通過導航,視覺上消失的路由組件,預設被卸載,需要用的時候在掛載。

第一個示例 中給 About.vue 增加兩個生命周期鉤子,再次切換 Home 和 About 組件,就能看到效果:

<template>
  <div>
    <h1>About</h1>
    <router-link to="/">Home</router-link>
  </div>
</template>

<script lang="ts" setup name="App">
import {onMounted, onUnmounted} from 'vue'
onMounted(() => {
  console.log('About 掛載了');
})
onUnmounted(() => {
  console.log('About 卸載了');
})
</script>

路由模式

history 模式 url 美觀,後期上線,需要服務端配合處理路徑問題,否則刷新會有404。當用戶在瀏覽器中直接訪問一個路由,或者刷新頁面時,如果伺服器端沒有正確配置,可能會導致 404 錯誤,因為此時伺服器會嘗試去尋找對應的文件或路由路徑,而實際上這個路徑是由前端控制的,並不一定存在於伺服器端的文件系統中。為瞭解決這個問題,你需要在伺服器端配置一個通配符路由,將所有的路由請求都指向你的應用的入口文件(比如 index.html),這樣就會確保 Vue Router 能夠正確地處理路由請求。

如果你使用的是 Node.js 伺服器,可以使用 Express 框架來進行配置,示例代碼如下所示:

const express = require('express');
const path = require('path');
const app = express();

// 靜態資源目錄,例如你的 CSS、JavaScript 文件等
app.use(express.static(path.join(__dirname, 'public')));

// 通配符路由,將所有的路由請求都指向 index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// 啟動伺服器,監聽埠
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

這樣配置後,無論用戶訪問哪個路由,伺服器都會返回 index.html,然後 Vue Router 就可以根據路由配置來正確地渲染相應的組件,避免了刷新頁面時出現的 404 錯誤。

Hash 模式在 SEO 優化方面相對較差。

  • 比如不利於搜索引擎爬蟲:Hash 模式下,URL 中的哈希部分(#後面的內容)不會被包含在 HTTP 請求中,因此在伺服器接收請求時,哈希部分對於伺服器來說是不可見的。這意味著搜索引擎爬蟲無法直接獲取到 URL 中的實際內容,因為爬蟲主要是通過 HTTP 請求獲取頁面內容的,所以無法獲取到 hash 後面的內容,這樣就會導致搜索引擎無法正確地索引和解析頁面。

雖然使用 history 模式相對於 hash 模式在 SEO 優化方面有所改善,但它仍然是單頁應用(SPA),可以和服務端渲染結合

沒有匹配到指定的路徑 /

配置如下路由,第一次打開,瀏覽器控制台有警告:main.ts:9 [Vue Router warn]: No match found for location with path "/"

const routes = [
  { path: '/home', component: Home },
  { path: '/about', component: About, name: 'guanyu' }
]

可以通過重定向解決。就像這樣:

const routes = [
  { path: '/', redirect: '/home'},
  { path: '/home', component: Home,},
作者:彭加李
出處:https://www.cnblogs.com/pengjiali/p/18123646
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • @目錄前言簡介一、準備工作1.1 創建寫入腳本1.2 設置執行許可權1.3 添加定時任務1.4 配置生效二、Tomcat日誌 按每天分割2.1 創建一個 sh文件2.2 設置執行許可權2.3 設置crontab指令,指定每日定時任務2.4 配置生效總結 前言 請各大網友尊重本人原創知識分享,謹記本人博客 ...
  • Android Compose 入門,深入底層源碼分析 我是跟著AS官網學習的,但是官方的教程寫的不是很詳細.官網鏈接 首先創建一個Compose項目,目錄結構是這樣: ui -> theme -> -> Color.kt -> -> Theme.kt -> -> Type.kt MainActiv ...
  • 一、Popup Popup組件通常用於在屏幕上彈出一個對話框或者浮動視窗。這個組件通常和其他組件一起用於用戶界面的交互和反饋。 Popup組件可以包含任何類型的組件或內容,比如文本、按鈕、輸入框、圖片等等。在打開和關閉Popup時,可以在代碼中設置不同的動畫效果來增強用戶體驗。 Popup組件的 ...
  • 一、Video 視頻組件是用於應用程式中嵌入視頻的一種方法。它可以讓用戶在網站上觀看視頻並與其進行交互。通常,視頻組件將一個視頻文件嵌入應用程式中,並提供一組控制項,這些控制項允許用戶播放、暫停、跳過、音量調整和全屏等。通過使用視頻組件,開發者可以更容易地將視頻嵌入應用程式,使其更易於管理和控制。 ...
  • 在我之前的文章中講了vue文件是如何編譯成js文件,今天這篇文章接著來講講vue3中是如何將template模塊編譯為render函數的。 ...
  • 本文分享自華為雲社區《3月閱讀周·你不知道的JavaScript | ES6生成器,看似同步的非同步流程式控制製表達風格》,作者: 葉一一。 生成器 打破完整運行 JavaScript開發者在代碼中幾乎普遍依賴的一個假定:一個函數一旦開始執行,就會運行到結束,期間不會有其他代碼能夠打斷它並插入其間。 ES ...
  • XSL(eXtensible Stylesheet Language)是一種用於 XML 的樣式語言。 XSL(T) 語言 XSLT 是一種用於轉換 XML 文檔的語言。 XPath 是一種用於在 XML 文檔中導航的語言。 XQuery 是一種用於查詢 XML 文檔的語言。 它始於 XSL XSL ...
  • 一、前言 演算法(Algorithm)是指用來操作數據、解決程式問題的一組方法。對於同一個問題,使用不同的演算法,也許最終得到的結果是一樣的,但在過程中消耗的資源和時間卻會有很大的區別 衡量不同演算法之間的優劣主要是通過時間和空間兩個維度去考量: 時間維度:是指執行當前演算法所消耗的時間,我們通常用「時間復 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...