Vue路由
- Vue路由基礎
- 嵌套路由
- 路由重定向
- 路由傳參
- params形式傳參
- query形式傳參
- params方式與query方式的區別
- 編程式路由
- 利用JS實作路由跳轉
- 通過watch實作路由監聽
- 導航守衛
Vue路由基礎
Vue屬于單頁應用(SPA),即整個應用程式中只有一個html頁面,
在單頁應用中(SPA),由于只是更改DOM來模擬多頁面,所以頁面瀏覽歷史記錄的功能就喪失了,此時,就需要前端路由來實作瀏覽歷史記錄的功能,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
<router-view></router-view>
</div>
<script>
const Home = {
template: '<div>首頁</div>'
}
const News = {
template: '<div>新聞</div>'
}
var router = new VueRouter({
// mode: 'hash',
mode: 'history',
routes: [{
path: '/home',
component: Home
}, {
path: '/news',
component: News
}]
});
var vm = new Vue({
el: '#app',
data: {},
// 將路由添加到Vue中
router,
});
</script>
</body>
</html>
效果截圖:
點擊home時:

點擊new時:

嵌套路由
實際應用界面,通常由多層嵌套的組件組合而成, 比如,我們 “新聞”組件中,還嵌套著 “國內”和 “國際”組件,那么URL對應就是/news/guonei和/news/guoji,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<!-- 使用 router-link 組件來導航. to屬性指定導航地址-->
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
</p>
<!-- 路由出口(路由匹配到的組件將渲染在這里) -->
<router-view></router-view>
</div>
<script>
// 1. 定義(路由)組件,
const Home = {
template: `<div>首頁</div>`
}
const News = {
template: `<div>
<p>
<router-link to="/news/guonei">國內新聞</router-link>
<router-link to="/news/guoji">國際新聞</router-link>
</p>
<router-view></router-view>
</div>`
}
const GuoNeiNews = {
template: `<div>這里顯示國內新聞</div>`
}
const GuoJiNews = {
template: `<div>這里顯示國際新聞,,,,</div>`
}
// 2. 定義路由規則物件(每個路由應該映射一個組件)
const routes = [{
path: '/home',
component: Home,
}, {
path: '/news',
component: News,
children: [{
path: '/news/guonei',
component: GuoNeiNews
}, {
path: '/news/guoji',
component: GuoJiNews
}
]
},
]
// 3. 創建 router 實體,然后傳 `routes` 配置
const router = new VueRouter({
//如果路由規則物件名也為routes,那么就可以簡寫為 routes
routes: routes
})
var vm = new Vue({
el: '#app',
data: {},
// 將路由添加到Vue中
router,
});
</script>
</body>
</html>
效果動圖:

路由重定向
路由重定向表示將你原來在轉發串列中發向一臺路由的路徑改成另外一條路徑,也就相當于讓你的資料走另外一條路到服務器,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<!-- 使用 router-link 組件來導航. to屬性指定導航地址-->
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
</p>
<!-- 路由出口(路由匹配到的組件將渲染在這里) -->
<router-view></router-view>
</div>
<script>
// 1. 定義(路由)組件,
const Home = {
template: `<div>首頁</div>`
}
const News = {
template: `<div>
<p>
<router-link to="/news/guonei">國內新聞</router-link>
<router-link to="/news/guoji">國際新聞</router-link>
</p>
<router-view></router-view>
</div>`
}
const GuoNeiNews = {
template: `<div>這里顯示國內新聞</div>`
}
const GuoJiNews = {
template: `<div>這里顯示國際新聞,,,,</div>`
}
// 2. 定義路由規則物件(每個路由應該映射一個組件)
const routes = [
/* {
path:'/',
redirect:'/home'
}, */
{
path: '/',
redirect: {
name: 'MyHome'
}
},
{
path: '/home',
name: 'MyHome',
component: Home,
}, {
path: '/news',
component: News,
children: [{
path: '/news/guonei',
component: GuoNeiNews
}, {
path: '/news/guoji',
component: GuoJiNews
}
]
},
]
// 3. 創建 router 實體,然后傳 `routes` 配置
const router = new VueRouter({
//如果路由規則物件名也為routes,那么就可以簡寫為 routes
routes: routes
})
var vm = new Vue({
el: '#app',
data: {},
// 將路由添加到Vue中
router,
});
</script>
</body>
</html>
當我們訪問
#/時會自動幫我們跳轉到#/home這也就是重定向,
效果截圖:

路由傳參
路由傳參有多種方式,常用的有兩種:params與query,
params形式傳參
注意:
- 使用v-bind系結to屬性,
- to屬性的值是一個json物件,此物件有兩個屬性:name屬性和params屬性,
- name屬性就是要路由的物件,所以,在路由規則串列中,每一個路由規則都應用有一個name值,
- params屬性就是要傳遞的引數,也是一個json物件,
- 組件接收引數時,使用 this.$route.params.引數名 的形式,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<router-link :to="{name:'News',params:{msg:'國內'}}">點擊這里會把國內傳過去</router-link>
</p>
<router-view></router-view>
</div>
<script>
const News = {
data(){
return {
msg:''
}
},
template: `<div> {{msg}}新聞</div>`,
created(){
this.msg = this.$route.params.msg;
console.log(this.$route.params)
}
}
// 2. 定義路由規則物件(每個路由應該映射一個組件)
const routes = [
{
path: '/news',
name: 'News',
component: News,
}
]
// 3. 創建 router 實體,然后傳 `routes` 配置
const router = new VueRouter({
//如果路由規則物件名也為routes,那么就可以簡寫為 routes
routes: routes
})
var vm = new Vue({
el: '#app',
data: {},
// 將路由添加到Vue中
router,
});
</script>
</body>
</html>
效果動圖:

query形式傳參
注意:
- to屬性的值仍然是一個josn物件,但是兩個屬性變了,一個是path,一個是query,
- path屬性就是路由地址,對應路由規則中的path值,
- query屬性就是要傳遞的引數,也是一個json物件,
- 組件接收引數時,使用 this.$route.query.引數名 的形式,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>
<router-link :to="{path:'/home',query:{msg:'hello world!'}}">home</router-link>
<router-link :to="{path:'/news',query:{id:id,name:name}}">news</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首頁內容: {{this.$route.query.msg}} </div>'
}
const News = {
template: `<div>新聞 </br>
引數id:{{this.$route.query.id}}</br>
引數name:{{this.$route.query.name}}
</div>`
}
const routes = [{
path: '/home',
component: Home
}, {
path: '/news',
component: News
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {
id:666,
name:'Keafmd'
},
router
})
</script>
</body>
</html>
效果動圖:

params方式與query方式的區別
query方式傳值:

params方式傳值:

總結:params方式與query方式的區別:
- query方式:
- 類似于get方式,引數會在路由中顯示,可以用做重繪后仍然存在的引數,
- 利用路由規則中的path跳轉,
- params方式:
- 類似于post方式,引數不會在路由中顯示,頁面重繪后引數將不存在,
- 利用路由規則中的name跳轉,
編程式路由
利用JS實作路由跳轉
router-link標簽可以實作頁面超鏈接形式的路由跳轉,但是實際開發中,在很多情況下,需要通過某些邏輯判斷來確定如何進行路由跳轉,也就是說:需要在js代碼中進行路由跳轉,此時可以使用編程式路由,
- 使用this.$router.push方法可以實作路由跳轉,方法的第一個引數可為string型別的路徑,或者可以通過物件將相應引數傳入,
- 通過this.$router.go(n)方法可以實作路由的前進后退,n表示跳轉的個數,正數表示前進,負數表示后退,
- 如果只想實作前進后退可以使用this.$router.forward()(前進一頁),以及this.$router.back()(后退一頁),
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>
<button @click="toHome">首頁</button>
<button @click="toNews">新聞</button>
<button @click="toLogin">登陸</button>
<button @click="doForward1">前進</button>
<button @click="doForward2">前進</button>
<button @click="doBack1">后退</button>
<button @click="doBack2">后退</button>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首頁</div>'
}
const News = {
template: '<div>新聞</div>'
}
const Login = {
template: '<div>登陸</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {},
router,
methods:{
toHome(){
//無引數時,push方法中直接寫路由地址
this.$router.push('/home');
},
toNews(){
//有引數時,push方法中寫一個json物件
this.$router.push({path:'/news',query:{name:'zhangsan'}});
},
toLogin(){
this.$router.push('/login');
},
doForward1(){
this.$router.forward();
},
doForward2(){
this.$router.go(1);
},
doBack1(){
this.$router.back();
},
doBack2(){
this.$router.go(-1);
}
}
})
</script>
</body>
</html>
效果動圖:

通過watch實作路由監聽
通過watch屬性設定監聽$route變化,達到監聽路由跳轉的目的,
在上面代碼中添加watch監聽:
watch: {
// 監聽路由跳轉,
$route(newRoute, oldRoute) {
console.log('watch', newRoute, oldRoute)
}
}
完整代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<p>
<button @click="toHome">首頁</button>
<button @click="toNews">新聞</button>
<button @click="toLogin">登陸</button>
<button @click="doForward1">前進</button>
<button @click="doForward2">前進</button>
<button @click="doBack1">后退</button>
<button @click="doBack2">后退</button>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首頁</div>'
}
const News = {
template: '<div>新聞</div>'
}
const Login = {
template: '<div>登陸</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {},
router,
methods:{
toHome(){
//無引數時,push方法中直接寫路由地址
this.$router.push('/home');
},
toNews(){
//有引數時,push方法中寫一個json物件
this.$router.push({path:'/news',query:{name:'zhangsan'}});
},
toLogin(){
this.$router.push('/login');
},
doForward1(){
this.$router.forward();
},
doForward2(){
this.$router.go(1);
},
doBack1(){
this.$router.back();
},
doBack2(){
this.$router.go(-1);
}
},
watch: {
// 監聽路由跳轉,
$route(newRoute, oldRoute) {
console.log('watch', newRoute, oldRoute)
}
}
})
</script>
</body>
</html>
效果動圖:

導航守衛
路由跳轉前做一些驗證,比如登錄驗證,是網站中的普遍需求, 對此,vue-route 提供了實作導航守衛(navigation-guards)的功能,
你可以使用 router.beforeEach 注冊一個全域前置守衛:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
每個守衛方法接收三個引數:
- to:即將要進入的目標路由物件(去哪里),可以使用 to.path 獲取即將要進入路由地址,
- from:當前導航正要離開的路由物件(從哪來),可以使用 from.path 獲取正要離開的路由地址,
- next:一個函式,表示繼續執行下一個路由,(如果沒有next,將不會進入到下一個路由),
下面例子中實作了如下功能:
- 列舉需要判斷登錄狀態的 “路由集合”,當跳轉至集合中的路由時,如果“未登錄狀態”,則跳轉到登錄頁面,
- 當直接進入登錄頁面LoginPage時,如果“已登錄狀態”,則跳轉到首頁HomePage,
樣例代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="box">
<p>
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
<router-link to="/music">music</router-link>
<router-link to="/login">login</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首頁</div>'
}
const News = {
template: '<div>新聞</div>'
}
const Music = {
template: '<div>音樂</div>'
}
const Login = {
template: '<div>登錄</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/music',
component: Music
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes // (縮寫)相當于 routes: routes
})
var vm = new Vue({
el: '#box',
data: {},
router
})
// 添加全域路由守衛
router.beforeEach((to, from, next) => {
//創建守衛規則集合(這里表示'/news'與'/music'路徑是需要權限驗證的)
const nextRoute = ['/news', '/music'];
// 使用isLogin來模擬是否登錄
let isLogin = false;
// let isLogin = true;
// 判斷to.path(要跳轉的路徑)是否是需要權限驗證的
if (nextRoute.indexOf(to.path) >= 0) {
if (!isLogin) {
router.push({
path: '/login'
})
location.reload(); //必須要有
}
}
// 已登錄狀態;當路由到login時,跳轉至home
if (to.path === '/login') {
if (isLogin) {
router.push({
path: '/home'
});
location.reload();
}
}
next(); //必須要有
});
</script>
</body>
</html>
isLogin = false效果動圖:

我們可以看出當我們點擊 news 和 music 時,因為isLogin = false,所以會自動跳轉到 login 界面,
isLogin = true效果動圖:

我們可以看出當我們點擊 news 和 music 時,因為isLogin = true,所以會顯示相應的界面,
看完如果對你有幫助,感謝點贊支持!
如果你是電腦端,看到右下角的 “一鍵三連” 了嗎,沒錯點它[哈哈]

加油!
共同努力!
Keafmd
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/232477.html
標籤:其他
上一篇:LeetCode題解:x的平方根
