三十分鐘學(xué)會使用VUE搭建單頁應(yīng)用(SPA) 下

在上一章中,我們學(xué)習(xí)了用VUE2構(gòu)建簡單的單頁應(yīng)用 (SPA)。

在本章中,我們將要學(xué)習(xí):

  1. 通過路由傳遞參數(shù)
  2. 使用路由守衛(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é)會了:

  1. 通過路由傳遞參數(shù)
  2. 路由名稱 (name) 的運用和創(chuàng)建
  3. 路由守護的使用

對了,與 beforeEach 方法相對應(yīng)的是 afterEach 方法,相信聰明的你肯定能舉一反三。

再加上上一章學(xué)會的注冊路由,所有這一切知識點加起來,我相信,你已經(jīng)可以獨立完成一個不錯的單頁程序 (SPA) 了!

最后如果你對我的文章有任何疑問,不要猶豫,在下方留言,或者通過QQ,微信,郵箱,微博任何一個方式聯(lián)系我,我希望有更多志同道合的朋友可以一起探討。

源代碼

碼字不易,喜歡請點贊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容