VueRouter學習筆記

1.路由的基本概念與原理

1.1 路由

路由是一個比較廣義和抽象的概念,路由的本質就是對應關係。
在開發中,路由分爲:

  • 後端路由
  • 前端路由

1. 後端路由

  • 概念:根據不同的用戶 URL 請求,返回不同的內容
  • 本質:URL 請求地址服務器資源之間的對應關係

2. SPA(Single Page Application)

  • 後端渲染(存在性能問題)
  • Ajax前端渲染(前端渲染提高性能,但是不支持瀏覽器的前進後退操作)
  • SPA(Single Page Application)單頁面應用程序:整個網站只有一個頁面,內容的變化通過Ajax局部更新實現、同時支持瀏覽器地址欄的前進和後退操作
  • SPA實現原理之一:基於URL地址的hash(hash的變化會導致瀏覽器記錄訪問歷史的變化、但是hash的變化不會觸發新的URL請求)
  • 在實現SPA過程中,最核心的技術點就是前端路由

3.前端路由

  • 概念:根據不同的用戶事件,顯示不同的頁面內容
  • 本質:用戶事件與事件處理函數之間的對應關係
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 導入 vue 文件 -->
    <script src="./lib/vue_2.5.22.js"></script>
  </head>
  <body>
    <!-- 被 vue 實例控制的 div 區域 -->
    <div id="app">
      <!-- 切換組件的超鏈接  #後面加路徑的形式————url的hash方式 -->
      <a href="#/zhuye">主頁</a> 
      <a href="#/keji">科技</a> 
      <a href="#/caijing">財經</a>
      <a href="#/yule">娛樂</a>

      <!-- 根據 :is 屬性指定的組件名稱,把對應的組件渲染到 component 標籤所在的位置 -->
      <!-- 可以把 component 標籤當做是【組件的佔位符】 -->
      <component :is="comName"></component>
    </div>

    <script>
      // #region 定義需要被切換的 4 個組件
      // 主頁組件
      const zhuye = {
        template: '<h1>主頁信息</h1>'
      }

      // 科技組件
      const keji = {
        template: '<h1>科技信息</h1>'
      }

      // 財經組件
      const caijing = {
        template: '<h1>財經信息</h1>'
      }

      // 娛樂組件
      const yule = {
        template: '<h1>娛樂信息</h1>'
      }
      // #endregion

      // #region vue 實例對象
      const vm = new Vue({
        el: '#app',
        data: {
          comName: 'zhuye'
        },
        // 註冊私有組件
        components: {
          zhuye,
          keji,
          caijing,
          yule
        }
      })
      // #endregion

      // 監聽 window 的 onhashchange 事件,根據獲取到的最新的 hash 值,切換要顯示的組件的名稱
      window.onhashchange = function() {
        // 通過 location.hash 獲取到最新的 hash 值
        console.log(location.hash);
        switch(location.hash.slice(1)){
          case '/zhuye':
            vm.comName = 'zhuye'
          break
          case '/keji':
            vm.comName = 'keji'
          break
          case '/caijing':
            vm.comName = 'caijing'
          break
          case '/yule':
            vm.comName = 'yule'
          break
        }
      }
    </script>
  </body>

1.2 Vue Router

Vue Router(官網:https://router.vuejs.org/zh/)是 Vue.js 官方的路由管理器。
它和 Vue.js 的核心深度集成,可以非常方便的用於SPA(single page web application,單頁應用程序)應用程序的開發。
Vue Router依賴於Vue,所以需要先引入Vue,再引入Vue Router

Vue Router的特性:

  • 支持H5歷史模式或者hash模式
  • 支持嵌套路由
  • 支持路由參數
  • 支持編程式路由
  • 支持命名路由
  • 支持路由導航守衛
  • 支持路由過渡動畫特效
  • 支持路由懶加載
  • 支持路由滾動行爲

2. vue-router的基本使用

2.1 基本使用步驟

// A.導入js文件

<script src="lib/vue_2.5.22.js"></script>
<script src="lib/vue-router_3.0.2.js"></script>

// B.添加路由鏈接:<router-link>是路由中提供的標籤,默認會被渲染爲a標籤,to屬性默認被渲染爲href屬性,to屬性的值會被渲染爲#開頭的hash地址
<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>
// C.添加路由填充位(路由佔位符)
// 將來通過路由規則匹配到的組件,將會被渲染到 router-view 所在的位置 
<router-view></router-view>
// D.定義路由組件
var User = { template:"<div>This is User</div>" }
var Login = { template:"<div>This is Login</div>" }
//E.配置路由規則並創建路由實例
var myRouter = new VueRouter({
    //routes是路由規則數組
    routes:[
        //每一個路由規則都是一個對象,對象中至少包含path和component兩個屬性
        //path表示  路由匹配的hash地址,component表示路由規則對應要展示的組件對象
        {path:"/user",component:User},
        {path:"/login",component:Login}
    ]
})
F.將路由掛載到Vue實例中
new Vue({
    el:"#app",
    //通過router屬性掛載路由對象
    router:myRouter
})

2.2 路由重定向

路由重定向指的是:用戶在訪問地址 A 的時候,強制用戶跳轉到地址 C ,從而展示特定的組件頁面;
通過路由規則的 redirect 屬性,指定一個新的路由地址,可以很方便地設置路由的重定向:

var router = new VueRouter({
 routes: [
 // 其中,path 表示需要被重定向的原地址,redirect 表示將要被重定向到的新地址
 {path:'/', redirect: '/user'},
 {path:'/user',component: User},
 {path:'/register',component: Register}
 ]
 })

3. vue-router嵌套路由

3.1 嵌套路由用法

1. 嵌套路由功能分析

  • 點擊父級路由鏈接顯示模板內容
  • 模板內容中又有子級路由鏈接
  • 點擊子級路由鏈接顯示子級模板內容

在這裏插入圖片描述

2. 父路由組件模板

  • 父級路由鏈接
  • 父組件路由填充位
<!-- 父級路由鏈接 -->
 <p>
	 <router-link to="/user">User</router-link>
	 <router-link to="/register">Register</router-link>
</p>
<div>
	 <!-- 控制組件的顯示位置 -->
	 <router-view></router-view>
 </div>

3. 子級路由模板

  • 子級路由鏈接
  • 子級路由填充位
const Register = {
 template: `<div>
		 <h1>Register 組件</h1>
		 <hr/>
		 <router-link to="/register/tab1">Tab1</router-link>
		 <router-link to="/register/tab2">Tab2</router-link>
		 <!-- 子路由填充位置 -->
		 <router-view><router-view/>
	 </div>`
 }

4. 嵌套路由配置

  • 父級路由通過children屬性配置子級路由
const router = new VueRouter({
	 routes: [
		 { path: '/user', component: User },
		 {
			 path: '/register',
			 component: Register,
			 // 通過 children 屬性,爲 /register 添加子路由規則
			 //這裏的path要寫完整的路由地址
			 children: [
				 { path: '/register/tab1', component: Tab1 },
				 { path: '/register/tab2', component: Tab2 }
			 ]
		 }
 	]
 })
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 導入 vue 文件 -->
    <script src="./lib/vue_2.5.22.js"></script>
    <script src="./lib/vue-router_3.0.2.js"></script>
  </head>
  <body>
    <!-- 被 vm 實例所控制的區域 -->
    <div id="app">
      <router-link to="/user">User</router-link>
      <router-link to="/register">Register</router-link>

      <!-- 路由佔位符 -->
      <router-view></router-view>
    </div>

    <script>
      const User = {
        template: '<h1>User 組件</h1>'
      }

      const Register = {
        template: `<div>
          <h1>Register 組件</h1>
          <hr/>

          <!-- 子路由鏈接 -->
          <router-link to="/register/tab1">tab1</router-link>
          <router-link to="/register/tab2">tab2</router-link>

          <!-- 子路由的佔位符 -->
           <router-view><router-view />
        <div>`
      }

      const Tab1 = {
        template: '<h3>tab1 子組件</h3>'
      }

      const Tab2 = {
        template: '<h3>tab2 子組件</h3>'
      }

      // 創建路由實例對象
      const router = new VueRouter({
        // 所有的路由規則
        routes: [
          { path: '/', redirect: '/user'},
          { path: '/user', component: User },
          // children 數組表示子路由規則
          { 
	          path: '/register', 
	          component: Register, 
	          children: [
	            { path: '/register/tab1', component: Tab1 },
	            { path: '/register/tab2', component: Tab2 }
	          ] 
          }
        ]
      })

      // 創建 vm 實例對象
      const vm = new Vue({
        // 指定控制的區域
        el: '#app',
        data: {},
        // 掛載路由實例對象
        // router: router
        router
      })
    </script>
  </body>
</html>

4. vue-router動態路由匹配

4.1 動態匹配路由的基本用法

應用場景:通過動態路由參數的模式進行路由匹配

var router = new VueRouter({
 routes: [
 // 動態路徑參數 以冒號開頭
 { path: '/user/:id', component: User }
 ]
})
const User = {
 // 路由組件中通過$route.params獲取路由參數
 template: '<div>User {{ $route.params.id }}</div>'
}

4.2 路由組件傳遞參數

$route與對應路由形成高度耦合,不夠靈活,所以可以使用props將組件和路由解耦

1. props的值爲布爾類型(獲取動態參數)

 const router = new VueRouter({
	 routes: [
		 // 如果 props 被設置爲 true,route.params 將會被設置爲組件屬性
		 { path: '/user/:id', component: User, props: true }
	 ]
 })
const User = {
	 props: ['id'], // 使用 props 接收路由參數
	 template: '<div>用戶ID:{{ id }}</div>' // 使用路由參數
}

2. props的值爲對象類型(傳遞靜態參數)

const router = new VueRouter({
	 routes: [
	 	// 如果 props 是一個對象,它會被按原樣設置爲組件屬性
		 { path: '/user/:id', component: User, props: { uname: 'lisi', age: 12 }}
	 ]
 })
const User = {
 props: ['uname', 'age'],
 template: '<div>用戶信息:{{ uname + '---' + age}}</div>'
 }

3. props的值爲函數類型(動靜都可以傳)

const router = new VueRouter({
	 routes: [
		 // 如果 props 是一個函數,則這個函數接收 route 對象爲自己的形參
		 { 
		 path: '/user/:id', 
		 component: User, 
		 props: route => (
			 { 
			 uname: 'zs', age: 20, id: route.params.id 
			 })
		 }
	 ]
 })
const User = {
 props: ['uname', 'age', 'id'],
 template: '<div>用戶信息:{{ uname + '---' + age + '---' + id}}</div>'
 }

5. vue-router命名路由

5.1 命名路由的配置規則

會選擇to裏面的參數進行渲染

const router = new VueRouter({
// 所有的路由規則
routes: [
{ path: ‘/’, redirect: ‘/user’ },
{
// 命名路由
name: 'user',
path: ‘/user/:id’,
component: User,
props: route => ({ uname: ‘zs’, age: 20, id: route.params.id })
},
{ path: ‘/register’, component: Register }
]
})

<router-link :to="{ name: 'user', params: { id: 123 }}">User</router-link>

跟上面代碼一個作用

router.push({ name: 'user', params: { id: 123 }})

這兩種方式都會把路由導航到 /user/123 路徑

6. vue-router編程式導航

6.1 頁面導航的兩種方式

  • 聲明式導航:通過點擊鏈接實現導航的方式,叫做聲明式導航
    例如:普通網頁中的 <a></a> 鏈接 或 vue 中的<router-link></router-link>
  • 編程式導航:通過調用JavaScript形式的API實現導航的方式,叫做編程式導航
    例如:普通網頁中的location.href

6.2 編程式導航基本用法

常用的編程式導航 API 如下:

  • this.$router.push(‘hash地址’)
  • this.$router.go(n) n爲-1 上一條 1 爲下一條
const User = {
	 template: '<div><button @click="goRegister">跳轉到註冊頁面</button></div>',
	 methods: {
		 goRegister: function(){
		 // 用編程的方式控制路由跳轉
		 this.$router.push('/register');
		 }
	 }
 }

6.3 編程式導航參數規則

router.push() 方法的參數規則

// 字符串(路徑名稱)
 router.push('/home')
 // 對象
 router.push({ path: '/home' })
 // 命名的路由(傳遞參數)
 router.push({ name: '/user', params: { userId: 123 }})
 // 帶查詢參數,變成 /register?uname=lisi
 router.push({ path: '/register', query: { uname: 'lisi' }})

參考文檔:https://router.vuejs.org/zh/installation.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章