單頁應用程序
單頁應用程序,即 Single-Page Application,簡稱 SPA,是一種使用 JavaScript、HTML 和 CSS 構建的 Web 應用程序。SPA 的核心是前端路由,它使得用戶在訪問網站時,只需加載一次頁面,然后通過前端路由來切換頁面,而不需要重新加載整個頁面。所有功能在 一個 html 頁面 上實現
單頁面應用程序,之所以開發效率高,性能高,用戶體驗好
最大的原因就是:頁面按需更新
要按需更新,首先就需要明確:訪問路徑 和 組件 的對應關系!
訪問路徑 和 組件的對應關系如何確定呢? 路由
路由
生活中的路由:設備和 ip 的映射關系
比如路由器通過源 ip 和目的 ip 確定數據包的下一跳。
Vue中路由:路徑 和 組件 的 映射 關系
VueRouter
目標:認識插件 VueRouter,掌握 VueRouter 的基本使用步驟
作用:修改地址欄路徑時,切換顯示匹配的組件
說明:Vue 官方的一個路由插件,是一個第三方包
官網:https://v3.router.vuejs.org/zh/
VueRouter 的 使用 (5 + 2)
5個基礎步驟 (固定)
- 下載: 下載 VueRouter 模塊到當前工程
npm install vue-router
- 創建
./router/index.js
文件,引入 VueRouter 模塊
import VueRouter from 'vue-router'
- 安裝注冊
Vue.use(VueRouter)
- 創建路由對象
const router = new VueRouter()
- 注入,將路由對象注入到 new Vue 實例(
main.js
)中,建立關聯
import router from './router/index'new Vue({render: h => h(App),router
}).$mount('#app')
2 個核心步驟
- 創建需要的組件 (views目錄),配置路由規則
這里創建 Find.vue
My.vue
Friend.vue
三個組件 (在 ./views
目錄下)
- 配置路由規則,在 ./router/index.js 文件中配置路由規則
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'// 創建了一個路由對象
const router = new VueRouter({// routes 路由規則們// route 一條路由規則 { path: 路徑, component: 組件 }routes: [{ path: '/find', component: Find },{ path: '/my', component: My },{ path: '/friend', component: Friend },]
})export default router
- 配置導航,配置路由出口(路徑匹配的組件顯示的位置),在
App.vue
文件中配置導航
<template><div><div class="footer_wrap"><a href="#/find">發現音樂</a><a href="#/my">我的音樂</a><a href="#/friend">朋友</a></div><div class="top"><!-- 路由出口 → 匹配的組件所展示的位置 --><router-view></router-view></div></div>
</template>
組件存放目錄問題
注意:.vue文件 本質無區別。
路由相關的組件,為什么放在 views 目錄呢?組件分類
組件分類: .vue文件分2類: 頁面組件 & 復用組件
分類開來 更易維護
src/views
文件夾- 頁面組件 - 頁面展示 - 配合路由用
src/components
文件夾- 復用組件 - 展示數據 - 常用于復用
聲明式導航
導航鏈接
需求:實現導航高亮效果
vue-router 提供了一個全局組件 router-link
(取代 a
標簽)
- 能跳轉,配置
to
屬性指定路徑(必須) 。本質還是a
標簽 ,to 無需#
- 能高亮,默認就會提供高亮類名,可以直接設置高亮樣式
<!-- 原來的 -->
<a href="#/find">發現音樂</a>
<a href="#/my">我的音樂</a>
<a href="#/friend">朋友</a><!-- 改成 -->
<router-link to="/find">發現音樂</router-link>
<router-link to="/my">我的音樂</router-link>
<router-link to="/friend">朋友</router-link>
精準匹配 & 模糊匹配
說明:我們發現 router-link
自動給當前導航添加了 兩個高亮類名
-
router-link-active
:模糊匹配 (用的多)to="/my"
可以匹配/my
/my/a
/my/b
…
-
router-link-exact-active
:精確匹配to="/my
" 僅可以匹配/my
自定義高亮類名
說明:router-link
的 兩個高亮類名太長了,我們希望能定制怎么辦?
語法:
const router = new VueRouter({routes: [...],linkActiveClass: "類名1", // 模糊匹配linkExactActiveClass: "類名2" // 精確匹配
})
跳轉傳參
目標:在跳轉路由時, 進行傳值
查詢參數傳參
語法格式如下:
to="/path?參數名=值"
- 對應頁面組件接收傳遞過來的值
$route.query.參數名
App.vue
<template><div id="app"><div class="link"><router-link to="/home">首頁</router-link><router-link to="/search">搜索頁</router-link></div><router-view></router-view></div>
</template>
router/index.js
const router = new VueRouter({routes: [{ path: '/home', component: Home },{ path: '/search', component: Search }]
})
Home.vue
<div class="hot-link">熱門搜索:<router-link to="/search?key=程序員">程序員</router-link><router-link to="/search?ke=前端培訓">前端培訓</router-link><router-link to="/search?key=如何成為前端大牛">如何成為前端大牛</router-link>
</div>
Search.vue
<template><div class="search"><p>搜索關鍵字: {{ $route.query.key }} </p><p>搜索結果: </p><ul><li>.............</li></ul></div>
</template><script>
export default {name: 'MyFriend',created () {// 在created中,獲取路由參數// this.$route.query.參數名 獲取console.log(this.$route.query.key)}
}
</script>
動態路由傳參
- 配置動態路由,在
./router/index.js
文件中配置路由規則
const router = new VueRouter({routes: [{ path: '/home', component: Home },{ path: '/search/:words', component: Search }]
})
-
配置導航鏈接:
to="/path/參數值"
-
對應頁面組件接收傳遞過來的值:
$route.params.參數名
App.vue
<template><div id="app"><div class="link"><router-link to="/home">首頁</router-link><router-link to="/search">搜索頁</router-link></div><router-view></router-view></div>
</template>
Home.vue
<div class="hot-link">熱門搜索:<router-link to="/search/程序員">程序員</router-link><router-link to="/search/前端培訓">前端培訓</router-link><router-link to="/search/如何成為前端大牛">如何成為前端大牛</router-link>
</div>
Search.vue
<template><div class="search"><p>搜索關鍵字: {{ $route.params.words }} </p><p>搜索結果: </p><ul><li>.............</li></ul></div>
</template><script>
export default {name: 'MyFriend',created () {// 在created中,獲取路由參數// this.$route.query.參數名 獲取查詢參數// this.$route.params.參數名 獲取動態路由參數console.log(this.$route.params.words);}
}
</script>
動態路由參數可選符
問題:配了路由 path: "/search/:words"
為什么按下面步驟操作,會未匹配到組件,顯示空白?
原因: /search/:words
表示,必須要傳參數。如果不傳參數,也希望匹配,可以加個可選符 "?"
。
{ path: '/search/:words?', component: Search }
兩種傳參方式的區別
查詢參數傳參 (比較適合傳多個參數)
- 跳轉:
to="/path?參數名=值&參數名2=值"
- 獲取:
$route.query.參數名
動態路由傳參 (優雅簡潔,傳單個參數比較方便)
- 配置動態路由:
path: "/path/:參數名"
- 跳轉:
to="/path/參數值"
- 獲取:
$route.params.參數名
路由重定向
問題:網頁打開, url 默認是 / 路徑,未匹配到組件時,會出現空白
說明:重定向 → 匹配path后, 強制跳轉path路徑
語法: { path: 匹配路徑, redirect: 重定向到的路徑 }
,
const router = new VueRouter({routes: [{ path: '/', redirect: '/home' }, // 重定向到 /home{ path: '/home', component: Home },{ path: '/search/:words?', component: Search }]
})
404
作用:當路徑找不到匹配時,給個提示頁面
位置:配在路由最后
語法:path: "*"
(任意路徑) – 前面不匹配就命中最后這個
const router = new VueRouter({routes: [{ path: '/', redirect: '/home' },{ path: '/home', component: Home },{ path: '/search/:words?', component: Search },{ path: '*', component: NotFound }]
})
模式設置
問題: 路由的路徑看起來不自然,有#
,能否切成真正路徑形式?
- hash路由(默認) 例如: http://localhost:8080/#/home
const router = new VueRouter({mode: 'hash',routes: [...]
})
- history路由(常用) 例如: http://localhost:8080/home
const router = new VueRouter({mode: 'history',routes: [...]
})
編程式導航
基本跳轉
問題:點擊按鈕跳轉如何實現?
編程式導航:用 JS
代碼來進行跳轉
兩種語法:
- path 路徑跳轉(簡易方便)
this.$router.push('路由路徑')this.$router.push({path: '路由路徑'
})
- name 命名路由跳轉(適合 path 路徑長的場景)
this.$router.push({name: '路由名'
})
const router = new VueRouter({routes: [{ name: '路由名', path: '/path/xxx', component: XXX },]
})
Home.vue
<template><div class="home"><div class="logo-box"></div><div class="search-box"><input type="text"><button @click="goSearch">搜索一下</button></div><div class="hot-link">熱門搜索:<router-link to="/search/程序員">程序員</router-link><router-link to="/search/前端培訓">前端培訓</router-link><router-link to="/search/如何成為前端大牛">如何成為前端大牛</router-link></div></div>
</template><script>
export default {name: 'FindMusic',methods: {goSearch () {// 1. 通過路徑的方式跳轉// (1) this.$router.push('路由路徑') [簡寫]// this.$router.push('/search')// (2) this.$router.push({ [完整寫法]// path: '路由路徑' // })// this.$router.push({// path: '/search'// })// 2. 通過命名路由的方式跳轉 (需要給路由起名字) 適合長路徑// this.$router.push({// name: '路由名'// })this.$router.push({name: 'search'})}}
}
</script>
路由傳參
問題:點擊搜索按鈕,跳轉需要傳參如何實現?
兩種傳參方式:查詢參數 + 動態路由傳參
兩種跳轉方式,對于兩種傳參方式都支持:
- path 路徑跳轉傳參(query傳參)
this.$router.push('/路徑?參數名1=參數值1&參數2=參數值2')this.$router.push({path: '/路徑',query: {參數名1: '參數值1',參數名2: '參數值2'}
})
- path 路徑跳轉傳參 (動態路由傳參)
this.$router.push('/路徑/參數值')this.$router.push({path: '/路徑/參數值'
})
- name 命名路由跳轉傳參(query傳參)
this.$router.push({name: '路由名字',query: {參數名1: '參數值1',參數名2: '參數值2'}
})
- name 命名路由跳轉傳參 (動態路由傳參)
this.$router.push({name: '路由名字',params: {參數名: '參數值'}
})
Home.vue
<template><div class="home"><div class="logo-box"></div><div class="search-box"><input v-model="inpValue" type="text"><button @click="goSearch">搜索一下</button></div><div class="hot-link">熱門搜索:<router-link to="/search/黑馬程序員">黑馬程序員</router-link><router-link to="/search/前端培訓">前端培訓</router-link><router-link to="/search/如何成為前端大牛">如何成為前端大牛</router-link></div></div>
</template><script>
export default {name: 'FindMusic',data () {return {inpValue: ''}},methods: {goSearch () {// 1. 通過路徑的方式跳轉// (1) this.$router.push('路由路徑') [簡寫]// this.$router.push('路由路徑?參數名=參數值')// this.$router.push('/search')// this.$router.push(`/search?key=${this.inpValue}`)// this.$router.push(`/search/${this.inpValue}`)// (2) this.$router.push({ [完整寫法] 更適合傳參// path: '路由路徑'// query: {// 參數名: 參數值,// 參數名: 參數值// }// })// this.$router.push({// path: '/search',// query: {// key: this.inpValue// }// })// this.$router.push({// path: `/search/${this.inpValue}`// })// 2. 通過命名路由的方式跳轉 (需要給路由起名字) 適合長路徑// this.$router.push({// name: '路由名'// query: { 參數名: 參數值 },// params: { 參數名: 參數值 }// })this.$router.push({name: 'search',// query: {// key: this.inpValue// }params: {words: this.inpValue}})}}
}
</script>
組件緩存 keep-alive
問題:從面經 點到 詳情頁,又點返回,數據重新加載了 → 希望回到原來的位置
原因:路由跳轉后,組件被銷毀了,返回回來組件又被重建了,所以數據重新被加載了
解決:利用 keep-alive
將組件緩存下來
keep-alive 是什么
keep-alive
是 Vue 的內置組件,當它包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。keep-alive
是一個抽象組件:它自身不會渲染成一個 DOM 元素,也不會出現在父組件鏈中。
keep-alive 的優點
- 在組件切換過程中 把切換出去的組件保留在內存中,防止重復渲染 DOM,
- 減少加載時間及性能消耗,提高用戶體驗性。
<template><div class="h5-wrapper"><keep-alive><router-view></router-view></keep-alive></div>
</template>
keep-alive 的三個屬性
- include : 組件名數組,只有匹配的組件會被緩存
- exclude : 組件名數組,任何匹配的組件都不會被緩存
- max : 最多可以緩存多少組件實例
<template><div class="h5-wrapper" :include="['LayoutPage']"><keep-alive ><router-view></router-view></keep-alive></div>
</template>
keep-alive 的使用會觸發兩個生命周期函數
activated
當組件**被激活(使用)**的時候觸發 → 進入這個頁面的時候觸發deactivated
當組件不被使用的時候觸發 → 離開這個頁面的時候觸發
組件緩存后就不會執行組件的created
, mounted
, destroyed
等鉤子了
所以其提供了 actived
和 deactived
鉤子,幫我們實現業務需求
activated () {console.log('actived 激活 → 進入頁面');
},
deactivated() {console.log('deactived 失活 → 離開頁面');
}
自定義創建項目
目標:基于 VueCli 自定義創建項目架子
的三個屬性
- include : 組件名數組,只有匹配的組件會被緩存
- exclude : 組件名數組,任何匹配的組件都不會被緩存
- max : 最多可以緩存多少組件實例
<template><div class="h5-wrapper" :include="['LayoutPage']"><keep-alive ><router-view></router-view></keep-alive></div>
</template>
keep-alive 的使用會觸發兩個生命周期函數
activated
當組件**被激活(使用)**的時候觸發 → 進入這個頁面的時候觸發deactivated
當組件不被使用的時候觸發 → 離開這個頁面的時候觸發
組件緩存后就不會執行組件的created
, mounted
, destroyed
等鉤子了
所以其提供了 actived
和 deactived
鉤子,幫我們實現業務需求
activated () {console.log('actived 激活 → 進入頁面');
},
deactivated() {console.log('deactived 失活 → 離開頁面');
}
自定義創建項目
目標:基于 VueCli 自定義創建項目架子