vue 之 路由 以及 單頁面應用程序 (路由可是重難點)

首先簡單說一下單頁面應用程序

單頁面應用程序 

  • SPA : single page application   單頁面應用程序
    • MPA : Multiple Page Application  多頁面應用程序
  • 單頁面 web 應用 
    • 就是隻有一個web頁面的應用
    • 是加載單個HTML頁面
    • 並在用戶與應用程序交互時,動態更新該頁面的wen應用程序
  • 區別
    • 對於傳統的多頁面應用程序來說,每次請求服務器返回的都是一個完整的頁面 
    • 對於單頁面應用程序來說 :  
      • 只要第一次加載頁面,   以後每次請求   僅僅是獲取必要的數據, 然後由 頁面中 js 解析 獲取的數據展示在頁面中
  • 單頁面優勢 :
  1. 減少了請求體積 , 加快頁面響應速度 ,降低了對服務器的壓力
  2. 更好的用戶體驗 , 讓用戶在 web app 感受 native app 的流暢 (局部刷新)
  • 單頁面的劣勢 
  1. 開發成本高 ( 需要學習路由 )
  2. 不利於SEO

路由

介紹路由 : 

  • 路由 : 是瀏覽器URL 中的哈希值( #hash ) 與 展示視圖內容之間的對用規則 
    • 簡單的來說 : 路由就是一套映射規則(一對一的對應規則),由開發人員制定規則
    • 當URL中的哈希值(#hash) 發生改變後, 路由會根據制定好的規則,展示對用的視圖內容
  • 爲什麼要學習路由 ?
    • 漸進式 => vue => vue-router (管理多個頁面)
    • 在web App中 , 經常會出現通過一個頁面來展示和管理整個應用的功能
    • SPA 往往是功能複雜的應用 , 爲了有效管理所有視圖內容,前端路由 應運而生
  • vue 中的路由 : 是hashcomponent 的對應關係 , 一個哈希值對應一個組件

一 : 路由的基本使用

準備工作 (3個)

  • 安裝  :    npm i vue-router
  • 引入 :    在引入vue之後引用  <script src="./node_modules/vue-router/dist/vue-router.js">
  • 實例路由對象 + 掛載到vue上

具體步驟(4個) 

  •  1. 入口 
  •  2. 路由規則
  •  3. 組件
  •  4. 出口 
// 1. 入口 
    //  方式1 : url 地址爲入口    調試開發用
    輸入 url 地址  改變哈希值   
    // 方式2  : 聲明式導航 : router-link + to
 
// 2. 路由規則 
    path : 路由路徑 
    component : 將要展示的路由組件
routes : [
    {path : '/one',component : One},
    {path : '/two',component : Two}
]

// 3. 組件 
    // 使用返回值的這個組件名稱
const One = Vue.component('one',{
    template : `<div>子組件 one </div>`
})

// 4 . 出口 
// 也就是組件要展示的地方
<router-view></router-view>

#  總結 
拿到入口 哈希路徑   ,根據路由匹配規則,找到對應的組件,顯示到對用的出口位置

二 : 路由使用注意事項

  • 入口

    • 最長用的 入口是  聲明式導航  router-link 
      // router-link 組件 最終被渲染爲 a 標籤  
      // to屬性轉化爲a標籤的href 屬性 
      // to屬性的值 , 實際上就是哈希值 , 將來要參與路由規則中進行匹配  
       <router-link to='/one'>首頁</router-link>

       

  • 組件 

const One = { 
    template : `<div> 子組件 one </div>`
}
  • 演示 : 多個組件 匹配 

    <div id="app">
      <!-- 1 路由入口:鏈接導航 -->
      <router-link to="/one">One</router-link>
      <router-link to="/two">Two</router-link>
    
      <!-- 4 路由出口:用來展示匹配路由視圖內容 -->
      <router-view></router-view>
    </div>
    
    <!--  導入 vue.js -->
    <script src="./vue.js"></script>
    <!--  導入 路由文件 -->
    <script src="./node_modules/vue-router/dist/vue-router.js"></script>
    <script>
      // 3 創建兩個組件
      const One ={
        template: '<h1>這是 one 組件</h1>'
      }
      const Two =  {
        template: '<h1>這是 two 組件</h1>'
      }
    
      // 0 創建路由對象
      const router = new VueRouter({
        // 2. 路由規則
        routes: [
          { path: '/one', component: One },
          { path: '/two', component: Two }
        ]
      })
    
      const vm = new Vue({
        el: '#app',
        //0. 不要忘記,將路由與vue實例關聯到一起!
        router
      })
    </script>

     

三 : 入口導航菜單高亮處理 

  • 點擊導航 => 元素裏添加了兩個類

<a href="#/one" class="router-link-exact-active router-link-active">One</a>
<a href="#/two" class="">Two</a>
  • 修改方式1 : 直接修改類的樣式

.router-link-exact-active,
.router-link-active {
  color: red;
  font-size: 50px;
}
  • 修改方式2 : 使用存在過的類樣式 => 修改默認高亮類名

const router = new VueRouter({
  routes: [],
  // 修改默認高亮的a標籤的類名
  // red 是已經存在過的
  linkActiveClass: 'red'
})

精確匹配和模糊匹配

  • 精確匹配 : router-link-exact-active 類名 : 只有當 瀏覽器地址欄中的哈希值 與 router-link 的 to 屬性值,完全匹配對,纔會添加該類

  • 模糊匹配: router-link-active 類名 : 只要 瀏覽器地址欄中的哈希值 包含 router-link 的 to 屬性值,就會添加該類名

  • 解決辦法 : 加個 exact

<router-link to="/" exact>
  One
</router-link>
  • 注意 : 精確匹配和模糊匹配,只對添加類名這個機制有效,與路由的匹配規則無關!!!

 

四 : 路由配置 

4.1 動態路由 => 詳情列表 

導入 : 列表的三個手機都要點擊進去詳情頁 , 只需要一個組件 , 顯示不同的數據即可

入口 : to="/detial/3"

規則 : path : '/detail/:id ?'

獲取值 :   組件    --->   $route.params.id

               事件中  --->  this.$route.params.id

               監聽     --->  $route(to){ to.params.id }   或者   watch 

4.2 路由對象  - $route  

  • 一個路由對象(route object) 表示當前激活的路由的狀態信息, 包含了當前url解析得到的信息
  • 一個哈希值路徑  ===>  一個路由對象
  • 路由對象
    • 例如 : /detail/4?age=21#one
      • $route.name : 路由規則名稱
      • $route.params : 路由參數     對象      ----->     { id : '4' }
      • $route.query :  查詢參數       對象      ----->     {age=21}
      • $route.path  :  哈希 值 路徑               ----->      '/detail/4'
      • $route.hash    當前路由的hash 值     ----->      "#one"
      • $route.fullPath   全路徑                      ----->      /detail/4?age=21#one

4.3  嵌套路由   

作用 :   想在一個組件(child)顯示在另一個組件(parent) 裏

如何使用 :  

  1. 在parent組件裏留一個出口  Parent :  ---   <router-view></router-view>
  2. 規則     children       children:[{ path:'/child' , componemt:'Child' }]

/child和child的區別 :  

  • 如果是 /child => 那麼直接訪問就可以了  #/child
  • 如果是 child => 那麼直接訪問就應該訪問#/parent/child  纔可以了  

4.4 命名路由  name

  • 有時候,通過一個名稱來標識一個路由顯得更方便一些
  • 特別是在創建一個路由 , 或者執行一些跳轉的時候  
  • 你可以在創建ROuter實例的時候,在routers配置中給某個路由設置名稱 
    # 命名
    routes: [
        {
            path: '/parent',
            name: 'parent',
            component: parent
        }
    ]
    
    # 入口鏈接 + 跳轉  (使用 path 和 name 的轉換)
    <!-- 方式1 : url手動寫 -->
    
    <!-- 方式2 : 入口鏈接 聲明式導航 -->
    <router-link to="/parent">點擊</router-link>
    <router-link :to="{ name : 'parent' }">點擊</router-link>  # 忘了 帶 : 原始對象類型
    
    <!-- 方式3 : 編程式導航 -->
     fn() {
         // this.$router.push('/parent')
         this.$router.push({
             name: 'parent'
         })
     }

     

4.5 命名視圖

作用 :  一個哈希值路徑顯示多個組件

如何使用 : 

    1. 規則裏面 { path :'/',  components : {   
                                                                   default : header,  
                                                                   m : main, 
                                                                    f :footer   
                                                              } }

      2.  出口 : <router-view />     <router-view name='m' />     <router-view  name='f' />

4.6  重定向 

作用 : 改變路由規則

使用 :  

{path:'/',redirect : ''}

// 1
redirect: '/header'
// 2
redirect: { name: 'header' }
// 3
redirect: to => {
      // console.log(to)
    return {
        name: 'about'
    }
}

4.7 組件傳參 

  • 原始方式使用$route獲取
    # 入口
        <router-link to="/header/3">123</router-link>
    # 規則
    routes: [
        {
            path: '/header/:id',
            component: header,
        }
    ]
    # 獲取參數
    const header = {
        template: `<p>header  {{ $route.params.id }}  </p>`
    }
  • 布爾模式
    # 入口
        <router-link to="/header/3">123</router-link>
    
    # 規則
    routes: [
        {
            path: '/header/:id',
            component: header,
            // 如果 props 被設置爲 true,route.params 將會被設置爲組件屬性
            props: true
        }
    ]
    
    # 獲取參數
    const header = {
        // 參數 id 當成參數
        props: ['id'],
        template: `<p>header   {{ id }} </p>`
    }
  • 對象模式
    # 入口
     <router-link to="/header">123</router-link>
    
    # 規則
     routes: [
         {
             path: '/header',
             component: header,
             props: { foo: '0000' }
         }
     ]
    # 組件
     const header = {
            props: ['foo'],
            template: `<p>header   {{ foo }} </p>`
     }
  • 函數模式
    # 同對象模式一樣
    # 區別是props值不一樣
     props: to => {
         return { foo: '0000' }
     }

     

路由進階 

一 . 元信息 

  • 作用 : 給路由添加一些自己的信息  在導航路由的時候,可以用作判斷
  • 規則 : {path :'/one'   ....    meta : { title : '春' '}}
  • 獲取 : $route.meta.title

二. 導航守衛 

說明 : 通過跳轉或者取消的方式 ,  守衛導航    比如 : 先登錄,在去home,要不然就會跳登錄頁

方法 

router.beforeEach((to, from, next) => {
    // 訪問 login

    if (to.name == 'login') {
        // 下一步
        next()
    } else {
        // 停止跳轉
        next(false)
        // 跳轉到下一步
        next({ name: 'login' }) 或者 使用路徑  next('/login')
    }
})

 

$route 和 $router   的區別

 

$route : 路由對象   --->  url解析對象  ---->   path/name/meta   ----->  都是屬性

$router : 路由實例  ---> new VueRouter()   ---> 編程式導航  ----->  跳轉用的   --->   push    back    replace

 

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