在上一章中,我們學(xué)習(xí)了用VUE2構(gòu)建簡單的單頁應(yīng)用 (SPA)。
在本章中,我們將要學(xué)習(xí):
- 通過路由傳遞參數(shù)
- 使用路由守衛(wèi) (route guards)使未授權(quán)的用戶不能訪問某些特殊頁面
我會在上一章寫好的程序上繼續(xù)添加功能,你可以直接在我的github上克隆上一章的源代碼
預(yù)覽
我們會在上一章已經(jīng)寫好的程序上加入路由參數(shù)傳遞和路由守護兩個功能。
通過路由傳遞參數(shù)
在VUE中,我們可以通過在某條路由信息 (route,希望你們還能記得route和router和routes的區(qū)別,我在上一章說過的) 中添加類似 :id
的屬性來傳遞參數(shù)。
這種路由參數(shù)傳遞機制在Laravel也有。
每一條路由信息都由一對大括號括起來,就像下面這樣
{ path: '/user/:id', component: User }
像上面這條路由信息,如果我在地址欄輸入/users/2
,那么在目的組件中 (在這里就是User組件),我們就可以通過$route.params.id
來得到2這個整數(shù)。
其實就是把2賦值給了一個變量id, 而這個變量id則定義在$route.params.id
中。
下面來實際操作一下。
創(chuàng)建一個帶參數(shù)的路由
在 scr\components
文件夾下創(chuàng)建新的組件文件Param.vue
,并且填入下面的內(nèi)容:
<!--src\components\Param.vue-->
<template>
<div class="param">
<input type="text" size="30" v-model="UserInput" />
<input type="button" value="Go to route" @click="GoToRoute()">
</div>
</template>
<script>
export default {
name: 'Param',
data () {
return {
UserInput :''
}
},
methods:{
GoToRoute : function(){
this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }})
}
}
}
</script>
上面這段代碼我們定義了一個 param
組件, 這個組建中有一個 input
輸入框和一個導(dǎo)航按鈕,這個導(dǎo)航按鈕會觸發(fā) GoToRoute
函數(shù)。
接著我們打開main.js
文件,把上面的Param.vue
組件導(dǎo)入,并且創(chuàng)建一個與之對應(yīng)的路由信息。
就在 Const routes
語句上面,加上下面這句話:
//main.js
import Param from './componets/Param'
然后把 routes
替換成如下內(nèi)容:
//main.js
//定義路由表
const routes = [
//主頁路由
{ path: '/', component: Hello },
//about頁面路由
{ path: '/about', component: About },
//param頁面路由
{ path: '/param', component: Param }
]
可以注意到上面這個代碼塊中,我僅僅是添加了一句話,一句param的路由信息。
在 App.vue
文件中加入對應(yīng) Param
模塊的超鏈接點擊 <router-link></router-link>
,就在 About
模塊的超鏈接點擊之后。
<!--src\components\App.vue-->
<router-link v-bind:to="'/param'">Param Link</router-link>
現(xiàn)在運行程序,我們的主頁應(yīng)該像是下面這個樣子:
現(xiàn)在緊接著 "about" 之后就是 param link
的超鏈接按鈕,點擊它,你會看到下面的頁面
點擊F12進入開發(fā)者工具,然后點擊 Go to route
的按鈕,在開發(fā)者工具欄中會出現(xiàn)下面的錯誤
[vue-router] Route with name 'Paramdetails' does not exist
這是因為當(dāng)我們點擊 Go to route
按鈕的時候觸發(fā)了 this.$router.push({name: 'Paramdetails', params: { id: this.UserInput }})
這個方法,但是我們還沒有定義任何關(guān)于 paramdetails
的路由。
所以下一步,我們就要創(chuàng)建一個關(guān)于 paramdetails
的組件和與之對應(yīng)的路由信息。
在 src/components
文件夾中創(chuàng)建 paramedetails.vue
文件,然后把下面的內(nèi)容粘貼進去。
<!--src/components/paramdetails.vue-->
<template>
<div class="paramdetails">
<span>The paremter value that was passed to me is: {{ $route.params.id }}</span>
</div>
</template>
<script>
export default {
name: 'paramdetails'
}
</script>
這個組件唯一的作用的就是把路由傳過來的參數(shù)顯示在頁面上。
接著,在 main.js
中引入這個組件,就在 Const routes
這句話上面寫:
//main.js
//import paramdetails component
import paramdetails from './components/paramdetails'
把 routes
替換成下面的內(nèi)容:
//main.js
//定義路由表
const routes = [
{ path: '/', component: Hello },
{ path: '/about', component: About },
{ path: '/param', component: Param },
//定義可以傳參的路由信息
{ path: '/Paramdetails/:id', component: paramdetails, name: 'Paramdetails' }
]
上面這段代碼加入了對 paramdetails
組件的路由信息,并且路由信息中加入對參數(shù) :id
的引用。
另外,還加入了另外一個參數(shù) name
, 關(guān)于 name
參數(shù),其實它是為了我們更加方便的記憶,這樣在切換路由的時候就不需要輸入完整的URL地址,取而代之用 name
定義的名字就可以正確導(dǎo)航到對應(yīng)的路由。
可以回過頭看看上面我們是怎么定義 GoToRoute
這個方法的,在 param.vue
文件中。
我們在 this.$router.push({name: 'Paramdetails', params: { id: this.UserInput }})
中就通過使用 name
參數(shù)來簡化路由的導(dǎo)航。
現(xiàn)在,我們重新運行程序,點擊 param link
導(dǎo)航到 param
組件,然后在輸入框中輸入52, 接著點擊 go to route
按鈕, 你將會看到下面的頁面:
好了!你已經(jīng)成功的通過路由把參數(shù)傳遞過來了,恭喜!
使用路由守護 (route guards)
路由守護我更愿意把他看成是一種鉤子方法,簡單說就是他可以在路由沒有跳轉(zhuǎn)之前 (before) 和已經(jīng)跳轉(zhuǎn)之后 (after) 分別執(zhí)行一些動作 (action)。
路由守護分為全局守護和組件守護兩種,顧名思義,全局守護會檢查每一次路由跳轉(zhuǎn),組件守護只會在當(dāng)前組件內(nèi)部出現(xiàn)路由跳轉(zhuǎn)時觸發(fā)。
下面我們將在 main.js
文件中添加全局路由守護 (beforeEach)。
打開 main.js
文件, 緊挨著 routes
常量下面加入下面的內(nèi)容:
//main.js
//設(shè)置路由守護
router.beforeEach((to, from, next) => {
//檢查這個跳轉(zhuǎn)是否是要跳轉(zhuǎn)到 param 組件
if(to.path == '/param'){
//如果'user' 對象還未賦值
if(localStorage.getItem('user')==undefined){
//提示輸入用戶名
var user = prompt('please enter your username');
//提示輸入密碼
var pass = prompt('please enter your password');
//檢查用戶輸入的用戶名密碼是否和我們預(yù)設(shè)的一樣
if (user == 'username' && pass == 'password'){
//賦值user對象
localStorage.setItem('user', user);
//跳轉(zhuǎn)到對應(yīng)的組件
next();
}else{//
//如果用戶名密碼不正確則顯示錯誤信息
alert('Wrong username and password, you do not have permission to access that route');
//返回并且不進行路由跳轉(zhuǎn)
return;
}
}
}
//如果要跳轉(zhuǎn)的路徑不是 param 組件,則不進行檢查直接跳轉(zhuǎn)
next()
})
上面的 beforeEach
方法有三個參數(shù), to
參數(shù)代表跳轉(zhuǎn)目的地對象, 而 from
這是代表原目的地對象。
在 beforeEach
方法中,首先檢查 "to.path" 是否等于 /param
, 如果是, 則檢查 "localStorage" 數(shù)據(jù)中是否已經(jīng)存有用戶 (user) 的信息。
如果沒有,則彈出提示框要求輸入用戶名和密碼,如果正確就創(chuàng)建 "localStorage" 本地存儲,用戶下次再訪問同樣的頁面就別用重復(fù)輸入用戶信息。
NOTE: next 方法用來跳轉(zhuǎn)到用戶將要跳轉(zhuǎn)的頁面,是一個必須調(diào)用的方法。 如果不調(diào)用此方法,那么用戶將不能進行路由跳轉(zhuǎn)。所以在上面的例子中如果用戶輸入錯誤,則直接警告并且返回,沒有調(diào)用 next 方法。上面只是一個最簡單的例子,只能作為理解使用,千萬不要應(yīng)用到實際開發(fā)中。
總結(jié)
現(xiàn)在你應(yīng)該已經(jīng)學(xué)會了:
- 通過路由傳遞參數(shù)
- 路由名稱 (name) 的運用和創(chuàng)建
- 路由守護的使用
對了,與 beforeEach
方法相對應(yīng)的是 afterEach
方法,相信聰明的你肯定能舉一反三。
再加上上一章學(xué)會的注冊路由,所有這一切知識點加起來,我相信,你已經(jīng)可以獨立完成一個不錯的單頁程序 (SPA) 了!
最后如果你對我的文章有任何疑問,不要猶豫,在下方留言,或者通過QQ,微信,郵箱,微博任何一個方式聯(lián)系我,我希望有更多志同道合的朋友可以一起探討。
碼字不易,喜歡請點贊