1.後端路由階段
- 流程:使用者在浏覽器中輸入url→發送給伺服器解析→通過jsp(java serve page)把網頁(包含html,css,java(java作用:從資料庫中讀取資料并将資料動态地放在頁面中))渲染好→将網頁傳給浏覽器(傳過去的網頁隻有html和css)
- 後端渲染(服務端渲染):後端通過jsp/php等技術把頁面渲染好了
- 後端路由:後端處理url映射到不同的頁面
2.前後端分離階段
- 簡述:此時後端隻負責提供資料,不負責任何階段的内容,伺服器分為靜态資源伺服器和提供api接口的伺服器
- 流程:使用者在浏覽器中輸入url→從靜态資源伺服器中擷取對應網頁的js html css代碼→浏覽器執行js代碼,向api接口伺服器請求資料→api伺服器傳回大量資料→網頁中其他js代碼生成帶有資料的标簽→通過js代碼渲染到網頁
- 前端渲染:浏覽器中顯示的網頁的大部分内容都是由前端的js代碼在浏覽器中執行,最終渲染出來的網頁
3.SPA頁面
- 差別于前後端分離:此時也有靜态資源伺服器,前後端分離階段中每個url對應一套js html css,spa中隻有一套js html css
-
流程:使用者輸入url→從靜态資源伺服器中擷取所有js html css代碼→根據使用者不同的操作抽取對應的 一部分 html css js到頁面中,不會向靜态資源伺服器中再請求資源(前後端分離階段會)
前端路由:用于映射url和相應要渲染的資源(根據使用者操作如點選生成不同的url)
4.運作一個vue-router小demo
- 我的步驟:
- 1.在router檔案夾裡面建立index.js,建立router執行個體
- 2.建立對應元件 并建立映射關系
- 3.在main.js裡面導入有映射關系的index.js,挂載router執行個體(這樣才可以在所有元件中使用
,等同于操作$router
)Vue.prototype.$router
- 4.将main.js所解析的App.vue template裡寫上router-link表簽
- 标準步驟:
- 1.導入路由對象,并且調用 Vue.use(VueRouter)
- 2.建立路由執行個體,并且傳入路由映射配置
- 3.在Vue執行個體中挂載建立的路由執行個體
- 4.建立路由元件 并 配置路由映射: 元件和路徑映射關系(我在第二步先做也沒問題)
- 5.使用路由: 通過
(用于顯示标簽)和<router-link/>
(用于給元件占位)<router-view>
5.路由的預設路徑
- 意義:打開網站預設顯示首頁
- 用法(預設通路home):
const routes = [
{
path: '', //預設是預設的意思
redirect: "/home" //redirect是重定向, 也就是将預設路徑重定向到/home的路徑下
},
{
path: "/home",
component: home
},
{
path: "/about",
component: about
}
];
6.history模式
- 意義:非history模式中url裡面含有 # 号
- 用法:建立路由執行個體的時候,屬性裡面添加 mode 屬性即可
const router = new VueRouter({
routes,
mode: "history"
});
7.router-link的一些屬性
- 改變router-link樣式:tag=其他标簽
- 取消history.pushState()模式,采用history.replace()模式:replace
- 當
對應的路由比對成功時, 會自動給目前元素設定一個router-link-active的class, 設定active-class可以改變配對成功的元素的樣式<router-link>
- 舉例:
App.vue:
<template>
<div id="app">
<router-link to="/about" tag="button" replace active-class="active">關于</router-link>
<router-link to="/home" tag="button" replace active-class="active">首頁</router-link>
<router-view></router-view>
</div>
</template>
- 效果:
8.用代碼轉跳路由
- 用法:
<template>
<div id="app">
<router-view></router-view>
<button @click="homeClick">首頁</button>
<button @click="aboutClick">關于</button>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
homeClick() {
console.log("homeClick");
this.$router.push("/home"); //等同于pushState,可以換成replace
},
aboutClick() {
console.log("aboutClick");
this.$router.push("/about");
}
}
}
</script>
- 效果和普通轉跳一緻
9.動态路由
- 意義:元件頁template裡擷取 目前路由頁面的參數
- 步驟:
- 1.注冊User元件并建立動态映射
- 2.App.vue 裡面 link-router v-bind動态綁定to屬性
- 3.$route.params擷取目前路由頁面的參數
User.js:
<template>
<div>
<h2>我是User</h2>
<h2>{{this.$route.params.userId}}</h2>
</div>
</template>
- 效果:
10.路由懶加載
- 意義:上面第3點說到:前端路由階段,從靜态資源伺服器中擷取所有js html css(擷取的都是js,拿到再解析)代碼。所有js檔案一起擷取量大,效率低,是以希望當路由被通路的時候才加載對應元件(js)
- 寫法:将import轉化為箭頭函數的寫法,其他無需改變,重新打包可以看到每個元件占一個js檔案(dist/static/js)
// import Home from "../components/Home";
// import About from "../components/About";
// import User from "../components/User";
const Home = () => import("../components/Home");
const About = () => import("../components/About");
const User = () => import("../components/User");
11.二級路由
- 意義:在home頁面中, 我們希望通過/home/news和/home/message通路一些内容
- 步驟:
- 1.建立對應頁面并建立映射關系
- 2.在home.vue裡面寫router-link
- 代碼:
Home.vue:
<template>
<div>
<h2>我是Home</h2>
<router-link to="/home/news">新聞</router-link>
<router-link to="/home/message">消息</router-link>
<router-view> </router-view>
</div>
</template>
- 結果:
12.參數傳遞方式
- 方式一:通過to屬性的query傳遞參數
- 意義:這樣頁面可以通路url中的query參數(參考url組成)
- 方式:router-link to屬性中傳入query參數,元件頁面再通過$route.query通路
- 代碼:
App.vue
<router-link :to="{
path:'/profile',
query:{
height: 188,
weight: 140,
age :19
}
}" tag="button" replace active-class="active">使用者</router-link>
Profile.vue:
<template>
<div>
<h2>我是Profile</h2>
<ul>
<li>{{$route.query.age}}</li>
<li>{{$route.query.weight}}</li>
<li>{{$route.query.height}}</li>
</ul>
</div>
</template>
- 效果:
- 方式二:用$router.push傳值
- 代碼:
App.vue:
<button @click="profileClick">檔案</button>
profileClick() {
this.$router.push({
path: "/profile",
query: {
height: 188,
weight: 140,
age: 19
}
})
}
Profile.vue:
<template>
<div>
<h2>我是Profile</h2>
<ul>
<li>{{$route.query.age}}</li>
<li>{{$route.query.weight}}</li>
<li>{{$route.query.height}}</li>
</ul>
</div>
</template>
效果同上
13. $route
和 $router
的差別
$route
$router
- $router:為VueRouter執行個體,可以認為是全局的路由對象,包含了所有路由的對象和屬性,無論在哪裡列印都一樣
-
$router:為目前router跳轉對象,包含目前url解析得到的資料,裡面可以擷取name、path、query、params等
在目前路由頁面列印:
$router可以看做是建立映射關系時建立的routes數組裡的目前頁面對應對象的擴充
const routes = [
{
path: "/user/:userId",
component: User
},
{
path: "/profile",
component: Profile
} //就是這個對象的擴充
];
14.全局導航守衛
- 介紹:導航守衛主要用來監聽監聽路由的進入和離開的
-
意義:有一個需求,使用者轉跳頁面的時候頁面标題也相應改變,通常情況聯想到在頁面(組 件)生命周期函數中加載的時候改變标題,但是還有一種更好的方法,就是全局路由守衛方法,在index.js裡面調用vue-router提供的beforeEach鈎子函數, 它們會在路由即将改變前和改變後觸發.(router就是全局)
寫法:
index.js:
//導航鈎子的三個參數解析:
//to: 即将要進入的目标的路由對象.
//from: 目前導航即将要離開的路由對象.
//next: 調用該方法後, 才能進入下一個鈎子
router.beforeEach((to, from, next) => {
next(); //這個規定要寫,不寫轉跳異常
document.title = to.matched[0].meta.title;
// to是route路由對象,是以所有參數都是在route裡面取出來的,matched[0]因為有子元件時to.meta.title為空
console.log(to);
});
- 列印結果:
15.keep-alive的作用
-
意義:有一個需求,使用者轉跳頁面再傳回原來頁面的時候,希望頁面内容是轉跳前的内容
方法:在home.vue(轉跳前元件)中添加beforeRouteLeave方法(離開導航守衛)記錄轉跳出去前頁面的最終路徑,用一個變量儲存,傳回時,actived周期函數調用this.$router.push(this.path);,轉跳最終路徑,注意actived在有keep-alive的情況下才能回調
- 代碼:
App.vue:
<keep-alive>
<router-view> </router-view>
</keep-alive>
Home.vue:
<script>
export default {
name: "home",
activated() {
console.log("home activated");
this.$router.push(this.path);
},
deactivated() {
console.log("home deactivated");
}, //失活周期函數,也要加上,不加報錯
beforeRouteLeave (to, from, next) {
next();
this.path = this.$route.path;
},
data(){
return{
path: "/home/news"
}
}
}
</script>
- 效果:
-
keep-alive 有兩個非常重要的屬性:
include - 字元串或正則表達,隻有比對的元件會被緩存
exclude - 字元串或正規表達式,任何比對的元件都不會被緩存
<keep-alive include="Home">
<router-view> </router-view>
</keep-alive>
16.屬性傳值props和路由搭配使用舉例
- 意義:點選觸發頁面轉跳和活躍路由顔色改變
- 代碼:
App.vue:
<tab-bar-item path="/home" activeColor="pink"> </tab-bar-item>
TabBarItem.vue:
<template>
<div class="tab-bar-item" @click="itemClick">
<div v-if="!isActive"><slot name="item-image"> </slot></div>
<div v-else><slot name="item-image-active"> </slot></div>
<div :style="isActive ? {color: activeColor}: {}"><slot name="item-text"> </slot></div>
<!--v-if和v-else 作用于圖檔激活情況,:style作用于文字顔色樣式-->
</div>
</template>
<script>
export default {
name: "TabBarItem",
data(){
return{
// isActive: true
}
},
methods: {
itemClick(){
this.$router.push(this.path);
}
},
props: {
path:{
type: String
},
activeColor: {
type: String
}
},
computed:{
isActive(){
return this.$route.path == this.path;
}
}
}
</script>
- 代碼邏輯:封裝好的元件标簽屬性裡傳值(props用法,每個标簽傳值不同),元件内部收到值并可以使用,作為判斷活躍的依據,再進行下一步操作