天天看點

Vue路由 vue-router知識點詳解

Vue路由 vue-router知識點詳解

一、什麼是前端渲染,什麼是後端渲染?

1.1 後端渲染

也叫服務端渲染,是指當伺服器擷取到url後,通過一些後端代碼在伺服器中直接将對應的html頁面渲染完畢後,再将頁面傳回給前端進行展示,這就叫做後端渲染。

優點:這種情況下渲染好的頁面,不需要單獨加載任何的js和css,可以交給浏覽器展示,這樣也有利于SEO的優化

缺點:後端人員編寫維護任務太重,前端人員要編寫頁面還需要學習後端代碼,而且這樣做會HTML代碼和資料以及對應的邏輯會混在一起,編寫和維護都非常糟糕。

1.2 後端路由

從上面可以知道,在後端,每一個url就對應了一個頁面,而處理這種url與頁面之間的映射關系的路由關系便是後端路由

當url發生改變時,浏覽器便會向靜态資源伺服器請求html,css,js,然後再通過請求過來的js代碼向API伺服器請求資料

1.3 前後端分離

前後端分離就是把資料操作和顯示分離出來。前端專注做資料顯示,通過文字,圖檔或者圖示等方式讓資料形象直覺的顯示出來。後端專注做資料的操作。前端把資料發給後端,有後端對資料進行修改。

1.4 前端渲染

在浏覽器中顯示的大部分内容,都是由前端寫的js代碼在浏覽器執行,最終渲染出來的頁面。

1.5 SPA頁面

單頁面富應用頁面,最主要的特點就是在前後端分離的基礎上加了一層前端路由

1.6 前端路由

網頁會從一開始就下載下傳所有資源,然後通過一些選項,通過改變url選擇性的加載部分資源,而支援這種功能的技術,便是前端路由,前端路由也是管理url和頁面的映射關系,而前端路由的核心便是改變url,而頁面不會進行整體的重新整理

二、更改URL而不重新整理頁面的方法

2.1 url的hash值

可以在控制台通過 location.hash = ‘aaa’ 修改url的hash值

2.2 HTML5的history模式

可以在控制台通過 history.pushState({} , ’ ’ , ‘aaa’ ) 修改url值,而且這個push其實是在做一個入棧和出棧的操作,在浏覽器可以通過history.back()來回到上一個url,也可以通過前進後退來通路之前的url。

還有一個方法是 history.replaceState( { }, ‘ ‘, ‘aaaa’ ),同樣能修改url而浏覽器不重新整理,但是用這種方法并不會有資料存儲,而是直接替換之前的資料,是以這種方法修改的url不能前進後退

三、vue-router

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-u1p85S4t-1570600486821)(file:///C:\Users\輕狂書生\AppData\Local\Temp\msohtmlclip1\01\clip_image004.jpg)]

3.1 安裝

通過npm安裝,也可以通過腳手架安裝

通過npm安裝時要注意,vue路由應該安裝為運作時依賴,是以後面應該加 --save

3.2 使用

  1. 在src/router下的index.js檔案中配置,導入vue/vue-router,通過Vue.use(Router)進行插件的安裝,接着new一個router執行個體,接着導出router執行個體,在main.js中進行導入,然後在vue執行個體中進行使用
  2. 導入要使用的元件,在router執行個體中配置routers屬性,裡面每一個路由都是一個對象,對象中有path:對應的url,component:對應的元件
  3. 在APP.vue中使用來設定路由選擇項,渲染出來為一個标簽,再通過設定元件顯示出來的位置

具體代碼如下:

Index.js:

import Vue from 'vue'

import Router from 'vue-router'

import Home from '../components/Home'    //導入要使用的元件

import About from '../components/About'

 

Vue.use(Router)

 

export default new Router({

  routes: [

​    {  //每一個路由都是一個對象

​      path:"/home",   //path用于設定url後面跟的東西

​      component:Home    //component表示這個path對應的元件

​    },

​    {

​      path:"/about",

​      component:About

​    }

  ]

})
           

Main.js

import Vue from 'vue'

import App from './App'

import router from './router'  //導入路由

 

Vue.config.productionTip = false

 

/* eslint-disable no-new */

new Vue({

  el: '#app',

  router,    //使用路由

  render: h => h(App)

})
           

App.js

<template>

  <div id="app">

​    <router-link to="/home">首頁</router-link>

​    <!-- 通過<router-link to="">設定對應的路由 -->

​    <router-link to="/about">關于</router-link>

​    <router-view></router-view>

​    <!-- 通過<router-view>設定元件顯示的位置 -->

  </div>

</template>

 

<script>

export default {

  name: 'App'

}

</script>

 

<style>
</style>

 
           

3.3 預設路徑設定

很簡單,隻需要在routes屬性中再定義一個對象,對象中使用redirect重定向一下路徑

{  //設定預設路徑,當路徑為空是,把路徑重定向到另一個路徑,這裡是重定向到首頁

​    path:"",

​    redirect:"/home"   //redirect:重定向

 }
           

這樣當路徑為空時,會自動轉到home的路徑

3.4.将浏覽器的url模式設定為history模式

我們使用路由時,預設使用的是hash模式,這樣的壞處是在url中會有一個#号,是以我們可以把模式設定為history,這樣就沒有#号了。

也很簡單,隻需要在router執行個體中設定一個mode屬性為history即可

export default new Router({

  routes,

  mode:'history'  //将路徑模式設定為HTML5的history模式,這樣就不會有#号了

})
           

記得加引号,沒有就會報錯

3.5.router-link标簽的補充屬性

3.5.1.tag

标簽預設的話會被渲染成a标簽,而tag這個屬性的作用便是将渲染成其他标簽

<template>

  <div id="app">

​    <router-link to="/home" tag="button">首頁</router-link>

​    <!-- 通過<router-link to="">設定對應的路由,渲染出來為一個a标簽 -->

​    <router-link to="/about" tag="button">關于</router-link>

​    <router-view></router-view>

​    <!-- 通過<router-view>設定元件顯示的位置 -->

  </div>

</template>
           

可以看到,通過tag=”button”這個屬性,屬性被渲染成了一個button按鈕。

3.5.2.replace

當我們用mode=’history’屬性将浏覽器的url模式從hash變成history之後,每次更改url時,浏覽器都是用pushState()方法來更改,這樣的好處是有曆史記錄,使用者可以通過前進後退來通路曆史頁面。但有些時候我們不想使用者可以通路曆史頁面,這個時候就可以使用replace屬性,用法很簡單,直接在标簽中添加一個replace屬性就好了。

這樣使用者在通路時就不能前進後退了

3.5.3.router-link-active

當我們的标簽處于活躍狀态時,浏覽器會自動給它加上一個這個樣式

是以當需要在添加樣式的時候,可以直接給router-link-active添加樣式

如果我們想修改這個樣式的名字,可以在router執行個體中有一個linkrouteractive屬性,

可以通過這個屬性修改名字

linkrouteractive:”active”
           

3.6.通過代碼修改路由

在上面我們說了設定路由之後可以通過的方式來修改路由

第二種修改路由的方法便是通過代碼修改路由,在原來router-link的地方可以通過兩個button來代替

router-link,然後給這兩個按鈕綁定一個點選事件,在事件中通過this.$router.push()來修改路由

<button @click="homeclick">首頁</button>
<button @click="aboutclick">首頁</button>
           
methods: {

​    homeclick(){

​      this.$router.push('/home')  //通過代碼的方式來修改router

​    },

​    aboutclick(){

​      this.$router.push('/about')

​    },

  },

 
           

3.7.動态路由

我們之前寫的路由都是靜态的已經寫死的,而我們現在需要動态的來決定路由

同樣的,我們需要先定義一個元件,然後将它導入,然後在routes裡定義路由

{

​    path:"/User/:userid",

​    component:User

  }
           

隻不過這次我們在後面加上了 :userid ,這個變量便是我們要動态擷取的值

接着我們在App.vue中使用router-link使用這個路由

可以看到,我們用v-bind指令綁定了to屬性,然後在user後面加上了一個變量userid,

這個變量在下面的data中定義

export default {

  name: 'App',

  data() {

​    return {

​      userid:"zhangsan"

​    }

  },
           

通過這種方式我們就能動态的擷取到userid的值,進而實作動态的路由。

而要是想擷取到url中的userid的值,我們需要通過$route.params.userid

<h2>{{ $route.params.userid }}</h2>

​    <!-- $route代表正在活躍的路由,而之前使用的$router代表我們new出來的路由執行個體 -->
           

要注意差別 r o u t e 和 route和 route和router

3.8.路由的懶加載

懶加載就是指用到時再加載

路由懶加載的寫法:

const Home = () => import('../components/Home')

const About = () => import('../components/About')

const User = () => import('../components/User')   //路由的懶加載方式寫法
           

可以看到,先定義一個常量,然後後面用箭頭函數的形式指派給它一個import,import裡跟上元件的路徑,這樣懶加載便寫好了

3.9.嵌套路由的使用

首先,依舊是導入元件(記得使用懶加載的寫法)

const HomeNews = () => import('../components/HomeNews')

const HomeMessage = () => import('../components/HomeMessage')
           

接着便是使用,而嵌套路由的使用是在需要嵌套的路由中,加入一個children屬性,傳入一個數組,在這個屬性中使用我們的子路由,在我們的嵌套路由裡一樣可以使用預設值

{  //每一個路由都是一個對象

​    path:"/home",   //path用于設定url後面跟的東西

​    component:Home,    //component表示這個path對應的元件

​    children:[         //嵌套路由在要嵌套的路由裡使用children屬性,傳入一個數組

​      {

​        path:'',     //在子路由中,依舊可以設定預設值

​        component:HomeNews

​      },

​      {

​        path:'news',       //在子路由裡,前面不用寫斜杠

​        component:HomeNews

​      },

​      {

​        path:'message',

​        component:HomeMessage

​      }

​    ]       

  },
           

接着就是在我們嵌套的元件中使用被嵌套的元件了,注意to屬性不要寫錯了

<template>

  <div>

​    <h2>我是首頁</h2>

    <p>我是内容,啊哈哈哈</p>

​    <router-link to="/home/news">新聞</router-link>

​    <router-link to="/home/message">資訊</router-link>

​    <router-view></router-view>

  </div>

</template>
           

這樣嵌套路由就寫好了

3.10.路由傳遞參數的方式

  1. 通過params方式

首先在index.js中的routers中設定路由,在路徑後面用冒号接收一個變量

{

​    path:"/User/:userid",

​    component:User

  }
           

在APP.vue中的router-link中 通過v-bind綁定to屬性,在後面加上變量用于傳遞

最後在User元件中通過$route.params.userid擷取參數值

<template>

  <div>

​    <h2>我是使用者</h2>

    <p>我是内容,嘿嘿嘿</p>

​    <h2>{{ $route.params.userid }}</h2>

​    <!-- $route代表正在活躍的路由,而之前使用的$router代表我們new出來的路由執行個體 -->

  </div>

</template>
           
  1. 通過query傳遞

所謂query,就是url後面用?進行連接配接的資料

http://localhost:8081/profile?name=YoRHa&age=18&height=1.88

使用query時index.js中的routers配置正常寫

{

​    path:"/profile",

​    component:Profile

  }
           

但是App.vue中的router-link中依舊需要用v-bind綁定to,然後to的值改為一個對象,第一個path依舊為所前往的路徑,第二個參數query也是一個對象便是我們要傳的值

最後在Profile中我們便可以通過$route.query.name來使用傳遞的值了

3.11. r o u t e r 和 router和 router和route是有差別的

r o u t e r : 為 V u e R o u t e r 實 例 , 想 要 導 航 到 不 同 u r l , 則 使 用 router:為VueRouter執行個體,想要導航到不同url,則使用 router:為VueRouter執行個體,想要導航到不同url,則使用router.push()方法

$route:為目前router跳轉對象,裡面可以擷取name,path,query,params等

3.12.導航守衛

vue-router提供的導航守衛主要是用來監聽路由的進入和離開的

①前置守衛 router.beforeEach((to,from,next)=>{next()}) //在跳轉前回調

其中,to是指進入到哪個路由去,form指從哪個路由跳轉過來,而next()是必須執行的函數,表示是否要展示你要看到的路由頁面,調用該方法後,才能進入下一個鈎子

是以當我們想在路由跳轉的同時修改title時,我們可以這麼做:

首先在每個router中定義title值

{

​    path:"/about",

​    component:About,

​    meta:{

​      title:"關于",

​    },

  },
           

然後我們來設定導航守衛,這裡是指當跳轉發生時,将to頁面的titlt值賦給document的title,next()是必須執行的,表示要展示我們要看到的頁面

router.beforeEach((to,from,next)=>{

  document.title = to.matched[0].meta.title

  next()

})
           

Ps:注意,這裡的router是我們自己定義的Router執行個體,通過腳手架安裝預設好像是沒有的

const router = new Router({

  routes,

  mode:'history'  //将路徑模式設定為HTML5的history模式,這樣就不會有#号了

})
           

②後置鈎子

router.afterEach((to,from)=>{}) //在跳轉後回調,沒有next()

以上的前置守衛和後置鈎子,都是全局守衛

2.路由獨享的守衛

beforeEnter((to,from,next)=>{}) 直接在路由中使用,參數使用和全局的一樣

使用之後在進入之前進行調用

{

​ path:"/about",

​ component:About,

​ meta:{

​ title:“關于”,

​ },

​ beforeEnter: (to, from, next) => {

​ console.log(‘about beforeEnter’)

​ next()

​ }

},

3.元件内的守衛

①beforeRouteEnter((to,from,next)=>{})

②beforeRouteUpdata((to,from,next)=>{})

③befroeRouteLeave((to,from,next)=>{})

3.13.keep-alive

1.Keep-alive标簽的作用是對元件進行一個緩存,使元件保持活着的狀态,不會被銷毀,正常的元件在路由跳轉之後都會調用distroyed()生命周期鈎子,在跳轉回來之後再調用created()生命周期鈎子。而使用keep-alive将Router-view包裹後,其中的元件在路由跳轉後不會被銷毀,會被緩存起來。

2.在使用keep-alive之後,可以使用兩個函數,activated/deactivated,因為元件不會被銷毀,是以相應的元件的狀态變為了活躍和非活躍狀态,當元件變為活躍時,會調用activated,變為不活躍時,會調用deactivated。這兩個隻有在使用了keep-alive時才有生效。

3.Keep-alive還有兩個重要的屬性:1.include 2.exclude

Include表示隻有比對的元件會被緩存

Exclude表示隻有比對的元件不會被緩存

這裡的比對可以是正則或者是元件中定義的name屬性

4.關于在跳轉後保持原來元件的點選路徑:可以在befroeRouteLeave元件内守衛記錄離開前的路徑,然後通過activated修改路徑

activated() {

​    this.$router.push(this.path)    //當元件變為活躍狀态時回調的函數,這裡轉變為離開前的路徑

  },

  beforeRouteLeave (to, from, next) {

​    this.path = this.$route.path   //元件内的守衛,記錄了離開時的路徑

​    next()

  }
           

Keep-alive标簽的作用是對元件進行一個緩存,使元件保持活着的狀态,不會被銷毀,正常的元件在路由跳轉之後都會調用distroyed()生命周期鈎子,在跳轉回來之後再調用created()生命周期鈎子。而使用keep-alive将Router-view包裹後,其中的元件在路由跳轉後不會被銷毀,會被緩存起來。

2.在使用keep-alive之後,可以使用兩個函數,activated/deactivated,因為元件不會被銷毀,是以相應的元件的狀态變為了活躍和非活躍狀态,當元件變為活躍時,會調用activated,變為不活躍時,會調用deactivated。這兩個隻有在使用了keep-alive時才有生效。

3.Keep-alive還有兩個重要的屬性:1.include 2.exclude

Include表示隻有比對的元件會被緩存

Exclude表示隻有比對的元件不會被緩存

這裡的比對可以是正則或者是元件中定義的name屬性

4.關于在跳轉後保持原來元件的點選路徑:可以在befroeRouteLeave元件内守衛記錄離開前的路徑,然後通過activated修改路徑

activated() {

​    this.$router.push(this.path)    //當元件變為活躍狀态時回調的函數,這裡轉變為離開前的路徑

  },

  beforeRouteLeave (to, from, next) {

​    this.path = this.$route.path   //元件内的守衛,記錄了離開時的路徑

​    next()

  }