38.Vue路由的簡單學習整理

不爱美女爱辣条發表於2024-04-30

關於vue路由 這是關於前端的知識 我大致就理解為其為跳轉規則

html中跳轉想一下 jsp跳轉 或者 直接a標籤跳轉
這個為人家規範的跳轉

image
這是vscode用到一些小外掛
{圖示和idea鍵盤操作 挺不錯的}
當然你需要vue外掛 否則無法識別vue
還有就是node.js的安裝就不說了


首先分為前後端路由

我們主要介紹前端路由
其整個過程發生在瀏覽器端

  • Hash模式 url中帶有#

image

  • HTML5模式 就太熟悉了沒有# 直接為路徑

不是吧不是吧 現在還能分不清URL和URI URI是唯一標識
兩者在運用中對應的函式用於指定路由的工作模式

  • createWebHashHistory()函式 即Hash模式
  • createWebHistory()函式 HTML5模式
    後面透過例子還會介紹

用它那是不是就得有它啊 首先就是Vue Router的安裝 哈哈這裡有個坑 一會介紹

首先進入你的專案路徑下
image

當然vue Router有很多版本 安裝方式也很多 4對應著vue3版本
使用一下命令的時候 你要確保你電腦上有yarn依賴的東西
yarn add vue-router@4 --save

安裝後檢查下啊

image
哦哦哦再給個小建議 關於註釋的
https://cloud.tencent.com/developer/article/2095044 註釋生效


那現在來看看如何使用

舉個例子 既然要跳轉就起碼有兩個以上的頁面
先說兩個基礎的 一個Home頁面 和一個 About頁面

建立就跳過了 就是簡單顯示個東西
為了顯示在App.vue中顯示

使用 scoped 後,父元件的樣式將不會滲透到子元件中 解決樣式衝突
<template>
  <div class="app-container">
    <h1>App根元件</h1>
    <router-link to="/home">首頁</router-link>
    <router-link to="/about">關於</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>

<script setup>
這個為監聽器
import{watch} from 'vue'
import { useRoute } from 'vue-router';
useRoute()函式用於獲取路由引數 為了後面監聽
const route=useRoute()
watch(()=>route.path,path=>{
  console.log(path);
})
</script>

<style scoped>
.app-container {
  text-align: center;
  font-size: 16px;
}
.app-container a {
  padding: 10px;
  color: #000;
}
.app-container a.router-link-active {
  color: #fff;
  background-color: #000;
}
</style>

使用 scoped 後,父元件的樣式將不會滲透到子元件中 解決樣式衝突
<router-link to="/home">首頁</router-link>
 <router-view></router-view>
 這個就是核心

再插個話題 關於箭頭函式 參考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arrow_functions


然後就需要配置相關的跳轉 在router.js中配置

import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
    history: createWebHashHistory(),
	這裡有兩種跳轉方式 第一種不寫了 因為大部分為第二種懶載入的方式
    routes: [
	主頁面  路由重定向
        { path: '/', redirect: '/home' },
        { path: '/home', component: () => import('./components/路由/Home.vue') },
        {
            path: '/about', component: () => import('./components/路由/About.vue')
    ]
})


匯出路由例項物件
export default router

首先匯入的模組依賴 這裡就有個坑
image
哈哈後面使用的也是這個 是useRouter不是Route
參考 https://blog.csdn.net/m54584mnkj/article/details/122853884 useRoute()和useRouter()區別


在main.js中匯入並掛載路由模組

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
匯入路由模組
import router from './router.js'
const app = createApp(App);  
掛載路由模組
app.use(router);  
app.mount('#app');

這裡也有個坑
createApp(App).mount('#app')
createApp(App).use(router) 錯誤只能建立一個vue應用例項
這是我之前寫的 錯誤錯誤

效果先不看很簡單 對比下面看個綜合的


巢狀路由 需要用到children屬性定義子路由匹配規則

我們向About中套兩個新頁面

例如

<template>
<div>table1元件</div>
</template>
<style scoped>
div{
    text-align: left;
    background-color: antiquewhite;
}
</style>
 <template>
  <div class="about-container">
    <h3>About元件</h3>
	主要多了這兩個 類似App.vue中顯示Home和About一樣
    <router-link to="/about/one">table1</router-link>
    <router-link to="/about/two">table2</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>
<style scoped>
.about-container {
  min-height: 150px;
  background-color: #f2f2f2;
  padding: 15px;
}
.about-container a {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 5px 10px;
  color: #000;
  margin: 0 5px;
}
.about-container a.router-link-active {
  color: #000;
  background-color: #deebf6;
}
</style> 

路徑寫完了需要配置下
在router.js中

 {
            path: '/about', component: () => import('./components/路由/About.vue'),
            children: [
                { path: 'one', component: () => import('./components/路由/Table1.vue') },
                { path: 'two', component: () => import('./components/路由/Table2.vue') }
            ]
        },

動態路由

路徑上帶有引數值
在App.vue中再來個跳轉

    <router-link to="/movie">電影</router-link>
<template>
      <div class="about-container">
    <h3>Movies元件</h3>
    <router-link to="/movie/1">電影1</router-link>
    <router-link to="/movie/2">電影2</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>
<style scoped>
.about-container {
  min-height: 150px;
  background-color: #f2f2f2;
  padding: 15px;
}
.about-container a {
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 5px 10px;
  color: #000;
  margin: 0 5px;
}
.about-container a.router-link-active {
  color: #000;
  background-color: #deebf6;
}
</style> 

這次不用單獨去寫兩個電影 1 2 頁面 而是寫一個頁面
關於獲取引數值
兩種方式
- {{ $route.params.id }}
- props獲取路由引數值
<template>
     <!-- <p>電影{{ $route.params.id }}頁面</p> -->
          <p>電影{{ id }}頁面</p>
          <br>
</template>
<script setup>
const props=defineProps({
    id:String
})
</script>

別忘記在router.js中配置

記得開啟props傳參
 {
            path: '/movie',
            component: () => import('./components/路由/Movies.vue'),
            children: [
                { path: ':id', name: 'MoviesCCC', component: () => import('./components/路由/MoviesCCC.vue'), props: true }
            ]
        }

:id 屬性繫結語法
這裡也有個坑就是我將

{ path: ':id', component: () => import('./components/路由/MoviesCCC.vue'), props: true }

寫在了外面
.vue-router.js?v=8a787c14:954 Uncaught Error: Route paths should start with a "/": ":id" should be "/:id".
:id 要加/ (命名路由)
那時候要加上/


命名路由

使用name屬性定義路由名稱
name屬性值不能重複 是唯一的

動態繫結to屬性
要使用v-bind指令進行繫結
假如在Home頁面跳轉到電影頁面並且攜帶引數

這裡有個小坑 注意下 就是"" 裡面要是''單引號
    <router-link :to="{ name: 'MoviesCCC', params: { id: 2 } }">跳轉到MoviesCCC2</router-link>

要在router.js中修改

加上name屬性
                { path: ':id', name: 'MoviesCCC', component: () => import('./components/路由/MoviesCCC.vue'), props: true }


程式設計式導航

兩種導航方式

  • 宣告式導航
 <router-link></router-link>
  • 程式設計式導航
    先使用useRouter()函式獲取全域性路由例項 常用方法push() go() replace()

  • push()

向歷史記錄新增一個新的記錄 以程式設計方式導航到一個新的URL 若在引數物件中提供了path則params會被忽略 需要使用name屬性或者手動拼接帶有引數的path
例如在Home中新增

a標籤預設有自己的href屬性 觸發a標籤後他會自動跳轉對應的連結地址或執行的函式
此處為了巢狀 避免調整樣式所以引用了a標籤來處理 但又為了避免a標籤的屬性限制
因此引用了@click.prevent函式阻隔預設的操作

    <a href="#" @click.prevent="pushgo(1)">跳轉到MoviesCCC1</a>
	<script setup>
import { useRouter } from 'vue-router';
先使用useRouter()函式獲取全域性路由例項
const router = useRouter()
const pushgo = go_id => {
  router.push({
    name: 'MoviesCCC',
    params: { id: go_id }
  })
}
</script>
  • replace()

與push()方法類似 區別在於後者不會向歷史記錄新增新的記錄而是替換

  • go()

用於實現前進後退效果 類似js中window.history.go() 相應的位址列也會改變
go(1) 前進一條 go(-1)後退一條
具體看下例子

          <button @click="goback">後退</button>
import { useRouter } from 'vue-router';
const router=useRouter()
const goback=()=>{
    router.go(-1)
}

導航守衛

可以理解為攔截器吧 就是沒有輸入賬號密碼跳轉登入頁面

  1. 全域性導航守衛 常用
  2. 導航獨享守衛 單個路由
  3. 元件導航守衛
    再寫個login頁面
<template>
    <h1>登入頁面</h1>
</template>

然後再router.js中配置 要在匯出路由例項之前

//全域性導航守衛
三個引數 to目標路由物件 from當前要離開的路由物件 
如果不接受next()函式 則預設執行訪問任何一個路由 若呼叫 則需要呼叫next()函式

next()執行下一個鉤子函式
next(false)強制停留在當前頁面
next('/')跳轉到其他地址

router.beforeEach((to, from, next) => {
    let flag = false
    if (to.name == 'MoviesCCC') {
        if (flag) {
            next()
        } else {
            next({ name: 'Login' })
        }
    } else {
        next()
    }

}
)

最後來看下效果

image
image
image
image
image

相關文章