首先簡單說一下單頁面應用程序
單頁面應用程序
- SPA : single page application 單頁面應用程序
- MPA : Multiple Page Application 多頁面應用程序
- 單頁面 web 應用
- 就是隻有一個web頁面的應用
- 是加載單個HTML頁面
- 並在用戶與應用程序交互時,動態更新該頁面的wen應用程序
- 區別
- 對於傳統的多頁面應用程序來說,每次請求服務器返回的都是一個完整的頁面
- 對於單頁面應用程序來說 :
- 只要第一次加載頁面, 以後每次請求 僅僅是獲取必要的數據, 然後由 頁面中 js 解析 獲取的數據展示在頁面中
- 單頁面優勢 :
- 減少了請求體積 , 加快頁面響應速度 ,降低了對服務器的壓力
- 更好的用戶體驗 , 讓用戶在 web app 感受 native app 的流暢 (局部刷新)
- 單頁面的劣勢
- 開發成本高 ( 需要學習路由 )
- 不利於SEO
路由
介紹路由 :
- 路由 : 是瀏覽器URL 中的哈希值( #hash ) 與 展示視圖內容之間的對用規則
- 簡單的來說 : 路由就是一套映射規則(一對一的對應規則),由開發人員制定規則
- 當URL中的哈希值(#hash) 發生改變後, 路由會根據制定好的規則,展示對用的視圖內容
- 爲什麼要學習路由 ?
- 漸進式 => vue => vue-router (管理多個頁面)
- 在web App中 , 經常會出現通過一個頁面來展示和管理整個應用的功能
- SPA 往往是功能複雜的應用 , 爲了有效管理所有視圖內容,前端路由 應運而生
- vue 中的路由 : 是hash 和 component 的對應關係 , 一個哈希值對應一個組件
一 : 路由的基本使用
準備工作 (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>
- 最長用的 入口是 聲明式導航 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
- 例如 : /detail/4?age=21#one
4.3 嵌套路由
作用 : 想在一個組件(child)顯示在另一個組件(parent) 裏
如何使用 :
- 在parent組件裏留一個出口 Parent : --- <router-view></router-view>
- 規則 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