本文以【前端框架】vue~hello world中的項目進行演示
注:本項目在初始化時已添加了vue-router
模塊,若項目未添加該模塊請先添加
添加vue-router
模塊
在項目目錄執行命令
npm install vue-router
項目中使用
此處通過項目初始化時生成的文件進行分析
src\router\index.js
import Vue from "vue";
import Router from "vue-router";
import HelloWorld from "@/components/HelloWorld";
Vue.use(Router);
export default new Router({
routes: [{
path: "/",
name: "HelloWorld",
component: HelloWorld
},
{
path: "/HelloVue",
name: "HelloVue",
component: () => import('../components/myComponents/HelloVue')
}
]
});
代碼說明:
導入並註冊插件
import Router from "vue-router";
Vue.use(Router);
將請求路徑與組件映射,在創建router
實例時將映射信息傳入(此處爲了便於理解,將代碼進行了拆分)
let myRouter = [{
path: "/",
name: "HelloWorld",
component: HelloWorld
},
{
path: "/HelloVue",
name: "HelloVue",
component: () => import('../components/myComponents/HelloVue')
}
];
let myOptions = {
routes: myRouter
}
export default new Router(myOptions);
src\App.vue
<template>
<div id="app">
<img src="./assets/logo.png" />
<router-view />
</div>
</template>
代碼說明:
<router-view>
標籤定義了路由出口, 路由匹配到的組件將渲染在這裏
src\main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App
},
template: '<App/>'
})
代碼說明:
import router from './router'
導入的是src\router\index.js中導出的路由實例
在創建Vue實例時將路由實例注入,這裏的Vue實例爲應用的根實例
使用步驟總結:
1、添加vue-router
模塊
2、定義路由映射信息
3、創建路由實例
4、定義路由出口
5、將路由實例注入vue實例中
當路由實例注入到vue根實例中後,我們可以在任何組件內通過 this.$router
訪問路由器,也可以通過 this.$route
訪問當前路由
固定路由與動態路由
固定路由是指我們在將請求路徑映射到組件上時明確定義的請求路徑
path: "/HelloVue"
動態路由是指我們在將請求路徑映射到組件上時未明確定義的請求路徑,該路由描述的是某一類請求,路徑中含有動態參數(參數可以有多個),參數以冒號開頭
path: '/user/:id'
/user/u1
、/user/u5
類似的請求都將與上述動態路由匹配
獲取動態路由參數
$route.params
返回json
對象,屬性名爲冒號後面的參數名稱
$route.params.id
當使用動態路由時,由於多個請求路徑都是映射到相同的組件上,故組件實例將被重複使用,由此會導致該組件生命週期中的勾子不會再次調用
如:/user/u1
--> /user/u5
let myRouter = [{
path: "/",
name: "HelloWorld",
component: HelloWorld
},
{
path: "/*",
name: "Hello",
component: HelloWorld
},
{
path: "/HelloVue",
name: "HelloVue",
component: () => import('../components/myComponents/HelloVue')
}
];
如上配置,路由含有通配符則HelloVue
將無法訪問
path: /*
會匹配所有的請求路徑
當配置的路由中含有通配符時,含有通配符的路由應放在最後
路由匹配的優先級爲 誰先定義則誰的優先級高
path: "/Hello*"
請求路徑爲 /HelloVue
時,*
將匹配Vue
字符串,獲取匹配的值可以使用$route.params.pathMatch
獲取
vue-router
路由匹配引擎規則:path-to-regexp
嵌套路由
當我們需要在一個頁面嵌入子頁面時,需要配置嵌套路由
此前,我們啓動項目訪問http://localhost:8080
將訪問HelloWorld
頁面,點擊頁面中的HelloVue
超鏈接將訪問HelloVue
頁面
現在我們在HelloVue
頁面中嵌入子頁面顯示This is Children Component
內容
1、新增文件src\components\myComponents\ChidrenComponent.vue
<template>
<div>This is Children Component</div>
</template>
<script>
export default {
name: 'ChildrenComponent'
}
</script>
2、修改HelloVue.vue
文件,導入新增組件ChildrenComponent
,指定該組件再何處渲染
<template>
<div id="vue">
Hello Vue.js! {{message}}
<MyButton :items="items"></MyButton>
<span v-for="(item,index) in 'person'" v-bind:key="item">{{index}}-{{item}}</span>
<!-- 指定子組件在此渲染 -->
<router-view></router-view>
</div>
</template>
<script>
// import other component
// 導入新增子組件
import ChildrenComponent from './ChildrenComponent'
export default {
name: 'HelloVue',
data() {
return {
// ...
}
},
methods: {
// ...
},
components: {
// ....
ChildrenComponent
}
}
</script>
3、修改路由文件在/HelloVue
路由下增加子路由
let myRouter = [{
path: "/",
name: "HelloWorld",
component: HelloWorld
},
{
path: "/HelloVue",
name: "HelloVue",
component: () => import('../components/myComponents/HelloVue'),
children: [{
path: "ChildrenComponent",
component: () => import('../components/myComponents/ChildrenComponent')
}]
}
];
4、修改請求路徑
<router-link to="/HelloVue/ChildrenComponent">HelloVue</router-link>
如果請求/HelloVue
則頁面不會顯示This is Children Component
編程式導航
我們開發過程中常遇到的跳轉有兩種場景
- 點擊超鏈接
<router-link :to="/HelloVue"></router-link>
- 在某一事件處理中跳轉
修改src\router\index.js
let myRouter = [{
path: "/",
name: "HelloWorld",
component: HelloWorld
},
{
path: "/HelloVue",
name: "HelloVue",
component: () => import('../components/myComponents/HelloVue')
},
{
path: "/ChildrenComponent",
name: "ChildrenComponent",
component: () => import('../components/myComponents/ChildrenComponent')
}
];
修改HelloVue.vue
<input type="button" @click="skip" name="跳轉" value="跳轉" />
<script>
export default {
name: 'HelloVue',
data() {
return { //... }
},
methods: {
skip() {
this.$router.push('ChildrenComponent')
}
},
components: { //... }
}
</script>
// 字符串 `home`是路由記錄中的`path`
router.push('home')
// 對象
router.push({ path: 'home' })
// 命名的路由 字符串`user`是路由記錄中的`name`
router.push({ name: 'user', params: { userId: '123' }})
// 帶查詢參數,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
如提供了path
屬性則無需再提供params
屬性,params
屬性會被忽略
router.push(location, onComplete?, onAbort?)
此方法會向棧中添加一個新記錄
router.replace(location, onComplete?, onAbort?)
與push不同在於不會新增記錄
超鏈接方式:<router-link :to="..." replace>
編程方式:router.replace(...)
router.go(n)
在 history 記錄中向前或者後退多少步
命名路由
在定義路由的時候可以爲路由設置名稱
name: "ChildrenComponent"
這兩種使用方式
<!-- 超鏈接 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 編程 -->
router.push({ name: 'user', params: { userId: 123 }})
命名視圖
爲了實現此效果我們需要命名視圖即在一個渲染組件中配置多個路由出口<router-view>
,若該標籤沒有設置name屬性則默認爲default
路由重定向
重定向的意思是,當用戶訪問/a
時,URL 將會被替換成/b
,然後匹配路由爲 /b
重定向的幾種寫法
// 使用路由信息中的path
{ path: "/HelloVue", redirect: "/ChildrenComponent/view" }
// 使用路由信息中的name
{ path: "/HelloVue", redirect: { name: 'view' } }
// 方法接收 目標路由 作爲參數 return 重定向的 字符串路徑/路徑對象
{ path: "/HelloVue", redirect: to => { return { name: 'view' } }
路由別名
/a
的別名是/b
,意味着,當用戶訪問 /b
時,URL 會保持爲/b
,但是路由匹配則爲 /a
,就像用戶訪問 /a
一樣。
{ path: "/HelloVue", alias: "/SecondPage" }
“別名”的功能讓你可以自由地將 UI 結構映射到任意的 URL,而不是受限於配置的嵌套路由結構
路由組件傳參
在組件中使用 $route 會使之與其對應路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。
我們可以使用props
將路由與組件解耦其使用方式有三種模式
布爾模式
針對的是動態路徑參數(即:通過route.params
獲取的參數)
// 路由配置信息
{
path: "/HelloVue/:query", name: "HelloVue",
component: () => import('../components/myComponents/HelloVue'),
props: true
}
// 組件內容
<template>
<div id="vue">
name: {{query}}
</div>
</template>
<script>
export default {
name: 'HelloVue',
props: ['query'],
data(){ //... },
methods:{ //... },
components:{ //... }
}
</script>
注意: :query
、['query']
、{{query}}
這三處的值必須一致(如此例子中爲query)
此模式下支持命名視圖
// 對於包含命名視圖的路由,你必須分別爲每個命名視圖添加 `props` 選項:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
對象模式
// 路由配置信息
{
path: "/HelloVue/:query", name: "HelloVue",
component: () => import('../components/myComponents/HelloVue'),
props: {
query1: 'javascript'
}
}
// 組件內容
<template>
<div id="vue">
name: {{query1}}
</div>
</template>
<script>
export default {
name: 'HelloVue',
props: ['query1'],
data(){ //... },
methods:{ //... },
components:{ //... }
}
</script>
函數模式
// 路由配置信息
{
path: "/HelloVue/:query",name: "HelloVue",
component: () => import('../components/myComponents/HelloVue'),
props: (route) => ({
query2: route.query.name
})
}
// 組件內容
<template>
<div id="vue">
name: {{query2}}
</div>
</template>
<script>
export default {
name: 'HelloVue',
props: ['query2'],
data(){ //... },
methods:{ //... },
components:{ //... }
}
</script>