關於vue路由 這是關於前端的知識 我大致就理解為其為跳轉規則
html中跳轉想一下 jsp跳轉 或者 直接a標籤跳轉
這個為人家規範的跳轉
這是vscode用到一些小外掛
{圖示和idea鍵盤操作 挺不錯的}
當然你需要vue外掛 否則無法識別vue
還有就是node.js的安裝就不說了
首先分為前後端路由
我們主要介紹前端路由
其整個過程發生在瀏覽器端
- Hash模式 url中帶有#
- HTML5模式 就太熟悉了沒有# 直接為路徑
不是吧不是吧 現在還能分不清URL和URI URI是唯一標識
兩者在運用中對應的函式用於指定路由的工作模式
- createWebHashHistory()函式 即Hash模式
- createWebHistory()函式 HTML5模式
後面透過例子還會介紹
用它那是不是就得有它啊 首先就是Vue Router的安裝 哈哈這裡有個坑 一會介紹
首先進入你的專案路徑下
當然vue Router有很多版本 安裝方式也很多 4對應著vue3版本
使用一下命令的時候 你要確保你電腦上有yarn依賴的東西
yarn add vue-router@4 --save
安裝後檢查下啊
哦哦哦再給個小建議 關於註釋的
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
首先匯入的模組依賴 這裡就有個坑
哈哈後面使用的也是這個 是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)
}
導航守衛
可以理解為攔截器吧 就是沒有輸入賬號密碼跳轉登入頁面
- 全域性導航守衛 常用
- 導航獨享守衛 單個路由
- 元件導航守衛
再寫個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()
}
}
)
最後來看下效果