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
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...