路由
路由是基于hash 和 history 封裝的
- hash
// 例子
location.hash = 'demo'
- history
//例子
history.pushState(null,'title','test')
history.back()
history.forward()
history.go(3)
路由在vue中使用流程
ps. 如果在vue create my-project的時(shí)候沒有選擇路由,就手動(dòng)安裝一下串结。 詳細(xì)見 router 網(wǎng)站
npm install vue-router
router 基礎(chǔ)使用分為以下步驟
1. 在和main.js同級(jí)創(chuàng)建router文件夾苗踪,一般都是src下同級(jí) 下圖
image.png
2. 在router文件下新建index.js文件
- 這個(gè)是router自動(dòng)指定的目錄灵嫌,最好不要更改
- 在main.js引入的時(shí)候直接 '@/router' 即可
路由基礎(chǔ)使用步驟
- 在router/index.js文件中導(dǎo)入router相關(guān)包筐赔。并且用Vue.use注冊(cè)一下
import Vue from 'vue';
import VueRouter from 'vue-router';
//使用router插件
Vue.use(VueRouter);
- 聲明使用VueRouter堪置,添加一些相關(guān)配置沐绒,并且注冊(cè)相關(guān)的組件犁柜。
const routes = [
{
path : '',
redirect : "/home"
},
{
path: '/home',
component: () => import('../views/Home')
},
{
path: '/about',
component: () => import('../views/About')
}
];
const router = new VueRouter({
mode : 'history', //使用history模式
base: process.env.BASE_URL,
routes
});
- 3.將聲明的VueRouter導(dǎo)出
export default router
- 在入口main.js文件中導(dǎo)入router/index.js文件剖毯。 并且在Vue里注冊(cè)
ps: 因?yàn)関ue-router底層默認(rèn)引用的就是router/index.js文件圾笨,所以可以簡(jiǎn)寫直接導(dǎo)入到router/目錄即可。
- 在入口main.js文件中導(dǎo)入router/index.js文件剖毯。 并且在Vue里注冊(cè)
import router from "@/router";
new Vue({
router,
render: h => h(App)
}).$mount('#app')
- 上面的就是基礎(chǔ)配置逊谋,配置好了就可以使用了擂达。to是對(duì)應(yīng)執(zhí)行的路徑。
<div class="centerText">
<router-link to="/home">首頁</router-link>
<router-link to="/about">關(guān)于</router-link>
<router-link to="/user">用戶</router-link>
</div>
<router-view />
router 一些常用字段
- to 對(duì)應(yīng)路徑胶滋。
- tag 設(shè)置類型板鬓。例如: tag="button",就是button樣式
router路徑定義傳參字段
// 可以通過:userId 即可
{
path: '/user/:userId/:age',
name: 'User',
component: () => import("../views/User.vue")
}
v-bind:to使用,語法糖 :to
//通過name 進(jìn)行傳參
<router-link :to="{name: 'User',params: {userId: 'xiaofang',age: 20}}">用戶</router-link>
this.$router常用字段
- this.$router.push
描述:跳轉(zhuǎn)到不同的url究恤,但這個(gè)方法回向history棧添加一個(gè)記錄俭令,點(diǎn)擊后退會(huì)返回到上一個(gè)頁面。
//跳轉(zhuǎn)路徑, 等同于 history.pushState()
this.$router.push('home');
//跳轉(zhuǎn)路徑
this.$router.push({path: '/about'});
// 跳轉(zhuǎn)路徑部宿,傳參數(shù)
this.$router.push({name: 'User',params: {userId: "123",age: 20}});
- this.$router.replace()
描述:同樣是跳轉(zhuǎn)到指定的url抄腔,但是這個(gè)方法不會(huì)向history里面添加新的記錄,點(diǎn)擊返回理张,會(huì)跳轉(zhuǎn)到上上一個(gè)頁面赫蛇。上一個(gè)記錄是不存在的。
//替換路徑, 等同于history.replaceState
this.$router.replace('home');
- this.$router.go(n)
相對(duì)于當(dāng)前頁面向前或向后跳轉(zhuǎn)多少個(gè)頁面,類似 window.history.go(n)雾叭。n可為正數(shù)可為負(fù)數(shù)悟耘。正數(shù)返回上一個(gè)頁面
//返回上一頁, 相當(dāng)于history.back()
this.$router.go(-1);
// 前進(jìn)一步,等同于history.forward
this.$router.go(1);
// 前進(jìn)3步
this.$router.go(3);
// 如果history不夠用织狐,就默認(rèn)失敗吧
this.$router.go(-100);
this.$router.go(100);
router接收路由參數(shù)的方法作煌,分 ? 和 : 兩種接收方式
this.$route是路由信息對(duì)象
- ? 形式的參數(shù)使用this.$route.query接收參數(shù),結(jié)果是一個(gè)對(duì)象赚瘦。
接收格式為?userId=123&age=20
//1.定義方式粟誓。只定義路徑即可。
{
path: '/about',
name: 'About',
component: () => import('../views/About')
}
//2. 傳參方式
<router-link :to="{name: 'User',query: {userId: userId,age}}">關(guān)于</router-link>
//3. 接收方式
- : 形式的參數(shù)使用this.$route.params接收參數(shù)起意,結(jié)果也是一個(gè)對(duì)象鹰服。
例如傳參: :to({name: 'User',params: {userId: "123",age: 20}});
接收格式為 /user/123/20
//1.定義方式
{
path: '/user/:userId/:age',
name: 'User',
component: () => import("../views/User.vue")
}
//2.傳參方式
<router-link :to="{name: 'User',params: {userId: userId,age}}">用戶</router-link>
//3.接收方式
<p>接收參數(shù) userId:{{this.$route.params.userId}} age:{{$route.params.age}}</p>
路由嵌套
開發(fā)中肯定會(huì)遇到路由嵌套的問題,路由嵌套進(jìn)一層精簡(jiǎn)了代碼,提高了組件的復(fù)用性悲酷,降低了代碼的耦合度套菜。
- 在路由中定義子路由使用children[]來包含多個(gè)路由,這里要注意的是path不需要添加 / 了
{
path: '/home',
name: 'Home',
children : [
{
path: '',
// name: 'News',
component : () => import('../components/News')
},
{
path: 'news',
name: 'News',
component : () => import('../components/News')
},
{
path: 'message',
name: 'Message',
component : () => import('../components/Message')
}
],
component: () => import('../views/Home')
}
- 使用路由嵌套同路由的正常使用一樣设易。要在對(duì)應(yīng)的路由.vue下使用逗柴,例如我上面定義的是在Home下的路由,那么路由應(yīng)該寫在Home.vue中
<p>當(dāng)前為Home.vue頁面</p>
<div>
<router-link :to="{name: 'News'}" tag="button">新聞</router-link>
<router-link :to="{name: 'Message'}" tag="button">消息</router-link>
</div>
<router-view />
Vue 導(dǎo)航守衛(wèi)
提供的導(dǎo)航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航顿肺。有多種機(jī)會(huì)植入路由導(dǎo)航過程中:全局的, 單個(gè)路由獨(dú)享的, 或者組件級(jí)的戏溺。
通俗講,導(dǎo)航守衛(wèi)就是控制路由跳轉(zhuǎn)前屠尊,或離開路由后的監(jiān)聽操作
更多路由導(dǎo)航守衛(wèi)使用介紹訪問 官網(wǎng)
- 組件內(nèi)守衛(wèi),也就是在組件內(nèi)才會(huì)執(zhí)行旷祸。
beforeRouteEnter 守衛(wèi)進(jìn)入組件前調(diào)用
beforeRouteUpdate 路由改變時(shí)調(diào)用
beforeRouteLeave 離開該組件時(shí)候調(diào)用
<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'
import News from "@/components/News";
import Message from "@/components/Message";
export default {
name: 'Home',
data(){
return {
togglePath : null
}
}
beforeRouteEnter(to, from, next) {
// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
// 不!能讼昆!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前托享,組件實(shí)例還沒被創(chuàng)建
console.log("執(zhí)行home的b beforeRouteEnter 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建");
next()
},
beforeRouteUpdate(to, from, next) {
// 在當(dāng)前路由改變浸赫,但是該組件被復(fù)用時(shí)調(diào)用
// 舉例來說闰围,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候既峡,
// 由于會(huì)渲染同樣的 Foo 組件辫诅,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用涧狮。
// 可以訪問組件實(shí)例 `this`
console.log("執(zhí)行home的b beforeRouteUpdate 因此組件實(shí)例會(huì)被復(fù)用炕矮。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。");
next()
},
beforeRouteLeave(to, from, next) {
// 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
// 可以訪問組件實(shí)例 `this`
this.togglePath = this.$route.path
console.log("執(zhí)行home的b beforeRouteLeave 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用者冤。"+to.path+"\t"+from.path+"\t"+this.$route.path);
next()
},
}
</script>
keep-alive
keep-alive 是 Vue 內(nèi)置的一個(gè)組件肤视,可以使被包含的組件保留狀態(tài),或避免重新渲染涉枫。 不會(huì)進(jìn)入離開每次都執(zhí)行創(chuàng)建和銷毀邢滑。
更多動(dòng)態(tài)組件 & 異步組件使用見 官網(wǎng)
- 基礎(chǔ)使用
<keep-alive>
<component>
<!-- 該組件將被緩存! -->
</component>
</keep-alive>
- 過濾路徑
<keep-alive include="abc">
<component>
<!-- name 為 abc 的組件將被緩存愿汰! -->
</component>
</keep-alive>
<keep-alive exclude="demo">
<component>
<!-- 除了 name 為 demo 的組件都將被緩存困后! -->
</component>
</keep-alive>
- 如果想某個(gè)路徑網(wǎng)址被緩存,在router 里 增加 meta 屬性衬廷。其中keepAlive為true表示緩存摇予。
const routes = [
{
path: '/about',
name: 'About',
meta: {
keepAlive: true //about路徑 需要緩存
},
component: () => import('../views/About')
},
{
path: '/user/:userId/:age',
name: 'User',
meta: {
keepAlive: false //user路徑 不需要緩存
},
component: () => import("../views/User.vue")
}
];
- 需求:
默認(rèn)顯示 A
B 跳到 A,A 不刷新
C 跳到 A吗跋,A 刷新
實(shí)現(xiàn)方式
//在 A 路由里面設(shè)置 meta 屬性:
{
path: '/',
name: 'A',
component: A,
meta: {
keepAlive: true // 需要被緩存
}
}
//在 B 組件里面設(shè)置 beforeRouteLeave:
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設(shè)置下一個(gè)路由的 meta
to.meta.keepAlive = true; // 讓 A 緩存侧戴,即不刷新
next();
}
};
//在 C 組件里面設(shè)置 beforeRouteLeave:
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設(shè)置下一個(gè)路由的 meta
to.meta.keepAlive = false; // 讓 A 不緩存宁昭,即刷新
next();
}
};