接著上一節(jié)講,基本框架已經(jīng)搭建完成,接下來最重要的就是項(xiàng)目里路由配置了衡便,它管理著頁面間的跳轉(zhuǎn),我們做前端項(xiàng)目洋访,基本上步驟就是:搭建前端框架--配置項(xiàng)目路由--開發(fā)具體頁面镣陕,按照這一步驟,我們來詳細(xì)講解一下vue Router的知識(shí)和使用方法姻政,學(xué)習(xí)這篇文章你可以可以對(duì)照著官方文檔Vue Router來學(xué)習(xí)
我們來看一下src/APP.vue里面的內(nèi)容:
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>
其中<router-link></router-link>
和<router-view/>
都是vue的內(nèi)置組件呆抑,這里簡(jiǎn)單介紹下這種內(nèi)置組件的作用
<router-link></router-link> 它是一個(gè)閉合標(biāo)簽,等同于封裝后的a標(biāo)簽汁展,里面有一個(gè)很重要的屬性to鹊碍,它的值是一個(gè)需要跳轉(zhuǎn)的路徑
<router-view/> 它是一個(gè)開標(biāo)簽,等同于<router-view></router-view>食绿,它是視圖渲染組件妹萨,通過<router-link>跳轉(zhuǎn)到某個(gè)頁面時(shí)所加載的組件都會(huì)在這里渲染
可能有些人有些疑問,什么是閉合標(biāo)簽什么是開標(biāo)簽?zāi)兀?/p>
簡(jiǎn)單介紹一下炫欺,比如<router-link to="/">Home</router-link>
它里面有home這個(gè)內(nèi)容乎完,所以只能寫成閉合標(biāo)簽,像<router-view></router-view>
這種標(biāo)簽品洛,里面沒有內(nèi)容树姨,就可以簡(jiǎn)寫成開標(biāo)簽<router-view/>
接下來切入正題摩桶,我們來說第一個(gè)知識(shí)點(diǎn):
- 動(dòng)態(tài)路由匹配
來舉一個(gè)實(shí)際的例子:有一個(gè)頁面,展示的是所有任務(wù)的一個(gè)table頁帽揪,在table頁的每一行硝清,都有一個(gè)查看按鈕,點(diǎn)擊查看可以跳轉(zhuǎn)到任務(wù)詳情的頁面转晰,查看任務(wù)詳細(xì)數(shù)據(jù)
http://10.0.0.186:18090/#/task/task-detail/10000218
http://10.0.0.186:18090/#/task/task-detail/10000217
http://10.0.0.186:18090/#/task/task-detail/10000216
跳轉(zhuǎn)的時(shí)候芦拿,需要把taskId傳過去,然后詳情頁面才能根據(jù)taskId請(qǐng)求接口查邢,獲取任務(wù)的詳情
好了蔗崎,知道需求了,利用動(dòng)態(tài)路由匹配我們應(yīng)該怎么做呢扰藕?
在src/index.js里面配置路由:
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/task-detail/:taskId',
name: 'taskDetail',
component: () => import('../views/task-detail.vue')
},
...errorRoutes
]
在src/App.vue里配置路由:
<router-link to="/task-detail/10000218">任務(wù)詳情10000218</router-link>
<router-link to="/task-detail/10000217">任務(wù)詳情10000217</router-link>
<router-link to="/task-detail/10000216">任務(wù)詳情10000216</router-link>
新增src/views/task-detail.vue頁面缓苛,來接收通過路由傳遞過來的值
<template>
<section>
{{$route.params.taskId}}
</section>
</template>
以上就是動(dòng)態(tài)路由匹配的用法,點(diǎn)擊跳轉(zhuǎn)的時(shí)候邓深,url是這樣的:http://localhost:4000/#/task-detail/10000218
- 編程式導(dǎo)航
除了使用<router-link>
創(chuàng)建a標(biāo)簽來定義導(dǎo)航鏈接未桥,我們還可以借助router的實(shí)例方法,通過編寫代碼來實(shí)現(xiàn)芥备,并且可以傳遞參數(shù)冬耿,具體應(yīng)該怎么做呢?
首先src/App.vue里面咱們把<router-link>
這種方式改成如下方式:
<button @click="go_page('10000218')">任務(wù)詳情10000218</button>
<button @click="go_page('10000217')">任務(wù)詳情10000217</button>
<button @click="go_page('10000216')">任務(wù)詳情10000216</button>
這里我們定義了一個(gè)go_page
方法萌壳,同樣也是在App.vue里面寫:
export default {
data () {
return {
}
},
methods: {
go_page (taskId) {
this.$router.push({
path: '/task-detail',
query: {
taskId: taskId
}
})
}
}
}
</script>
而且剛才在src/index.js里面配置的路由也要變一變了:
{
path: '/task-detail',
name: 'taskDetail',
component: () => import('../views/task-detail.vue')
},
在src/views/task-detail.vue頁面獲取傳遞過來的值亦镶,采用的方式也不一樣了:
<template>
<section>
{{$route.query.taskId}}
</section>
</template>
以上,就可以拿到由路由傳遞過來的值了讶凉,點(diǎn)擊跳轉(zhuǎn)的時(shí)候染乌,url是這樣的:http://localhost:4000/#/task-detail?taskId=10000218
,通過這兩個(gè)url懂讯,你發(fā)現(xiàn)了動(dòng)態(tài)路由匹配和編程式導(dǎo)航的區(qū)別了嗎荷憋?
如果不想在url暴露參數(shù)出來,go_page
方法也可以這樣寫:
export default {
data () {
return {
}
},
methods: {
go_page (taskId) {
this.$router.push({
name: 'task-detail', // 這里只能采用路由的別名褐望,不能使用path: '/task-detail'
params: {
taskId: taskId
}
})
}
}
}
</script>
在src/views/task-detail.vue頁面獲取傳遞過來的值
<template>
<section>
{{$route.params.taskId}}
</section>
</template>
但是這種方式也有弊端勒庄,當(dāng)你在http://localhost:4000/#/task-detail
路由下刷新這個(gè)頁面的時(shí)候,傳遞的參數(shù)就沒了
- 嵌套路由匹配
我借用vue-router官網(wǎng)的例子來說明:實(shí)際的項(xiàng)目往往都是由多層嵌套的組件組合而成瘫里,同樣实蔽,url中各段動(dòng)態(tài)路徑也按某種結(jié)構(gòu)對(duì)應(yīng)嵌套的各層組件:
/product/ele_product/phone /product/ele_product/computer
+------------------+ +-----------------+
| product | | product |
| +--------------+ | | +-------------+ |
| | ele_product | | +------------> | | ele_product | |
| | +---------+ | | | | +---------+ | |
| | | phone | | | | | |computer | | |
| | | | | | | | | | | |
| | +---------+ | | | | +---------+ | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
比如一個(gè)商城的項(xiàng)目,產(chǎn)品-電子產(chǎn)品-手機(jī)谨读,產(chǎn)品-電子產(chǎn)品-電腦局装,像這種三級(jí)的嵌套頁面,那么應(yīng)該怎么寫嵌套路由呢?接下來咱們一步步實(shí)現(xiàn):
首先咱們
首先先把這四個(gè)頁面新建出來:
在src/views文件夾下新建product文件夾铐尚,同時(shí)新增index.vue
拨脉,ele-product.vue
,phone.vue
和computer.vue
這四個(gè)文件
index.vue
<template>
<section>
<h3>這是產(chǎn)品頁</h3>
<router-view/>
</section>
</template>
ele-product.vue
<template>
<section>
<h3>我是電子產(chǎn)品頁</h3>
<router-view/>
</section>
</template>
phone.vue
<template>
<section>
<h3>我是手機(jī)頁</h3>
</section>
</template>
computer.vue
<template>
<section>
<h3>我是電腦頁</h3>
</section>
</template>
同時(shí)需要在src/index.js里面配置我們的嵌套路由:
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/task-detail',
name: 'taskDetail',
component: () => import('../views/task-detail.vue')
},
{
path: '/product',
name: 'product',
component: () => import('../views/product/index.vue'),
children: [
{
path: 'ele-product', // 子路由需要前面加'/'宣增,只有副路由才有
name: 'ele-product',
component: () => import('../views/product/ele-product.vue'),
children: [
{
path: 'phone', // 子路由需要前面加'/'玫膀,只有副路由才有
name: 'phone',
component: () => import('../views/product/phone.vue'),
},
{
path: 'computer', // 子路由需要前面加'/',只有副路由才有
name: 'computer',
component: () => import('../views/product/computer.vue'),
}
]
}
]
},
...errorRoutes
]
接下來在src/App.vue頁面爹脾,根據(jù)路由訪問這幾個(gè)頁面:
<router-link to="/product">產(chǎn)品</router-link><br>
<router-link to="/product/ele-product">電子產(chǎn)品</router-link><br>
<router-link to="/product/ele-product/phone">手機(jī)</router-link>
<router-link to="/product/ele-product/computer">電腦</router-link>
這里你會(huì)發(fā)現(xiàn)帖旨,index.vue
和ele-product.vue
頁面都有<router-view/>
這個(gè)標(biāo)簽,因?yàn)楹?code>App.vue頁面一樣灵妨,它們都是父頁面解阅,App.vue
是根頁面,是項(xiàng)目中所有頁面的父頁面闷串,而index.vue
是ele-product.vue
頁面的父頁面瓮钥,ele-product.vue
是phone.vue
和computer.vue
的父頁面筋量,只要這個(gè)頁面是父頁面就需要添加<router-view/>
標(biāo)簽
- 命名路由
在src/index.js文件里烹吵,在配置路由的時(shí)候,每個(gè)路由對(duì)象上都加了一個(gè)name屬性桨武,為啥子加呢肋拔,相當(dāng)于給這個(gè)路由起了一個(gè)名字,所以有了命名路由的叫法呀酸,有什么用呢凉蜂?還真有用處,上面我們?cè)谟?code><router-link>做路由跳轉(zhuǎn)時(shí)性誉,是怎么寫的呢窿吩?
<router-link to="/product/ele-product/computer">電腦</router-link>
我們也可以用命名路由來進(jìn)行路由跳轉(zhuǎn):
<router-link :to="{name: 'computer'}">電腦</router-link>
這樣寫也起到了相同的效果,而且不用寫那么一大串長的路由错览,是不是很方便呢纫雁?這里提一下哦,給路由命名的時(shí)候倾哺,不能存在兩個(gè)name相同的路由轧邪,name具有唯一性荚守,在配置路由的時(shí)候看一下千萬別整成多個(gè)路由都叫某一個(gè)name哦
- 命名視圖
上面我們提到過奔誓,只要一個(gè)頁面它是父頁面略吨,那么里面就要添加一個(gè)<router-view/>
標(biāo)簽咽瓷,但是如果想在這個(gè)父頁面顯示多個(gè)視圖获列,而且讓不同的視圖顯示在指定位置唾糯,OK爽撒,就要用到命名視圖了
還拿上面的產(chǎn)品-電子產(chǎn)品-手機(jī)這個(gè)嵌套頁面說事兒蕊唐,當(dāng)進(jìn)入了手機(jī)這個(gè)頁面,我們又分很多手機(jī)品牌简十,比如要在phone.vue
這個(gè)頁面分別展示華為專場(chǎng)衙耕,蘋果專場(chǎng),小米專場(chǎng)勺远,vivo專場(chǎng)橙喘,怎么做呢?
在src/views/product文件夾下新增apple.vue
胶逢,mi.vue
厅瞎,vivo.vue
這三個(gè)文件,同時(shí)修改phone.vue
這個(gè)頁面的內(nèi)容初坠,讓它作為華為專場(chǎng)的頁面展示:
phone.vue
<template>
<section>
<h3>華為專場(chǎng)</h3>
</section>
</template>
apple.vue
<template>
<section>
<h3>蘋果專場(chǎng)</h3>
</section>
</template>
mi.vue
<template>
<section>
<h3>小米專場(chǎng)</h3>
</section>
</template>
vivo.vue
<template>
<section>
<h3>vivo專場(chǎng)</h3>
</section>
</template>
并且找到它的父頁面ele-product.vue
頁面和簸,修改如下:
<template>
<section>
<h3>我是電子產(chǎn)品頁</h3>
<router-view/>
<router-view name="apple"/>
<router-view name="mi"/>
<router-view name="vivo"/>
</section>
</template>
修改src/router/index.js里的路由配置:
{
path: '/product',
name: 'product',
component: () => import('../views/product/index.vue'),
children: [
{
path: 'ele-product', // 子路由需要前面加'/',只有副路由才有
name: 'ele-product',
component: () => import('../views/product/ele-product.vue'),
children: [
{
path: 'phone', // 子路由需要前面加'/'碟刺,只有副路由才有
name: 'phone',
components: {
default: () => import('../views/product/phone.vue'),
apple: () => import('../views/product/apple.vue'),
mi: () => import('../views/product/mi.vue'),
vivo: () => import('../views/product/vivo.vue'),
},
},
{
path: 'computer', // 子路由需要前面加'/'锁保,只有副路由才有
name: 'computer',
component: () => import('../views/product/computer.vue'),
}
]
}
]
},
完成上述操作,當(dāng)你要訪問http://localhost:4000/#/product/ele-product/phone
時(shí)半沽,就可以看到頁面加載了多個(gè)專場(chǎng)視圖
- 重定向
這個(gè)重定向就是幫助我們將當(dāng)前路由指向另外一個(gè)路由爽柒,在做管理類項(xiàng)目(左側(cè)導(dǎo)航欄,右側(cè)視圖的項(xiàng)目)的時(shí)候者填,我們就需要用到重定向
{
path: '/web-task',
component: Layout,
redirect: '/web-task/task-list',
name: 'web-task',
meta: {
title: '撥測(cè)任務(wù)管理',
},
children: [
{
path: 'task-list',
component: resolve => require(['@/views/web-task/task-list.vue'], resolve),
name: 'task-list',
meta: {
title: '撥測(cè)任務(wù)列表',
},
},
]
}
當(dāng)點(diǎn)擊撥測(cè)任務(wù)管理時(shí)浩村,就直接跳轉(zhuǎn)到撥測(cè)任務(wù)列表頁面,之所以能重定向占哟,就是redirect
在起作用心墅,它的值可以是字符串,也可以是個(gè)對(duì)象或則方法
// 字符串
{
redirect: '/web-task/task-list'
}
// 對(duì)象
{
redirect: {
name: 'task-list'
}
}
// 方法
{
redirect: to => {
return {
name: 'task-list'
}
}
}